diff options
73 files changed, 2233 insertions, 575 deletions
@@ -18,6 +18,7 @@ composer.lock /app/config/packages /public/packages +/public/storage /node_modules diff --git a/app/Console/Commands/.gitkeep b/app/Console/Commands/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/app/Console/Commands/.gitkeep +++ /dev/null diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index ad6e311..622e774 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -3,7 +3,7 @@ namespace App\Console; use Illuminate\Console\Scheduling\Schedule; -use Laravel\Lumen\Console\Kernel as ConsoleKernel; +use Illuminate\Foundation\Console\Kernel as ConsoleKernel; class Kernel extends ConsoleKernel { @@ -24,6 +24,17 @@ class Kernel extends ConsoleKernel */ protected function schedule(Schedule $schedule) { - // + // $schedule->command('inspire') + // ->hourly(); + } + + /** + * Register the Closure based commands for the application. + * + * @return void + */ + protected function commands() + { + require base_path('routes/console.php'); } } diff --git a/app/Events/Event.php b/app/Events/Event.php deleted file mode 100644 index b8230f0..0000000 --- a/app/Events/Event.php +++ /dev/null @@ -1,10 +0,0 @@ -<?php - -namespace App\Events; - -use Illuminate\Queue\SerializesModels; - -abstract class Event -{ - use SerializesModels; -} diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 8d0b13e..21c9784 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -3,8 +3,8 @@ namespace App\Exceptions; use Exception; -use Symfony\Component\HttpKernel\Exception\HttpException; -use Laravel\Lumen\Exceptions\Handler as ExceptionHandler; +use Illuminate\Auth\AuthenticationException; +use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { @@ -14,7 +14,12 @@ class Handler extends ExceptionHandler * @var array */ protected $dontReport = [ - HttpException::class, + \Illuminate\Auth\AuthenticationException::class, + \Illuminate\Auth\Access\AuthorizationException::class, + \Symfony\Component\HttpKernel\Exception\HttpException::class, + \Illuminate\Database\Eloquent\ModelNotFoundException::class, + \Illuminate\Session\TokenMismatchException::class, + \Illuminate\Validation\ValidationException::class, ]; /** @@ -22,23 +27,39 @@ class Handler extends ExceptionHandler * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * - * @param \Exception $e + * @param \Exception $exception * @return void */ - public function report(Exception $e) + public function report(Exception $exception) { - return parent::report($e); + parent::report($exception); } /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request - * @param \Exception $e + * @param \Exception $exception * @return \Illuminate\Http\Response */ - public function render($request, Exception $e) + public function render($request, Exception $exception) { - return parent::render($request, $e); + return parent::render($request, $exception); + } + + /** + * Convert an authentication exception into an unauthenticated response. + * + * @param \Illuminate\Http\Request $request + * @param \Illuminate\Auth\AuthenticationException $exception + * @return \Illuminate\Http\Response + */ + protected function unauthenticated($request, AuthenticationException $exception) + { + if ($request->expectsJson()) { + return response()->json(['error' => 'Unauthenticated.'], 401); + } + + return redirect()->guest('login'); } } diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php new file mode 100644 index 0000000..a36a6f4 --- /dev/null +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -0,0 +1,32 @@ +<?php + +namespace App\Http\Controllers\Auth; + +use App\Http\Controllers\Controller; +use Illuminate\Foundation\Auth\SendsPasswordResetEmails; + +class ForgotPasswordController extends Controller +{ + /* + |-------------------------------------------------------------------------- + | Password Reset Controller + |-------------------------------------------------------------------------- + | + | This controller is responsible for handling password reset emails and + | includes a trait which assists in sending these notifications from + | your application to your users. Feel free to explore this trait. + | + */ + + use SendsPasswordResetEmails; + + /** + * Create a new controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('guest'); + } +} diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php new file mode 100644 index 0000000..4c81bea --- /dev/null +++ b/app/Http/Controllers/Auth/LoginController.php @@ -0,0 +1,39 @@ +<?php + +namespace App\Http\Controllers\Auth; + +use App\Http\Controllers\Controller; +use Illuminate\Foundation\Auth\AuthenticatesUsers; + +class LoginController extends Controller +{ + /* + |-------------------------------------------------------------------------- + | Login Controller + |-------------------------------------------------------------------------- + | + | This controller handles authenticating users for the application and + | redirecting them to your home screen. The controller uses a trait + | to conveniently provide its functionality to your applications. + | + */ + + use AuthenticatesUsers; + + /** + * Where to redirect users after login. + * + * @var string + */ + protected $redirectTo = '/contribute'; + + /** + * Create a new controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('guest', ['except' => 'logout']); + } +} diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php new file mode 100644 index 0000000..ed46cab --- /dev/null +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -0,0 +1,76 @@ +<?php + +namespace App\Http\Controllers\Auth; + +use HebrewParseTrainer\User; +use Validator; +use App\Http\Controllers\Controller; +use Illuminate\Foundation\Auth\RegistersUsers; + +class RegisterController extends Controller +{ + /* + |-------------------------------------------------------------------------- + | Register Controller + |-------------------------------------------------------------------------- + | + | This controller handles the registration of new users as well as their + | validation and creation. By default this controller uses a trait to + | provide this functionality without requiring any additional code. + | + */ + + use RegistersUsers; + + /** + * Where to redirect users after login / registration. + * + * @var string + */ + protected $redirectTo = '/'; + + /** + * Create a new controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('guest'); + } + + /** + * Get a validator for an incoming registration request. + * + * @param array $data + * @return \Illuminate\Contracts\Validation\Validator + */ + protected function validator(array $data) + { + return Validator::make($data, [ + 'name' => 'required|max:255', + 'email' => 'required|email|max:255|unique:users', + 'password' => 'required|min:6|confirmed', + ]); + } + + /** + * Create a new user instance after a valid registration. + * + * @param array $data + * @return User + */ + protected function create(array $data) + { + $user = new User([ + 'name' => $data['name'], + 'email' => $data['email'], + ]); + + $user->password = $data['password']; + + $user->save(); + + return $user; + } +} diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php new file mode 100644 index 0000000..98d1131 --- /dev/null +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -0,0 +1,34 @@ +<?php + +namespace App\Http\Controllers\Auth; + +use App\Http\Controllers\Controller; +use Illuminate\Foundation\Auth\ResetsPasswords; + +class ResetPasswordController extends Controller +{ + /* + |-------------------------------------------------------------------------- + | Password Reset Controller + |-------------------------------------------------------------------------- + | + | This controller is responsible for handling password reset requests + | and uses a simple trait to include this behavior. You're free to + | explore this trait and override any methods you wish to tweak. + | + */ + + use ResetsPasswords; + + protected $redirectTo = '/'; + + /** + * Create a new controller instance. + * + * @return void + */ + public function __construct() + { + $this->middleware('guest'); + } +} diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 0ccb918..03e02a2 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -2,9 +2,12 @@ namespace App\Http\Controllers; -use Laravel\Lumen\Routing\Controller as BaseController; +use Illuminate\Foundation\Bus\DispatchesJobs; +use Illuminate\Routing\Controller as BaseController; +use Illuminate\Foundation\Validation\ValidatesRequests; +use Illuminate\Foundation\Auth\Access\AuthorizesRequests; class Controller extends BaseController { - // + use AuthorizesRequests, DispatchesJobs, ValidatesRequests; } diff --git a/app/Http/Controllers/RandomVerbController.php b/app/Http/Controllers/RandomVerbController.php index 501440a..ceb5ff9 100644 --- a/app/Http/Controllers/RandomVerbController.php +++ b/app/Http/Controllers/RandomVerbController.php @@ -22,9 +22,8 @@ use HebrewParseTrainer\Verb; use HebrewParseTrainer\RandomLog; use Illuminate\Http\Request; use Illuminate\Support\Facades\Input; -use Laravel\Lumen\Routing\Controller as BaseController; -class RandomVerbController extends BaseController { +class RandomVerbController extends Controller { public function show() { diff --git a/app/Http/Controllers/RootController.php b/app/Http/Controllers/RootController.php index 3899754..5546a1d 100644 --- a/app/Http/Controllers/RootController.php +++ b/app/Http/Controllers/RootController.php @@ -21,12 +21,11 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Validator; -use Laravel\Lumen\Routing\Controller as BaseController; use HebrewParseTrainer\Root; use HebrewParseTrainer\RootKind; -class RootController extends BaseController { +class RootController extends Controller { public function create(Request $request) { $_kinds = RootKind::all(); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php deleted file mode 100644 index 7036439..0000000 --- a/app/Http/Controllers/UserController.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** - * HebrewParseTrainer - practice Hebrew verbs - * Copyright (C) 2015 Camil Staps <info@camilstaps.nl> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -namespace App\Http\Controllers; - -use Illuminate\Http\Request; -use Illuminate\Support\Facades\Validator; -use Illuminate\Validation\ValidationException; -use Laravel\Lumen\Routing\Controller as BaseController; - -use HebrewParseTrainer\User; - -class UserController extends BaseController { - - public function createForm(Request $request) { - $messages = []; - - if ($request->isMethod('post')) { - $validator = Validator::make($request->input(), [ - 'email' => 'required|unique:users|email', - 'name' => 'required|unique:users', - 'password' => 'required|confirmed|min:8', - ]); - - if ($validator->fails()) { - foreach ($validator->errors()->all() as $error) { - $messages[] = ['danger', $error]; - } - } else { - $user = new User; - $user->name = $request->input('name'); - $user->email = $request->input('email'); - $user->password = $request->input('password'); - if ($user->save()) { - $messages[] = ['success', 'Your account has been created.']; - } else { - $messages[] = ['danger', 'Your account could not be created.']; - } - } - } - - return view('user.create', - [ - 'messages' => $messages, - 'form' => [ - 'email' => $request->input('email'), - 'name' => $request->input('name') - ] - ]); - } - -} diff --git a/app/Http/Controllers/VerbController.php b/app/Http/Controllers/VerbController.php index 18cdd2f..59289c1 100644 --- a/app/Http/Controllers/VerbController.php +++ b/app/Http/Controllers/VerbController.php @@ -29,9 +29,8 @@ use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Input; use Illuminate\Support\Facades\Validator; -use Laravel\Lumen\Routing\Controller as BaseController; -class VerbController extends BaseController { +class VerbController extends Controller { public function random() { $verbs = Verb::where('active', 1)->get(); @@ -129,7 +128,7 @@ class VerbController extends BaseController { return true; } - public function vote($choice, $verb_id) { + public function vote($verb_id, $choice) { $verb = Verb::findOrFail($verb_id); $user = Auth::user(); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php new file mode 100644 index 0000000..85782f3 --- /dev/null +++ b/app/Http/Kernel.php @@ -0,0 +1,56 @@ +<?php + +namespace App\Http; + +use Illuminate\Foundation\Http\Kernel as HttpKernel; + +class Kernel extends HttpKernel +{ + /** + * The application's global HTTP middleware stack. + * + * These middleware are run during every request to your application. + * + * @var array + */ + protected $middleware = [ + \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array + */ + protected $middlewareGroups = [ + 'web' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + + 'api' => [ + 'throttle:60,1', + 'bindings', + ], + ]; + + /** + * The application's route middleware. + * + * These middleware may be assigned to groups or used individually. + * + * @var array + */ + protected $routeMiddleware = [ + 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + ]; +} diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php deleted file mode 100644 index 6db8bb0..0000000 --- a/app/Http/Middleware/Authenticate.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php - -namespace App\Http\Middleware; - -use Closure; -use Illuminate\Contracts\Auth\Factory as Auth; - -class Authenticate -{ - /** - * The authentication guard factory instance. - * - * @var \Illuminate\Contracts\Auth\Factory - */ - protected $auth; - - /** - * Create a new middleware instance. - * - * @param \Illuminate\Contracts\Auth\Factory $auth - * @return void - */ - public function __construct(Auth $auth) - { - $this->auth = $auth; - } - - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null $guard - * @return mixed - */ - public function handle($request, Closure $next, $guard = null) - { - if ($this->auth->guard($guard)->guest()) { - return response('Unauthorized.', 401) - ->header('WWW-Authenticate', 'Basic realm="Please enter your email and password"'); - } - - return $next($request); - } -} diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 0000000..3aa15f8 --- /dev/null +++ b/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,17 @@ +<?php + +namespace App\Http\Middleware; + +use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter; + +class EncryptCookies extends BaseEncrypter +{ + /** + * The names of the cookies that should not be encrypted. + * + * @var array + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/Middleware/Login.php b/app/Http/Middleware/Login.php deleted file mode 100644 index 8a71104..0000000 --- a/app/Http/Middleware/Login.php +++ /dev/null @@ -1,34 +0,0 @@ -<?php - -namespace App\Http\Middleware; - -use Closure; -use Illuminate\Support\Facades\Auth; - -class Login { - /** - * Create a new middleware instance. - * - * @param \Illuminate\Contracts\Auth\Factory $auth - * @return void - */ - public function __construct() { - } - - /** - * Handle an incoming request. - * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null $guard - * @return mixed - */ - public function handle($request, Closure $next, $guard = null) { - if ($request->has('login') && !Auth::check()) { - return response('Unauthorized.', 401) - ->header('WWW-Authenticate', 'Basic realm="Please enter your email and password"'); - } - - return $next($request); - } -} diff --git a/app/Http/Middleware/ExampleMiddleware.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 166581c..e27860e 100644 --- a/app/Http/Middleware/ExampleMiddleware.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -3,18 +3,24 @@ namespace App\Http\Middleware; use Closure; +use Illuminate\Support\Facades\Auth; -class ExampleMiddleware +class RedirectIfAuthenticated { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next + * @param string|null $guard * @return mixed */ - public function handle($request, Closure $next) + public function handle($request, Closure $next, $guard = null) { + if (Auth::guard($guard)->check()) { + return redirect('/'); + } + return $next($request); } } diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 0000000..a2c3541 --- /dev/null +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,17 @@ +<?php + +namespace App\Http\Middleware; + +use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; + +class VerifyCsrfToken extends BaseVerifier +{ + /** + * The URIs that should be excluded from CSRF verification. + * + * @var array + */ + protected $except = [ + // + ]; +} diff --git a/app/Http/routes.php b/app/Http/routes.php deleted file mode 100644 index b233efa..0000000 --- a/app/Http/routes.php +++ /dev/null @@ -1,88 +0,0 @@ -<?php -/** - * HebrewParseTrainer - practice Hebrew verbs - * Copyright (C) 2015 Camil Staps <info@camilstaps.nl> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* -|-------------------------------------------------------------------------- -| Application Routes -|-------------------------------------------------------------------------- -| -| Here is where you can register all of the routes for an application. -| It is a breeze. Simply tell Lumen the URIs it should respond to -| and give it the Closure to call when that URI is requested. -| -*/ - -$app->group( - [ - 'prefix' => parse_url(env('APP_URL'), PHP_URL_PATH), - 'middleware' => 'login' - ], - function ($app) { - - $app->get('/', function () use ($app) { - return view('trainer'); - }); - - $app->get('/stem', function () use ($app) { - return \HebrewParseTrainer\Stem::all(); - }); - - $app->get('/tense', function () use ($app) { - return \HebrewParseTrainer\Tense::all(); - }); - - $app->get('/verb/random', - 'App\Http\Controllers\VerbController@random'); - - $app->get('/logout', function () use ($app) { - return response('You have been logged out.', 401) - ->header( - 'WWW-Authenticate', - 'Basic realm="Please click OK, then Cancel to logout."'); - }); - - $app->get('/contribute', function () use ($app) { - return view('contribute'); - }); - - $app->get('/user/create', - 'App\Http\Controllers\UserController@createForm'); - $app->post('/user/create', - 'App\Http\Controllers\UserController@createForm'); - - $app->group( - ['middleware' => 'auth:basic-http'], - function ($app) { - - $app->get('/stats', function () use ($app) { - return view('stats'); - }); - - $app->get('/verb/{id}/vote/{choice}', - 'App\Http\Controllers\VerbController@vote'); - - $app->post('/verb/suggest', - 'App\Http\Controllers\VerbController@suggest'); - - $app->post('/root/create', - 'App\Http\Controllers\RootController@create'); - - }); - -}); diff --git a/app/Jobs/Job.php b/app/Jobs/Job.php deleted file mode 100644 index 2bc4975..0000000 --- a/app/Jobs/Job.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -namespace App\Jobs; - -use Illuminate\Bus\Queueable; -use Illuminate\Queue\SerializesModels; -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Contracts\Bus\SelfHandling; -use Illuminate\Contracts\Queue\ShouldQueue; - -abstract class Job implements SelfHandling, ShouldQueue -{ - /* - |-------------------------------------------------------------------------- - | Queueable Jobs - |-------------------------------------------------------------------------- - | - | This job base class provides a central location to place any logic that - | is shared across all of your jobs. The trait included with the class - | provides access to the "queueOn" and "delay" queue helper methods. - | - */ - - use InteractsWithQueue, Queueable, SerializesModels; -} diff --git a/app/Listeners/Listener.php b/app/Listeners/Listener.php deleted file mode 100644 index d346fc1..0000000 --- a/app/Listeners/Listener.php +++ /dev/null @@ -1,11 +0,0 @@ -<?php - -namespace App\Listeners; - -use Illuminate\Queue\InteractsWithQueue; -use Illuminate\Contracts\Queue\ShouldQueue; - -abstract class Listener -{ - // -} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 9bc5fd1..35471f6 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -3,23 +3,26 @@ namespace App\Providers; use Illuminate\Support\ServiceProvider; -use App\Observers\UserObserver; -use HebrewParseTrainer\User; class AppServiceProvider extends ServiceProvider { - /** - * Register any application services. - * - * @return void - */ - public function register() - { - $this->app->singleton('mailer', function ($app) { - $app->configure('services'); - return $app->loadComponent('mail', 'Illuminate\Mail\MailServiceProvider', 'mailer'); - }); + /** + * Bootstrap any application services. + * + * @return void + */ + public function boot() + { + // + } - User::observe(UserObserver::class); - } + /** + * Register any application services. + * + * @return void + */ + public function register() + { + // + } } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 7cf4b27..9784b1a 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -2,38 +2,29 @@ namespace App\Providers; -use App\User; -use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Gate; -use Illuminate\Support\ServiceProvider; +use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; class AuthServiceProvider extends ServiceProvider { - /** - * Register any application services. - * - * @return void - */ - public function register() - { - // - } + /** + * The policy mappings for the application. + * + * @var array + */ + protected $policies = [ + 'App\Model' => 'App\Policies\ModelPolicy', + ]; - /** - * Boot the authentication services for the application. - * - * @return void - */ - public function boot() - { - // Here you may define how you wish users to be authenticated for your Lumen - // application. The callback which receives the incoming request instance - // should return either a User instance or null. You're free to obtain - // the User instance via an API token or any other method necessary. - Auth::viaRequest('api', function ($request) { - if ($request->input('api_token')) { - return User::where('api_token', $request->input('api_token'))->first(); - } - }); - } + /** + * Register any authentication / authorization services. + * + * @return void + */ + public function boot() + { + $this->registerPolicies(); + + // + } } diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php new file mode 100644 index 0000000..1dcf8d2 --- /dev/null +++ b/app/Providers/BroadcastServiceProvider.php @@ -0,0 +1,26 @@ +<?php + +namespace App\Providers; + +use Illuminate\Support\ServiceProvider; +use Illuminate\Support\Facades\Broadcast; + +class BroadcastServiceProvider extends ServiceProvider +{ + /** + * Bootstrap any application services. + * + * @return void + */ + public function boot() + { + Broadcast::routes(); + + /* + * Authenticate the user's personal channel... + */ + Broadcast::channel('App.User.*', function ($user, $userId) { + return (int) $user->id === (int) $userId; + }); + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index ff72210..a182657 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,6 +2,7 @@ namespace App\Providers; +use Illuminate\Support\Facades\Event; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider @@ -16,4 +17,16 @@ class EventServiceProvider extends ServiceProvider 'App\Listeners\EventListener', ], ]; + + /** + * Register any events for your application. + * + * @return void + */ + public function boot() + { + parent::boot(); + + // + } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php new file mode 100644 index 0000000..87ffb05 --- /dev/null +++ b/app/Providers/RouteServiceProvider.php @@ -0,0 +1,79 @@ +<?php + +namespace App\Providers; + +use Illuminate\Support\Facades\Route; +use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; + +class RouteServiceProvider extends ServiceProvider +{ + /** + * This namespace is applied to your controller routes. + * + * In addition, it is set as the URL generator's root namespace. + * + * @var string + */ + protected $namespace = 'App\Http\Controllers'; + + /** + * Define your route model bindings, pattern filters, etc. + * + * @return void + */ + public function boot() + { + // + + parent::boot(); + } + + /** + * Define the routes for the application. + * + * @return void + */ + public function map() + { + $this->mapApiRoutes(); + + $this->mapWebRoutes(); + + // + } + + /** + * Define the "web" routes for the application. + * + * These routes all receive session state, CSRF protection, etc. + * + * @return void + */ + protected function mapWebRoutes() + { + Route::group([ + 'middleware' => 'web', + 'namespace' => $this->namespace, + ], function ($router) { + require base_path('routes/web.php'); + }); + } + + /** + * Define the "api" routes for the application. + * + * These routes are typically stateless. + * + * @return void + */ + protected function mapApiRoutes() + { + Route::group([ + 'middleware' => 'api', + 'namespace' => $this->namespace, + 'prefix' => 'api', + ], function ($router) { + require base_path('routes/api.php'); + }); + } +} diff --git a/app/User.php b/app/User.php index f1ff869..8853733 100644 --- a/app/User.php +++ b/app/User.php @@ -19,10 +19,16 @@ namespace HebrewParseTrainer; use Illuminate\Contracts\Auth\Authenticatable; +use Illuminate\Contracts\Auth\CanResetPassword; +use Illuminate\Auth\Passwords\CanResetPassword as CanResetPasswordTrait; +use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Hash; -class User extends Model implements Authenticatable { +class User extends Model implements Authenticatable, CanResetPassword { + + use CanResetPasswordTrait; + use Notifiable; protected $table = 'users'; public $timestamps = false; @@ -52,10 +58,6 @@ class User extends Model implements Authenticatable { return floor(log($this->points, self::VOTE_WEIGHT_BASE)); } - public function setPasswordAttribute($pass) { - $this->attributes['password'] = Hash::make($pass); - } - public function verifyPassword($pass) { if (!Hash::check($pass, $this->password)) return false; @@ -81,14 +83,16 @@ class User extends Model implements Authenticatable { } public function getRememberToken() { - return null; + return $this->remember_token; } public function setRememberToken($token) { + $this->remember_token = $token; + $this->save(); } public function getRememberTokenName() { - return null; + return 'remember_token'; } } @@ -1,21 +1,21 @@ #!/usr/bin/env php <?php -use Symfony\Component\Console\Input\ArgvInput; -use Symfony\Component\Console\Output\ConsoleOutput; - /* |-------------------------------------------------------------------------- -| Create The Application +| Register The Auto Loader |-------------------------------------------------------------------------- | -| First we need to get an application instance. This creates an instance -| of the application / container and bootstraps the application so it -| is ready to receive HTTP / Console requests from the environment. +| Composer provides a convenient, automatically generated class loader +| for our application. We just need to utilize it! We'll require it +| into the script here so that we do not have to worry about the +| loading of any our classes "manually". Feels great to relax. | */ -$app = require __DIR__.'/bootstrap/app.php'; +require __DIR__.'/bootstrap/autoload.php'; + +$app = require_once __DIR__.'/bootstrap/app.php'; /* |-------------------------------------------------------------------------- @@ -28,8 +28,24 @@ $app = require __DIR__.'/bootstrap/app.php'; | */ -$kernel = $app->make( - 'Illuminate\Contracts\Console\Kernel' +$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput ); -exit($kernel->handle(new ArgvInput, new ConsoleOutput)); +/* +|-------------------------------------------------------------------------- +| Shutdown The Application +|-------------------------------------------------------------------------- +| +| Once Artisan has finished running. We will fire off the shutdown events +| so that any final work may be done by the application before we shut +| down the process. This is the last thing to happen to the request. +| +*/ + +$kernel->terminate($input, $status); + +exit($status); diff --git a/bootstrap/app.php b/bootstrap/app.php index c72ab23..f2801ad 100644 --- a/bootstrap/app.php +++ b/bootstrap/app.php @@ -1,109 +1,55 @@ <?php -require_once __DIR__.'/../vendor/autoload.php'; - -try { - (new Dotenv\Dotenv(__DIR__.'/../'))->load(); -} catch (Dotenv\Exception\InvalidPathException $e) { -} - /* |-------------------------------------------------------------------------- | Create The Application |-------------------------------------------------------------------------- | -| Here we will load the environment and create the application instance -| that serves as the central piece of this framework. We'll use this -| application as an "IoC" container and router for this framework. +| The first thing we will do is create a new Laravel application instance +| which serves as the "glue" for all the components of Laravel, and is +| the IoC container for the system binding all of the various parts. | */ -$app = new Laravel\Lumen\Application( - realpath(__DIR__.'/../') +$app = new Illuminate\Foundation\Application( + realpath(__DIR__.'/../') ); -$app->withFacades(); - -$app->withEloquent(); - /* |-------------------------------------------------------------------------- -| Register Container Bindings +| Bind Important Interfaces |-------------------------------------------------------------------------- | -| Now we will register a few bindings in the service container. We will -| register the exception handler and the console kernel. You may add -| your own bindings here if you like or you can make another file. +| Next, we need to bind some important interfaces into the container so +| we will be able to resolve them when needed. The kernels serve the +| incoming requests to this application from both the web and CLI. | */ $app->singleton( - Illuminate\Contracts\Debug\ExceptionHandler::class, - App\Exceptions\Handler::class + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class ); $app->singleton( - Illuminate\Contracts\Console\Kernel::class, - App\Console\Kernel::class + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class ); -/* -|-------------------------------------------------------------------------- -| Register Middleware -|-------------------------------------------------------------------------- -| -| Next, we will register the middleware with the application. These can -| be global middleware that run before and after each request into a -| route or middleware that'll be assigned to some specific routes. -| -*/ - -// $app->middleware([ -// // Illuminate\Cookie\Middleware\EncryptCookies::class, -// // Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, -// // Illuminate\Session\Middleware\StartSession::class, -// // Illuminate\View\Middleware\ShareErrorsFromSession::class, -// // Laravel\Lumen\Http\Middleware\VerifyCsrfToken::class, -// ]); - -$app->routeMiddleware([ - 'auth' => App\Http\Middleware\Authenticate::class, - 'login' => App\Http\Middleware\Login::class, -]); - -/* -|-------------------------------------------------------------------------- -| Register Service Providers -|-------------------------------------------------------------------------- -| -| Here we will register all of the application's service providers which -| are used to bind services into the container. Service providers are -| totally optional, so you are not required to uncomment this line. -| -*/ - -$app->register(App\Providers\AppServiceProvider::class); -$app->register(App\Providers\AuthServiceProvider::class); -// $app->register(App\Providers\EventServiceProvider::class); - -$app->register(Illuminate\Mail\MailServiceProvider::class); -$app->register(Arubacao\BasicAuth\BasicGuardServiceProvider::class); +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); /* |-------------------------------------------------------------------------- -| Load The Application Routes +| Return The Application |-------------------------------------------------------------------------- | -| Next we will include the routes file so that they can all be added to -| the application. This will provide all of the URLs the application -| can respond to, as well as the controllers that may handle them. +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. | */ -$app->group(['namespace' => 'App\Http\Controllers'], function ($app) { - require __DIR__.'/../app/Http/routes.php'; -}); - -$app->configure('mail'); - return $app; diff --git a/bootstrap/autoload.php b/bootstrap/autoload.php new file mode 100644 index 0000000..3830137 --- /dev/null +++ b/bootstrap/autoload.php @@ -0,0 +1,34 @@ +<?php + +define('LARAVEL_START', microtime(true)); + +/* +|-------------------------------------------------------------------------- +| Register The Composer Auto Loader +|-------------------------------------------------------------------------- +| +| Composer provides a convenient, automatically generated class loader +| for our application. We just need to utilize it! We'll require it +| into the script here so that we do not have to worry about the +| loading of any our classes "manually". Feels great to relax. +| +*/ + +require __DIR__.'/../vendor/autoload.php'; + +/* +|-------------------------------------------------------------------------- +| Include The Compiled Class File +|-------------------------------------------------------------------------- +| +| To dramatically increase your application's performance, you may use a +| compiled class file which contains all of the classes commonly used +| by a request. The Artisan "optimize" is used to create this file. +| +*/ + +$compiledPath = __DIR__.'/cache/compiled.php'; + +if (file_exists($compiledPath)) { + require $compiledPath; +} diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/composer.json b/composer.json index dee60f3..1d24a6a 100644 --- a/composer.json +++ b/composer.json @@ -1,34 +1,50 @@ { - "name": "laravel/lumen", - "description": "The Laravel Lumen Framework.", - "keywords": ["framework", "laravel", "lumen"], - "license": "MIT", + "name": "hebrewtools/parsetrainer", + "description": "A simple app to practice Hebrew verbs", + "keywords": ["hebrew", "education", "bible"], + "license": "GPLv3", "type": "project", "require": { - "php": ">=5.5.9", - "laravel/lumen-framework": "5.2.*", - "illuminate/mail": "5.2.*", - "vlucas/phpdotenv": "~2.2", + "php": ">=5.6.4", + "laravel/framework": "5.3.*", "twbs/bootstrap": "^3.3", - "components/jquery": "^2.1", - "arubacao/http-basic-auth-guard": "^1.0" + "components/jquery": "^2.1" }, "require-dev": { - "phpunit/phpunit": "~4.0", - "fzaninotto/faker": "~1.0" + "fzaninotto/faker": "~1.4", + "mockery/mockery": "0.9.*", + "phpunit/phpunit": "~5.0", + "symfony/css-selector": "3.1.*", + "symfony/dom-crawler": "3.1.*" }, "autoload": { + "classmap": [ + "database" + ], "psr-4": { "App\\": "app/", "HebrewParseTrainer\\": "app/" - }, - "classmap": [ - "database/" - ] + } }, "autoload-dev": { "classmap": [ - "tests/" + "tests/TestCase.php" + ] + }, + "scripts": { + "post-root-package-install": [ + "php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "php artisan key:generate" + ], + "post-install-cmd": [ + "Illuminate\\Foundation\\ComposerScripts::postInstall", + "php artisan optimize" + ], + "post-update-cmd": [ + "Illuminate\\Foundation\\ComposerScripts::postUpdate", + "php artisan optimize" ] }, "config": { diff --git a/config/app.php b/config/app.php new file mode 100644 index 0000000..a615b38 --- /dev/null +++ b/config/app.php @@ -0,0 +1,231 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Application Name + |-------------------------------------------------------------------------- + | + | This value is the name of your application. This value is used when the + | framework needs to place the application's name in a notification or + | any other location as required by the application or its packages. + */ + + 'name' => 'ParseTrainer', + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services your application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | your application so that it is used when running Artisan tasks. + | + */ + + 'url' => env('APP_URL'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. We have gone + | ahead and set this to a sensible default for you out of the box. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is used by the Illuminate encrypter service and should be set + | to a random, 32 character string, otherwise these encrypted strings + | will not be safe. Please do this before deploying an application! + | + */ + + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Logging Configuration + |-------------------------------------------------------------------------- + | + | Here you may configure the log settings for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Settings: "single", "daily", "syslog", "errorlog" + | + */ + + 'log' => env('APP_LOG', 'single'), + + 'log_level' => env('APP_LOG_LEVEL', 'debug'), + + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + + /* + * Laravel Framework Service Providers... + */ + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + + /* + * Package Service Providers... + */ + + // + + /* + * Application Service Providers... + */ + App\Providers\AppServiceProvider::class, + App\Providers\AuthServiceProvider::class, + // App\Providers\BroadcastServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\RouteServiceProvider::class, + + ], + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. However, feel free to register as many as you wish as + | the aliases are "lazy" loaded so they don't hinder performance. + | + */ + + 'aliases' => [ + + 'App' => Illuminate\Support\Facades\App::class, + 'Artisan' => Illuminate\Support\Facades\Artisan::class, + 'Auth' => Illuminate\Support\Facades\Auth::class, + 'Blade' => Illuminate\Support\Facades\Blade::class, + 'Bus' => Illuminate\Support\Facades\Bus::class, + 'Cache' => Illuminate\Support\Facades\Cache::class, + 'Config' => Illuminate\Support\Facades\Config::class, + 'Cookie' => Illuminate\Support\Facades\Cookie::class, + 'Crypt' => Illuminate\Support\Facades\Crypt::class, + 'DB' => Illuminate\Support\Facades\DB::class, + 'Eloquent' => Illuminate\Database\Eloquent\Model::class, + 'Event' => Illuminate\Support\Facades\Event::class, + 'File' => Illuminate\Support\Facades\File::class, + 'Gate' => Illuminate\Support\Facades\Gate::class, + 'Hash' => Illuminate\Support\Facades\Hash::class, + 'Lang' => Illuminate\Support\Facades\Lang::class, + 'Log' => Illuminate\Support\Facades\Log::class, + 'Mail' => Illuminate\Support\Facades\Mail::class, + 'Notification' => Illuminate\Support\Facades\Notification::class, + 'Password' => Illuminate\Support\Facades\Password::class, + 'Queue' => Illuminate\Support\Facades\Queue::class, + 'Redirect' => Illuminate\Support\Facades\Redirect::class, + 'Redis' => Illuminate\Support\Facades\Redis::class, + 'Request' => Illuminate\Support\Facades\Request::class, + 'Response' => Illuminate\Support\Facades\Response::class, + 'Route' => Illuminate\Support\Facades\Route::class, + 'Schema' => Illuminate\Support\Facades\Schema::class, + 'Session' => Illuminate\Support\Facades\Session::class, + 'Storage' => Illuminate\Support\Facades\Storage::class, + 'URL' => Illuminate\Support\Facades\URL::class, + 'Validator' => Illuminate\Support\Facades\Validator::class, + 'View' => Illuminate\Support\Facades\View::class, + + ], + +]; diff --git a/config/auth.php b/config/auth.php index 2331863..5e571a9 100644 --- a/config/auth.php +++ b/config/auth.php @@ -2,87 +2,101 @@ return [ - /* - |-------------------------------------------------------------------------- - | Authentication Defaults - |-------------------------------------------------------------------------- - | - | This option controls the default authentication "guard" and password - | reset options for your application. You may change these defaults - | as required, but they're a perfect start for most applications. - | - */ + /* + |-------------------------------------------------------------------------- + | Authentication Defaults + |-------------------------------------------------------------------------- + | + | This option controls the default authentication "guard" and password + | reset options for your application. You may change these defaults + | as required, but they're a perfect start for most applications. + | + */ - 'defaults' => [ - 'guard' => env('AUTH_GUARD', 'basic-http'), - ], + 'defaults' => [ + 'guard' => 'web', + 'passwords' => 'users', + ], - /* - |-------------------------------------------------------------------------- - | Authentication Guards - |-------------------------------------------------------------------------- - | - | Next, you may define every authentication guard for your application. - | Of course, a great default configuration has been defined for you - | here which uses session storage and the Eloquent user provider. - | - | All authentication drivers have a user provider. This defines how the - | users are actually retrieved out of your database or other storage - | mechanisms used by this application to persist your user's data. - | - | Supported: "token" - | - */ + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session", "token" + | + */ - 'guards' => [ - 'basic-http' => ['driver' => 'basic', 'provider' => 'users'], - ], + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], - /* - |-------------------------------------------------------------------------- - | User Providers - |-------------------------------------------------------------------------- - | - | All authentication drivers have a user provider. This defines how the - | users are actually retrieved out of your database or other storage - | mechanisms used by this application to persist your user's data. - | - | If you have multiple user tables or models you may configure multiple - | sources which represent each model / table. These sources may then - | be assigned to any extra authentication guards you have defined. - | - | Supported: "database", "eloquent" - | - */ + 'api' => [ + 'driver' => 'token', + 'provider' => 'users', + ], + ], - 'providers' => [ - 'users' => [ - 'driver' => 'eloquent', - 'model' => HebrewParseTrainer\User::class, - ], - ], + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ - /* - |-------------------------------------------------------------------------- - | Resetting Passwords - |-------------------------------------------------------------------------- - | - | Here you may set the options for resetting passwords including the view - | that is your password reset e-mail. You may also set the name of the - | table that maintains all of the reset tokens for your application. - | - | You may specify multiple password reset configurations if you have more - | than one user table or model in the application and you want to have - | separate password reset settings based on the specific user types. - | - | The expire time is the number of minutes that the reset token should be - | considered valid. This security feature keeps tokens short-lived so - | they have less time to be guessed. You may change this as needed. - | - */ + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => HebrewParseTrainer\User::class, + ], - 'passwords' => [ - // - ], + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expire time is the number of minutes that the reset token should be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_resets', + 'expire' => 60, + ], + ], ]; diff --git a/config/broadcasting.php b/config/broadcasting.php new file mode 100644 index 0000000..19a59ba --- /dev/null +++ b/config/broadcasting.php @@ -0,0 +1,58 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Broadcaster + |-------------------------------------------------------------------------- + | + | This option controls the default broadcaster that will be used by the + | framework when an event needs to be broadcast. You may set this to + | any of the connections defined in the "connections" array below. + | + | Supported: "pusher", "redis", "log", "null" + | + */ + + 'default' => env('BROADCAST_DRIVER', 'null'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_KEY'), + 'secret' => env('PUSHER_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + 'options' => [ + // + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + 'null' => [ + 'driver' => 'null', + ], + + ], + +]; diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..1d3de87 --- /dev/null +++ b/config/cache.php @@ -0,0 +1,91 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Cache Store + |-------------------------------------------------------------------------- + | + | This option controls the default cache connection that gets used while + | using this caching library. This connection is used when another is + | not explicitly specified when executing a given caching function. + | + | Supported: "apc", "array", "database", "file", "memcached", "redis" + | + */ + + 'default' => env('CACHE_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing a RAM based store such as APC or Memcached, there might + | be other applications utilizing the same cache. So, we'll specify a + | value to get prefixed to all our keys so we can avoid collisions. + | + */ + + 'prefix' => 'laravel', + +]; diff --git a/config/compile.php b/config/compile.php new file mode 100644 index 0000000..04807ea --- /dev/null +++ b/config/compile.php @@ -0,0 +1,35 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Additional Compiled Classes + |-------------------------------------------------------------------------- + | + | Here you may specify additional classes to include in the compiled file + | generated by the `artisan optimize` command. These should be classes + | that are included on basically every request into the application. + | + */ + + 'files' => [ + // + ], + + /* + |-------------------------------------------------------------------------- + | Compiled File Providers + |-------------------------------------------------------------------------- + | + | Here you may list service providers which define a "compiles" function + | that returns additional files that should be compiled, providing an + | easy way to get common files from any packages you are utilizing. + | + */ + + 'providers' => [ + // + ], + +]; diff --git a/config/database.php b/config/database.php new file mode 100644 index 0000000..fd22e8e --- /dev/null +++ b/config/database.php @@ -0,0 +1,121 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | PDO Fetch Style + |-------------------------------------------------------------------------- + | + | By default, database results will be returned as instances of the PHP + | stdClass object; however, you may desire to retrieve records in an + | array format for simplicity. Here you can tweak the fetch style. + | + */ + + 'fetch' => PDO::FETCH_OBJ, + + /* + |-------------------------------------------------------------------------- + | Default Database Connection Name + |-------------------------------------------------------------------------- + | + | Here you may specify which of the database connections below you wish + | to use as your default connection for all database work. Of course + | you may use many connections at once using the Database library. + | + */ + + 'default' => env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'collation' => 'utf8_unicode_ci', + 'prefix' => '', + 'strict' => true, + 'engine' => null, + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'schema' => 'public', + 'sslmode' => 'prefer', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer set of commands than a typical key-value systems + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'cluster' => false, + + 'default' => [ + 'host' => env('REDIS_HOST', 'localhost'), + 'password' => env('REDIS_PASSWORD', null), + 'port' => env('REDIS_PORT', 6379), + 'database' => 0, + ], + + ], + +]; diff --git a/config/filesystems.php b/config/filesystems.php new file mode 100644 index 0000000..75b5002 --- /dev/null +++ b/config/filesystems.php @@ -0,0 +1,67 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Filesystem Disk + |-------------------------------------------------------------------------- + | + | Here you may specify the default filesystem disk that should be used + | by the framework. A "local" driver, as well as a variety of cloud + | based drivers are available for your choosing. Just store away! + | + | Supported: "local", "ftp", "s3", "rackspace" + | + */ + + 'default' => 'local', + + /* + |-------------------------------------------------------------------------- + | Default Cloud Filesystem Disk + |-------------------------------------------------------------------------- + | + | Many applications store files both locally and in the cloud. For this + | reason, you may specify a default "cloud" driver here. This driver + | will be bound as the Cloud disk implementation in the container. + | + */ + + 'cloud' => 's3', + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been setup for each driver as an example of the required options. + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'visibility' => 'public', + ], + + 's3' => [ + 'driver' => 's3', + 'key' => 'your-key', + 'secret' => 'your-secret', + 'region' => 'your-region', + 'bucket' => 'your-bucket', + ], + + ], + +]; diff --git a/config/queue.php b/config/queue.php new file mode 100644 index 0000000..549322e --- /dev/null +++ b/config/queue.php @@ -0,0 +1,85 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Queue Driver + |-------------------------------------------------------------------------- + | + | The Laravel queue API supports a variety of back-ends via an unified + | API, giving you convenient access to each back-end using the same + | syntax for each one. Here you may set the default queue driver. + | + | Supported: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'default' => env('QUEUE_DRIVER', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'retry_after' => 90, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'retry_after' => 90, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => 'your-public-key', + 'secret' => 'your-secret-key', + 'prefix' => 'https://sqs.us-east-1.amazonaws.com/your-account-id', + 'queue' => 'your-queue-name', + 'region' => 'us-east-1', + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => 'default', + 'retry_after' => 90, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/config/services.php b/config/services.php new file mode 100644 index 0000000..4460f0e --- /dev/null +++ b/config/services.php @@ -0,0 +1,38 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Third Party Services + |-------------------------------------------------------------------------- + | + | This file is for storing the credentials for third party services such + | as Stripe, Mailgun, SparkPost and others. This file provides a sane + | default location for this type of information, allowing packages + | to have a conventional place to find your various credentials. + | + */ + + 'mailgun' => [ + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), + ], + + 'ses' => [ + 'key' => env('SES_KEY'), + 'secret' => env('SES_SECRET'), + 'region' => 'us-east-1', + ], + + 'sparkpost' => [ + 'secret' => env('SPARKPOST_SECRET'), + ], + + 'stripe' => [ + 'model' => App\User::class, + 'key' => env('STRIPE_KEY'), + 'secret' => env('STRIPE_SECRET'), + ], + +]; diff --git a/config/session.php b/config/session.php new file mode 100644 index 0000000..e2779ad --- /dev/null +++ b/config/session.php @@ -0,0 +1,179 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Default Session Driver + |-------------------------------------------------------------------------- + | + | This option controls the default session "driver" that will be used on + | requests. By default, we will use the lightweight native driver but + | you may specify any of the other wonderful drivers provided here. + | + | Supported: "file", "cookie", "database", "apc", + | "memcached", "redis", "array" + | + */ + + 'driver' => env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => 120, + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => null, + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | When using the "apc" or "memcached" session drivers, you may specify a + | cache store that should be used for these sessions. This value must + | correspond with one of the application's configured cache stores. + | + */ + + 'store' => null, + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => 'laravel_session', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN', null), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you if it can not be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE', false), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + +]; diff --git a/config/view.php b/config/view.php new file mode 100644 index 0000000..e193ab6 --- /dev/null +++ b/config/view.php @@ -0,0 +1,33 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | View Storage Paths + |-------------------------------------------------------------------------- + | + | Most templating systems load templates from disk. Here you may specify + | an array of paths that should be checked for your views. Of course + | the usual Laravel view path has already been registered for you. + | + */ + + 'paths' => [ + realpath(base_path('resources/views')), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => realpath(storage_path('framework/views')), + +]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index ae7165b..e0dc869 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -11,11 +11,13 @@ | */ -$factory->define(App\User::class, function ($faker) { +$factory->define(App\User::class, function (Faker\Generator $faker) { + static $password; + return [ 'name' => $faker->name, - 'email' => $faker->email, - 'password' => str_random(10), + 'email' => $faker->unique()->safeEmail, + 'password' => $password ?: $password = bcrypt('secret'), 'remember_token' => str_random(10), ]; }); diff --git a/database/migrations/2016_09_25_210947_add_remember_token.php b/database/migrations/2016_09_25_210947_add_remember_token.php new file mode 100644 index 0000000..83f72bd --- /dev/null +++ b/database/migrations/2016_09_25_210947_add_remember_token.php @@ -0,0 +1,32 @@ +<?php + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class AddRememberToken extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::table('users', function (Blueprint $table) { + $table->rememberToken(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('remember_token'); + }); + } +} diff --git a/database/migrations/2016_09_25_230620_create_password_resets_table.php b/database/migrations/2016_09_25_230620_create_password_resets_table.php new file mode 100644 index 0000000..bda733d --- /dev/null +++ b/database/migrations/2016_09_25_230620_create_password_resets_table.php @@ -0,0 +1,32 @@ +<?php + +use Illuminate\Support\Facades\Schema; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Database\Migrations\Migration; + +class CreatePasswordResetsTable extends Migration +{ + /** + * Run the migrations. + * + * @return void + */ + public function up() + { + Schema::create('password_resets', function (Blueprint $table) { + $table->string('email')->index(); + $table->string('token')->index(); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::drop('password_resets'); + } +} diff --git a/phpunit.xml b/phpunit.xml index cebc7a2..712e0af 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,22 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <phpunit backupGlobals="false" backupStaticAttributes="false" - bootstrap="bootstrap/app.php" + bootstrap="bootstrap/autoload.php" colors="true" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" processIsolation="false" - stopOnFailure="false" - syntaxCheck="false"> + stopOnFailure="false"> <testsuites> <testsuite name="Application Test Suite"> - <directory>./tests/</directory> + <directory suffix="Test.php">./tests</directory> </testsuite> </testsuites> <filter> - <whitelist> - <directory suffix=".php">app/</directory> + <whitelist processUncoveredFilesFromWhitelist="true"> + <directory suffix=".php">./app</directory> </whitelist> </filter> <php> diff --git a/public/index.php b/public/index.php index 04aa086..716731f 100644 --- a/public/index.php +++ b/public/index.php @@ -1,17 +1,39 @@ <?php +/** + * Laravel - A PHP Framework For Web Artisans + * + * @package Laravel + * @author Taylor Otwell <taylor@laravel.com> + */ + +/* +|-------------------------------------------------------------------------- +| Register The Auto Loader +|-------------------------------------------------------------------------- +| +| Composer provides a convenient, automatically generated class loader for +| our application. We just need to utilize it! We'll simply require it +| into the script here so that we don't have to worry about manual +| loading any of our classes later on. It feels nice to relax. +| +*/ + +require __DIR__.'/../bootstrap/autoload.php'; + /* |-------------------------------------------------------------------------- -| Create The Application +| Turn On The Lights |-------------------------------------------------------------------------- | -| First we need to get an application instance. This creates an instance -| of the application / container and bootstraps the application so it -| is ready to receive HTTP / Console requests from the environment. +| We need to illuminate PHP development, so let us turn on the lights. +| This bootstraps the framework and gets it ready for use, then it +| will load up this application so that we can run it and send +| the responses back to the browser and delight our users. | */ -$app = require __DIR__.'/../bootstrap/app.php'; +$app = require_once __DIR__.'/../bootstrap/app.php'; /* |-------------------------------------------------------------------------- @@ -25,4 +47,12 @@ $app = require __DIR__.'/../bootstrap/app.php'; | */ -$app->run(); +$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); + +$response = $kernel->handle( + $request = Illuminate\Http\Request::capture() +); + +$response->send(); + +$kernel->terminate($request, $response); diff --git a/public/js/moderators.js b/public/js/moderators.js index 10dd2a0..36ec3ed 100644 --- a/public/js/moderators.js +++ b/public/js/moderators.js @@ -54,7 +54,7 @@ $(document).ready(function(){ if (data.accepted) { alert('This verb has now been accepted!'); - container.parent().remove(); + container.remove(); } } }); diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php new file mode 100644 index 0000000..e5506df --- /dev/null +++ b/resources/lang/en/auth.php @@ -0,0 +1,19 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Authentication Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines are used during authentication for various + | messages that we need to display to the user. You are free to modify + | these language lines according to your application's requirements. + | + */ + + 'failed' => 'These credentials do not match our records.', + 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + +]; diff --git a/resources/lang/en/pagination.php b/resources/lang/en/pagination.php new file mode 100644 index 0000000..fcab34b --- /dev/null +++ b/resources/lang/en/pagination.php @@ -0,0 +1,19 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Pagination Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines are used by the paginator library to build + | the simple pagination links. You are free to change them to anything + | you want to customize your views to better match your application. + | + */ + + 'previous' => '« Previous', + 'next' => 'Next »', + +]; diff --git a/resources/lang/en/passwords.php b/resources/lang/en/passwords.php new file mode 100644 index 0000000..e5544d2 --- /dev/null +++ b/resources/lang/en/passwords.php @@ -0,0 +1,22 @@ +<?php + +return [ + + /* + |-------------------------------------------------------------------------- + | Password Reset Language Lines + |-------------------------------------------------------------------------- + | + | The following language lines are the default lines which match reasons + | that are given by the password broker for a password update attempt + | has failed, such as for an invalid token or invalid new password. + | + */ + + 'password' => 'Passwords must be at least six characters and match the confirmation.', + 'reset' => 'Your password has been reset!', + 'sent' => 'We have e-mailed your password reset link!', + 'token' => 'This password reset token is invalid.', + 'user' => "We can't find a user with that e-mail address.", + +]; diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php index ff1c087..73b49d0 100644 --- a/resources/lang/en/validation.php +++ b/resources/lang/en/validation.php @@ -34,13 +34,18 @@ return [ 'different' => 'The :attribute and :other must be different.', 'digits' => 'The :attribute must be :digits digits.', 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', 'email' => 'The :attribute must be a valid email address.', - 'filled' => 'The :attribute field is required.', 'exists' => 'The selected :attribute is invalid.', + 'file' => 'The :attribute must be a file.', + 'filled' => 'The :attribute field is required.', 'image' => 'The :attribute must be an image.', 'in' => 'The selected :attribute is invalid.', + 'in_array' => 'The :attribute field does not exist in :other.', 'integer' => 'The :attribute must be an integer.', 'ip' => 'The :attribute must be a valid IP address.', + 'json' => 'The :attribute must be a valid JSON string.', 'max' => [ 'numeric' => 'The :attribute may not be greater than :max.', 'file' => 'The :attribute may not be greater than :max kilobytes.', @@ -48,6 +53,7 @@ return [ 'array' => 'The :attribute may not have more than :max items.', ], 'mimes' => 'The :attribute must be a file of type: :values.', + 'mimetypes' => 'The :attribute must be a file of type: :values.', 'min' => [ 'numeric' => 'The :attribute must be at least :min.', 'file' => 'The :attribute must be at least :min kilobytes.', @@ -56,9 +62,11 @@ return [ ], 'not_in' => 'The selected :attribute is invalid.', 'numeric' => 'The :attribute must be a number.', + 'present' => 'The :attribute field must be present.', 'regex' => 'The :attribute format is invalid.', 'required' => 'The :attribute field is required.', 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', 'required_with' => 'The :attribute field is required when :values is present.', 'required_with_all' => 'The :attribute field is required when :values is present.', 'required_without' => 'The :attribute field is required when :values is not present.', @@ -70,9 +78,11 @@ return [ 'string' => 'The :attribute must be :size characters.', 'array' => 'The :attribute must contain :size items.', ], + 'string' => 'The :attribute must be a string.', + 'timezone' => 'The :attribute must be a valid zone.', 'unique' => 'The :attribute has already been taken.', + 'uploaded' => 'The :attribute failed to upload.', 'url' => 'The :attribute format is invalid.', - 'timezone' => 'The :attribute must be a valid zone.', /* |-------------------------------------------------------------------------- diff --git a/resources/views/.gitkeep b/resources/views/.gitkeep deleted file mode 100644 index e69de29..0000000 --- a/resources/views/.gitkeep +++ /dev/null diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php new file mode 100644 index 0000000..2070f2b --- /dev/null +++ b/resources/views/auth/login.blade.php @@ -0,0 +1,68 @@ +@extends('layouts.master') + +@section('master-content') +<div class="container"> + <div class="row"> + <div class="col-md-8 col-md-offset-2"> + <div class="panel panel-default"> + <div class="panel-heading">Login</div> + <div class="panel-body"> + <form class="form-horizontal" role="form" method="POST" action="{{ url('/login') }}"> + {{ csrf_field() }} + + <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> + <label for="email" class="col-md-4 control-label">E-Mail Address</label> + + <div class="col-md-6"> + <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus> + + @if ($errors->has('email')) + <span class="help-block"> + <strong>{{ $errors->first('email') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}"> + <label for="password" class="col-md-4 control-label">Password</label> + + <div class="col-md-6"> + <input id="password" type="password" class="form-control" name="password" required> + + @if ($errors->has('password')) + <span class="help-block"> + <strong>{{ $errors->first('password') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group"> + <div class="col-md-6 col-md-offset-4"> + <div class="checkbox"> + <label> + <input type="checkbox" name="remember"> Remember Me + </label> + </div> + </div> + </div> + + <div class="form-group"> + <div class="col-md-8 col-md-offset-4"> + <button type="submit" class="btn btn-primary"> + Login + </button> + + <a class="btn btn-link" href="{{ url('/password/reset') }}"> + Forgot Your Password? + </a> + </div> + </div> + </form> + </div> + </div> + </div> + </div> +</div> +@endsection diff --git a/resources/views/auth/passwords/email.blade.php b/resources/views/auth/passwords/email.blade.php new file mode 100644 index 0000000..62e0120 --- /dev/null +++ b/resources/views/auth/passwords/email.blade.php @@ -0,0 +1,47 @@ +@extends('layouts.master') + +<!-- Main Content --> +@section('master-content') +<div class="container"> + <div class="row"> + <div class="col-md-8 col-md-offset-2"> + <div class="panel panel-default"> + <div class="panel-heading">Reset Password</div> + <div class="panel-body"> + @if (session('status')) + <div class="alert alert-success"> + {{ session('status') }} + </div> + @endif + + <form class="form-horizontal" role="form" method="POST" action="{{ url('/password/email') }}"> + {{ csrf_field() }} + + <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> + <label for="email" class="col-md-4 control-label">E-Mail Address</label> + + <div class="col-md-6"> + <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required> + + @if ($errors->has('email')) + <span class="help-block"> + <strong>{{ $errors->first('email') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group"> + <div class="col-md-6 col-md-offset-4"> + <button type="submit" class="btn btn-primary"> + Send Password Reset Link + </button> + </div> + </div> + </form> + </div> + </div> + </div> + </div> +</div> +@endsection diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php new file mode 100644 index 0000000..deb4d56 --- /dev/null +++ b/resources/views/auth/passwords/reset.blade.php @@ -0,0 +1,70 @@ +@extends('layouts.master') + +@section('master-content') +<div class="container"> + <div class="row"> + <div class="col-md-8 col-md-offset-2"> + <div class="panel panel-default"> + <div class="panel-heading">Reset Password</div> + + <div class="panel-body"> + <form class="form-horizontal" role="form" method="POST" action="{{ url('/password/reset') }}"> + {{ csrf_field() }} + + <input type="hidden" name="token" value="{{ $token }}"> + + <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> + <label for="email" class="col-md-4 control-label">E-Mail Address</label> + + <div class="col-md-6"> + <input id="email" type="email" class="form-control" name="email" value="{{ $email or old('email') }}" required autofocus> + + @if ($errors->has('email')) + <span class="help-block"> + <strong>{{ $errors->first('email') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}"> + <label for="password" class="col-md-4 control-label">Password</label> + + <div class="col-md-6"> + <input id="password" type="password" class="form-control" name="password" required> + + @if ($errors->has('password')) + <span class="help-block"> + <strong>{{ $errors->first('password') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}"> + <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label> + <div class="col-md-6"> + <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required> + + @if ($errors->has('password_confirmation')) + <span class="help-block"> + <strong>{{ $errors->first('password_confirmation') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group"> + <div class="col-md-6 col-md-offset-4"> + <button type="submit" class="btn btn-primary"> + Reset Password + </button> + </div> + </div> + </form> + </div> + </div> + </div> + </div> +</div> +@endsection diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php new file mode 100644 index 0000000..c4f9009 --- /dev/null +++ b/resources/views/auth/register.blade.php @@ -0,0 +1,82 @@ +@extends('layouts.master') + +@section('master-content') +<div class="container"> + <div class="row"> + <div class="col-md-8 col-md-offset-2"> + <div class="panel panel-default"> + <div class="panel-heading">Register</div> + <div class="panel-body"> + <form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}"> + {{ csrf_field() }} + + <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}"> + <label for="name" class="col-md-4 control-label">Name</label> + + <div class="col-md-6"> + <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus> + + @if ($errors->has('name')) + <span class="help-block"> + <strong>{{ $errors->first('name') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> + <label for="email" class="col-md-4 control-label">E-Mail Address</label> + + <div class="col-md-6"> + <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required> + + @if ($errors->has('email')) + <span class="help-block"> + <strong>{{ $errors->first('email') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}"> + <label for="password" class="col-md-4 control-label">Password</label> + + <div class="col-md-6"> + <input id="password" type="password" class="form-control" name="password" required> + + @if ($errors->has('password')) + <span class="help-block"> + <strong>{{ $errors->first('password') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}"> + <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label> + + <div class="col-md-6"> + <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required> + + @if ($errors->has('password_confirmation')) + <span class="help-block"> + <strong>{{ $errors->first('password_confirmation') }}</strong> + </span> + @endif + </div> + </div> + + <div class="form-group"> + <div class="col-md-6 col-md-offset-4"> + <button type="submit" class="btn btn-primary"> + Register + </button> + </div> + </div> + </form> + </div> + </div> + </div> + </div> +</div> +@endsection diff --git a/resources/views/contribute.blade.php b/resources/views/contribute.blade.php index 2e0eff3..6ddd37c 100644 --- a/resources/views/contribute.blade.php +++ b/resources/views/contribute.blade.php @@ -9,8 +9,8 @@ use HebrewParseTrainer\Verb; </p> @if(!Auth::check()) - <a class="btn btn-lg btn-primary" href="{{ env('APP_URL') }}contribute?login=yes">Login</a> - <a class="btn btn-lg btn-success" href="{{ env('APP_URL') }}user/create">Sign up</a> + <a class="btn btn-lg btn-primary" href="{{ url('/login') }}">Login</a> + <a class="btn btn-lg btn-success" href="{{ url('/register') }}">Sign up</a> @endif <h3>Here's how it works:</h3> diff --git a/resources/views/layouts/master.blade.php b/resources/views/layouts/master.blade.php index 095fee9..5d244d0 100644 --- a/resources/views/layouts/master.blade.php +++ b/resources/views/layouts/master.blade.php @@ -28,18 +28,21 @@ $menu = [ if (Auth::check()) { $menu['Statistics'] = ['stats', 'stats']; - $menu['Logout'] = ['logout', 'logout']; } ?> <html lang="en"> <head> - <meta charset="utf-8"> + <meta charset="utf-8"/> + <meta name="csrf-token" content="{{ csrf_token() }}"/> + <title>ParseTrainer</title> - <link rel="stylesheet" href="{{ env('APP_URL') }}vendor/twbs/bootstrap/dist/css/bootstrap.min.css"> - <link rel="stylesheet" href="{{ env('APP_URL') }}public/css/hebrewparsetrainer.css"> + + <link rel="stylesheet" href="{{ asset('vendor/twbs/bootstrap/dist/css/bootstrap.min.css') }}"/> + <link rel="stylesheet" href="{{ asset('public/css/hebrewparsetrainer.css') }}"/> <script type="text/javascript"> var app_url = '{{ env('APP_URL') }}'; + window.Laravel = <?php echo json_encode([ 'csrfToken' => csrf_token() ]); ?>; </script> </head> <body role="application"> @@ -48,22 +51,29 @@ if (Auth::check()) { <nav> <ul class="nav nav-pills pull-right"> @foreach($menu as $name => $link) - <li role="presentation" class="{{ Request::is($link[0]) ? 'active' : '' }}"><a href="{{ env('APP_URL') }}{{ $link[1] }}">{{ $name }}</a></li> + <li role="presentation" class="{{ Request::is($link[0]) ? 'active' : '' }}"><a href="{{ url($link[1]) }}">{{ $name }}</a></li> @endforeach + @if(Auth::check()) + <li role="presentation"><a href="{{ url('/logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();">Logout</a></li> + @endif </ul> </nav> - <h2 class="text-muted"><a href="{{ env('APP_URL') }}">ParseTrainer</a></h2> + <h2 class="text-muted"><a href="{{ url('/') }}">ParseTrainer</a></h2> </div> @yield('master-content') </div> - <script src="{{ env('APP_URL') }}vendor/components/jquery/jquery.min.js"></script> - <script src="{{ env('APP_URL') }}vendor/twbs/bootstrap/dist/js/bootstrap.min.js"></script> - <script src="{{ env('APP_URL') }}public/js/alerts.js"></script> - <script src="{{ env('APP_URL') }}public/js/hebrewparsetrainer.js"></script> + <script src="{{ asset('vendor/components/jquery/jquery.min.js') }}"></script> + <script src="{{ asset('vendor/twbs/bootstrap/dist/js/bootstrap.min.js') }}"></script> + <script src="{{ asset('public/js/alerts.js') }}"></script> + <script src="{{ asset('public/js/hebrewparsetrainer.js') }}"></script> @if(Auth::check()) - <script src="{{ env('APP_URL') }}public/js/moderators.js"></script> + <script src="{{ asset('public/js/moderators.js') }}"></script> + + <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display:none;"> + {{ csrf_field() }} + </form> @endif </body> </html> diff --git a/resources/views/stats.blade.php b/resources/views/stats.blade.php index 27010fd..eb4205f 100644 --- a/resources/views/stats.blade.php +++ b/resources/views/stats.blade.php @@ -2,7 +2,9 @@ use \HebrewParseTrainer\RandomLog; $db_stats = RandomLog - ::select(DB::raw('COUNT(*) as count'), 'created_at') + ::select( + DB::raw('COUNT(*) as count'), + DB::raw('DATE(created_at) as created_at')) ->groupBy(DB::raw('DATE(created_at)')) ->orderBy('created_at') ->get(); @@ -21,7 +23,9 @@ foreach ($db_stats as $stat) { $stats['requests'] = "[" . implode(",", $stats['requests']) . "]"; $db_stats = RandomLog - ::select(DB::raw('COUNT(DISTINCT `ip`) as count'), 'created_at') + ::select( + DB::raw('COUNT(DISTINCT `ip`) as count'), + DB::raw('DATE(created_at) as created_at')) ->groupBy(DB::raw('DATE(created_at)')) ->orderBy('created_at') ->get(); diff --git a/resources/views/trainer.blade.php b/resources/views/trainer.blade.php index 02d9964..f03254a 100644 --- a/resources/views/trainer.blade.php +++ b/resources/views/trainer.blade.php @@ -82,10 +82,10 @@ use HebrewParseTrainer\Tense; <h3 class="panel-title">Contribute!</h3> </div> <div class="panel-body"> - <p>If this app is useful to you, please consider <a href="{{ env('APP_URL') }}contribute">contributing</a> by adding more verbs to the database!</p> + <p>If this app is useful to you, please consider <a href="{{ url('/contribute') }}">contributing</a> by adding more verbs to the database!</p> @if(!Auth::check()) - <a class="btn btn-success" href="{{ env('APP_URL') }}user/create">Sign up</a> - or <a href="{{ env('APP_URL') }}contribute?login=yes">login</a> + <a class="btn btn-success" href="{{ url('/register') }}">Sign up</a> + or <a href="{{ url('/login') }}">login</a> @endif </div> </div> diff --git a/routes/api.php b/routes/api.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/routes/api.php @@ -0,0 +1 @@ +<?php diff --git a/routes/console.php b/routes/console.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/routes/console.php @@ -0,0 +1 @@ +<?php diff --git a/routes/web.php b/routes/web.php new file mode 100644 index 0000000..40314cb --- /dev/null +++ b/routes/web.php @@ -0,0 +1,63 @@ +<?php +/** + * HebrewParseTrainer - practice Hebrew verbs + * Copyright (C) 2015 Camil Staps <info@camilstaps.nl> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +Route::group( + [ + 'prefix' => parse_url(env('APP_URL'), PHP_URL_PATH), + ], + function () { + + Route::get('/', function () { + return view('trainer'); + }); + + Route::get('/stem', function () { + return \HebrewParseTrainer\Stem::all(); + }); + + Route::get('/tense', function () { + return \HebrewParseTrainer\Tense::all(); + }); + + Route::get('/verb/random', + '\App\Http\Controllers\VerbController@random'); + + Route::get('/contribute', function () { + return view('contribute'); + }); + + Route::group(['middleware' => 'auth'], function () { + Route::get('/stats', function () { + return view('stats'); + }); + + Route::get('/verb/{id}/vote/{choice}', + '\App\Http\Controllers\VerbController@vote'); + + Route::post('/verb/suggest', + '\App\Http\Controllers\VerbController@suggest'); + + Route::post('/root/create', + '\App\Http\Controllers\RootController@create'); + + }); + +}); + +Auth::routes(); @@ -1,10 +1,19 @@ <?php -$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); +/** + * Laravel - A PHP Framework For Web Artisans + * + * @package Laravel + * @author Taylor Otwell <taylor@laravel.com> + */ + +$uri = urldecode( + parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) +); // This file allows us to emulate Apache's "mod_rewrite" functionality from the -// built-in PHP web server. This provides a convenient way to test a Lumen -// application without having installed a "real" server software here. +// built-in PHP web server. This provides a convenient way to test a Laravel +// application without having installed a "real" web server software here. if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { return false; } diff --git a/storage/app/.gitignore b/storage/app/.gitignore index d6b7ef3..8f4803c 100644 --- a/storage/app/.gitignore +++ b/storage/app/.gitignore @@ -1,2 +1,3 @@ * +!public/ !.gitignore diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/storage/app/public/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/storage/framework/.gitignore b/storage/framework/.gitignore new file mode 100644 index 0000000..b02b700 --- /dev/null +++ b/storage/framework/.gitignore @@ -0,0 +1,8 @@ +config.php +routes.php +schedule-* +compiled.php +services.json +events.scanned.php +routes.scanned.php +down diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php index 67c9299..2f2d20f 100644 --- a/tests/ExampleTest.php +++ b/tests/ExampleTest.php @@ -1,15 +1,19 @@ <?php +use Illuminate\Foundation\Testing\WithoutMiddleware; +use Illuminate\Foundation\Testing\DatabaseMigrations; +use Illuminate\Foundation\Testing\DatabaseTransactions; + class ExampleTest extends TestCase { /** - * A basic test example. + * A basic functional test example. * * @return void */ public function testBasicExample() { $this->visit('/') - ->see('Lumen.'); + ->see('Laravel'); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 651d9cb..8208edc 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,14 +1,25 @@ <?php -class TestCase extends Laravel\Lumen\Testing\TestCase +abstract class TestCase extends Illuminate\Foundation\Testing\TestCase { /** + * The base URL to use while testing the application. + * + * @var string + */ + protected $baseUrl = 'http://localhost'; + + /** * Creates the application. * - * @return \Laravel\Lumen\Application + * @return \Illuminate\Foundation\Application */ public function createApplication() { - return require __DIR__.'/../bootstrap/app.php'; + $app = require __DIR__.'/../bootstrap/app.php'; + + $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); + + return $app; } } |