diff --git a/.editorconfig b/.editorconfig index 1671c9b..8f0de65 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,9 +3,9 @@ root = true [*] charset = utf-8 end_of_line = lf -insert_final_newline = true -indent_style = space indent_size = 4 +indent_style = space +insert_final_newline = true trim_trailing_whitespace = true [*.md] diff --git a/.env.example b/.env.example index afc88e5..b534c68 100644 --- a/.env.example +++ b/.env.example @@ -29,12 +29,12 @@ REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_MAILER=smtp -MAIL_HOST=mailhog +MAIL_HOST=mailpit MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null -MAIL_FROM_ADDRESS=null +MAIL_FROM_ADDRESS="hello@example.com" MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= @@ -46,7 +46,14 @@ AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= +PUSHER_HOST= +PUSHER_PORT=443 +PUSHER_SCHEME=https PUSHER_APP_CLUSTER=mt1 -MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" -MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" +VITE_APP_NAME="${APP_NAME}" +VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +VITE_PUSHER_HOST="${PUSHER_HOST}" +VITE_PUSHER_PORT="${PUSHER_PORT}" +VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" +VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/.gitattributes b/.gitattributes index 967315d..fcb21d3 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,5 +1,11 @@ -* text=auto -*.css linguist-vendored -*.scss linguist-vendored -*.js linguist-vendored +* text=auto eol=lf + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore CHANGELOG.md export-ignore +.styleci.yml export-ignore diff --git a/.gitignore b/.gitignore index 0f81ee3..cee83f8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,21 @@ +/.phpunit.cache /node_modules +/public/build /public/hot /public/storage /storage/*.key /vendor .env .env.backup +.env.production .phpunit.result.cache docker-compose.override.yml Homestead.json Homestead.yaml +auth.json npm-debug.log yarn-error.log +/.fleet /.idea /.vscode composer.lock diff --git a/.styleci.yml b/.styleci.yml index 877ea70..9daadf1 100644 --- a/.styleci.yml +++ b/.styleci.yml @@ -1,14 +1,9 @@ php: preset: laravel - version: 8 disabled: - no_unused_imports finder: not-name: - index.php - - server.php -js: - finder: - not-name: - - webpack.mix.js +js: true css: true diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 69914e9..e6b9960 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -7,32 +7,18 @@ class Kernel extends ConsoleKernel { - /** - * The Artisan commands provided by your application. - * - * @var array - */ - protected $commands = [ - // - ]; - /** * Define the application's command schedule. - * - * @param \Illuminate\Console\Scheduling\Schedule $schedule - * @return void */ - protected function schedule(Schedule $schedule) + protected function schedule(Schedule $schedule): void { // $schedule->command('inspire')->hourly(); } /** * Register the commands for the application. - * - * @return void */ - protected function commands() + protected function commands(): void { $this->load(__DIR__.'/Commands'); diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 3ca4b34..56af264 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -8,18 +8,9 @@ class Handler extends ExceptionHandler { /** - * A list of the exception types that are not reported. + * The list of the inputs that are never flashed to the session on validation exceptions. * - * @var string[] - */ - protected $dontReport = [ - // - ]; - - /** - * A list of the inputs that are never flashed for validation exceptions. - * - * @var string[] + * @var array */ protected $dontFlash = [ 'current_password', @@ -29,10 +20,8 @@ class Handler extends ExceptionHandler /** * Register the exception handling callbacks for the application. - * - * @return void */ - public function register() + public function register(): void { $this->reportable(function (Throwable $e) { // diff --git a/app/Http/Controllers/Api/V1/UserController.php b/app/Http/Controllers/Api/V1/UserController.php index 168978c..beb5cbc 100644 --- a/app/Http/Controllers/Api/V1/UserController.php +++ b/app/Http/Controllers/Api/V1/UserController.php @@ -10,8 +10,6 @@ class UserController extends Controller { /** * Display a listing of the resource. - * - * @return \Illuminate\Http\Response */ public function index() { @@ -20,9 +18,6 @@ public function index() /** * Store a newly created resource in storage. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response */ public function store(Request $request) { @@ -35,9 +30,6 @@ public function store(Request $request) /** * Display the specified resource. - * - * @param User $user - * @return \Illuminate\Http\Response */ public function show(User $user) { @@ -46,10 +38,6 @@ public function show(User $user) /** * Update the specified resource in storage. - * - * @param \Illuminate\Http\Request $request - * @param User $user - * @return \Illuminate\Http\Response */ public function update(Request $request, User $user) { @@ -62,9 +50,6 @@ public function update(Request $request, User $user) /** * Remove the specified resource from storage. - * - * @param User $user - * @return \Illuminate\Http\Response */ public function destroy(User $user) { diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index a0a2a8a..77ec359 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -3,11 +3,10 @@ namespace App\Http\Controllers; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; -use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests; + use AuthorizesRequests, ValidatesRequests; } diff --git a/app/Http/Controllers/EloquentController.php b/app/Http/Controllers/EloquentController.php index 1d82892..e331077 100644 --- a/app/Http/Controllers/EloquentController.php +++ b/app/Http/Controllers/EloquentController.php @@ -30,7 +30,7 @@ public function task3() ]); } - public function task4($id) + public function task4(int $id) { // TODO Eloquent Задание 4: Найти Item по id и передать во view либо отдать 404 страницу // Одна строка кода вместо [] @@ -49,7 +49,7 @@ public function task5(Request $request) return redirect('/'); } - public function task6($id, Request $request) + public function task6(int $id, Request $request) { $product = Item::findOrFail($id); // TODO Eloquent Задание 6: В запросе будет все необходимое для обновления записи diff --git a/app/Http/Controllers/ItemController.php b/app/Http/Controllers/ItemController.php index e137712..500c0d0 100644 --- a/app/Http/Controllers/ItemController.php +++ b/app/Http/Controllers/ItemController.php @@ -9,8 +9,6 @@ class ItemController extends Controller { /** * Display a listing of the resource. - * - * @return \Illuminate\Http\Response */ public function index() { @@ -19,8 +17,6 @@ public function index() /** * Show the form for creating a new resource. - * - * @return \Illuminate\Http\Response */ public function create() { @@ -29,9 +25,6 @@ public function create() /** * Store a newly created resource in storage. - * - * @param ItemStoreRequest $request - * @return \Illuminate\Http\Response */ public function store(ItemStoreRequest $request) { @@ -40,45 +33,32 @@ public function store(ItemStoreRequest $request) /** * Display the specified resource. - * - * @param int $id - * @return \Illuminate\Http\Response */ - public function show($id) + public function show(int $id) { // } /** * Show the form for editing the specified resource. - * - * @param int $id - * @return \Illuminate\Http\Response */ - public function edit($id) + public function edit(int $id) { // } /** * Update the specified resource in storage. - * - * @param \Illuminate\Http\Request $request - * @param int $id - * @return \Illuminate\Http\Response */ - public function update(Request $request, $id) + public function update(Request $request, int $id) { // } /** * Remove the specified resource from storage. - * - * @param int $id - * @return \Illuminate\Http\Response */ - public function destroy($id) + public function destroy(int $id) { // } diff --git a/app/Http/Controllers/UserCrudController.php b/app/Http/Controllers/UserCrudController.php index c6cfed7..52a7057 100644 --- a/app/Http/Controllers/UserCrudController.php +++ b/app/Http/Controllers/UserCrudController.php @@ -9,8 +9,6 @@ class UserCrudController extends Controller { /** * Display a listing of the resource. - * - * @return \Illuminate\Http\Response */ public function index() { @@ -21,8 +19,6 @@ public function index() /** * Show the form for creating a new resource. - * - * @return \Illuminate\Http\Response */ public function create() { @@ -31,9 +27,6 @@ public function create() /** * Store a newly created resource in storage. - * - * @param \Illuminate\Http\Request $request - * @return \Illuminate\Http\Response */ public function store(Request $request) { @@ -48,9 +41,6 @@ public function store(Request $request) /** * Display the specified resource. - * - * @param User $user - * @return \Illuminate\Http\Response */ public function show(User $user) { @@ -59,9 +49,6 @@ public function show(User $user) /** * Show the form for editing the specified resource. - * - * @param User $user - * @return \Illuminate\Http\Response */ public function edit(User $user) { @@ -70,10 +57,6 @@ public function edit(User $user) /** * Update the specified resource in storage. - * - * @param \Illuminate\Http\Request $request - * @param User $user - * @return \Illuminate\Http\Response */ public function update(Request $request, User $user) { @@ -88,9 +71,6 @@ public function update(Request $request, User $user) /** * Remove the specified resource from storage. - * - * @param User $user - * @return \Illuminate\Http\Response */ public function destroy(User $user) { diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 39910d7..494c050 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -11,12 +11,12 @@ class Kernel extends HttpKernel * * These middleware are run during every request to your application. * - * @var array + * @var array */ protected $middleware = [ // \App\Http\Middleware\TrustHosts::class, \App\Http\Middleware\TrustProxies::class, - \Fruitcake\Cors\HandleCors::class, + \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, @@ -26,14 +26,13 @@ class Kernel extends HttpKernel /** * The application's route middleware groups. * - * @var array + * @var array> */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, - // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, @@ -41,26 +40,28 @@ class Kernel extends HttpKernel 'api' => [ // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, - 'throttle:api', + \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; /** - * The application's route middleware. + * The application's middleware aliases. * - * These middleware may be assigned to groups or used individually. + * Aliases may be used instead of class names to conveniently assign middleware to routes and groups. * - * @var array + * @var array */ - protected $routeMiddleware = [ + protected $middlewareAliases = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, - 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, + 'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, + 'signed' => \App\Http\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, ]; diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php index 704089a..d4ef644 100644 --- a/app/Http/Middleware/Authenticate.php +++ b/app/Http/Middleware/Authenticate.php @@ -3,19 +3,15 @@ namespace App\Http\Middleware; use Illuminate\Auth\Middleware\Authenticate as Middleware; +use Illuminate\Http\Request; class Authenticate extends Middleware { /** * Get the path the user should be redirected to when they are not authenticated. - * - * @param \Illuminate\Http\Request $request - * @return string|null */ - protected function redirectTo($request) + protected function redirectTo(Request $request): ?string { - if (! $request->expectsJson()) { - return route('login'); - } + return $request->expectsJson() ? null : route('login'); } } diff --git a/app/Http/Middleware/EncryptCookies.php b/app/Http/Middleware/EncryptCookies.php index 033136a..867695b 100644 --- a/app/Http/Middleware/EncryptCookies.php +++ b/app/Http/Middleware/EncryptCookies.php @@ -9,7 +9,7 @@ class EncryptCookies extends Middleware /** * The names of the cookies that should not be encrypted. * - * @var array + * @var array */ protected $except = [ // diff --git a/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/app/Http/Middleware/PreventRequestsDuringMaintenance.php index e4956d0..74cbd9a 100644 --- a/app/Http/Middleware/PreventRequestsDuringMaintenance.php +++ b/app/Http/Middleware/PreventRequestsDuringMaintenance.php @@ -9,7 +9,7 @@ class PreventRequestsDuringMaintenance extends Middleware /** * The URIs that should be reachable while maintenance mode is enabled. * - * @var array + * @var array */ protected $except = [ // diff --git a/app/Http/Middleware/RedirectIfAuthenticated.php b/app/Http/Middleware/RedirectIfAuthenticated.php index 362b48b..afc78c4 100644 --- a/app/Http/Middleware/RedirectIfAuthenticated.php +++ b/app/Http/Middleware/RedirectIfAuthenticated.php @@ -6,18 +6,16 @@ use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Symfony\Component\HttpFoundation\Response; class RedirectIfAuthenticated { /** * Handle an incoming request. * - * @param \Illuminate\Http\Request $request - * @param \Closure $next - * @param string|null ...$guards - * @return mixed + * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ - public function handle(Request $request, Closure $next, ...$guards) + public function handle(Request $request, Closure $next, string ...$guards): Response { $guards = empty($guards) ? [null] : $guards; diff --git a/app/Http/Middleware/TrimStrings.php b/app/Http/Middleware/TrimStrings.php index a8a252d..88cadca 100644 --- a/app/Http/Middleware/TrimStrings.php +++ b/app/Http/Middleware/TrimStrings.php @@ -9,7 +9,7 @@ class TrimStrings extends Middleware /** * The names of the attributes that should not be trimmed. * - * @var array + * @var array */ protected $except = [ 'current_password', diff --git a/app/Http/Middleware/TrustHosts.php b/app/Http/Middleware/TrustHosts.php index b0550cf..c9c58bd 100644 --- a/app/Http/Middleware/TrustHosts.php +++ b/app/Http/Middleware/TrustHosts.php @@ -9,9 +9,9 @@ class TrustHosts extends Middleware /** * Get the host patterns that should be trusted. * - * @return array + * @return array */ - public function hosts() + public function hosts(): array { return [ $this->allSubdomainsOfApplicationUrl(), diff --git a/app/Http/Middleware/TrustProxies.php b/app/Http/Middleware/TrustProxies.php index 0c7d3b6..3391630 100644 --- a/app/Http/Middleware/TrustProxies.php +++ b/app/Http/Middleware/TrustProxies.php @@ -10,7 +10,7 @@ class TrustProxies extends Middleware /** * The trusted proxies for this application. * - * @var array|string|null + * @var array|string|null */ protected $proxies; diff --git a/app/Http/Middleware/ValidateSignature.php b/app/Http/Middleware/ValidateSignature.php new file mode 100644 index 0000000..093bf64 --- /dev/null +++ b/app/Http/Middleware/ValidateSignature.php @@ -0,0 +1,22 @@ + + */ + protected $except = [ + // 'fbclid', + // 'utm_campaign', + // 'utm_content', + // 'utm_medium', + // 'utm_source', + // 'utm_term', + ]; +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 0c13b85..9e86521 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -9,7 +9,7 @@ class VerifyCsrfToken extends Middleware /** * The URIs that should be excluded from CSRF verification. * - * @var array + * @var array */ protected $except = [ // diff --git a/app/Http/Requests/ItemStoreRequest.php b/app/Http/Requests/ItemStoreRequest.php index d921832..c77e7be 100644 --- a/app/Http/Requests/ItemStoreRequest.php +++ b/app/Http/Requests/ItemStoreRequest.php @@ -8,10 +8,8 @@ class ItemStoreRequest extends FormRequest { /** * Determine if the user is authorized to make this request. - * - * @return bool */ - public function authorize() + public function authorize(): bool { return true; } @@ -19,16 +17,13 @@ public function authorize() /** * Get the validation rules that apply to the request. * - * @return array + * @return array|string> */ - public function rules() + public function rules(): array { return [ - //TODO Validation Задание: Добавить правила валидации для поля title - // Поле обязательно - // Строковое - // Минимам 5 символов - // Максимум 15 символов + // TODO Validation Задание: Добавить правила валидации для поля title + // Поле обязательно, строковое, минимум 5 символов, максимум 15 символов ]; } } diff --git a/app/Models/User.php b/app/Models/User.php index e23e090..4d7f70f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,7 +2,7 @@ namespace App\Models; -use Illuminate\Contracts\Auth\MustVerifyEmail; +// use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; @@ -15,7 +15,7 @@ class User extends Authenticatable /** * The attributes that are mass assignable. * - * @var string[] + * @var array */ protected $fillable = [ 'name', @@ -26,7 +26,7 @@ class User extends Authenticatable /** * The attributes that should be hidden for serialization. * - * @var array + * @var array */ protected $hidden = [ 'password', @@ -36,9 +36,10 @@ class User extends Authenticatable /** * The attributes that should be cast. * - * @var array + * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', + 'password' => 'hashed', ]; } diff --git a/app/Policies/ItemPolicy.php b/app/Policies/ItemPolicy.php index dd7d720..66a00a2 100644 --- a/app/Policies/ItemPolicy.php +++ b/app/Policies/ItemPolicy.php @@ -4,42 +4,29 @@ use App\Models\Item; use App\Models\User; -use Illuminate\Auth\Access\HandlesAuthorization; class ItemPolicy { - use HandlesAuthorization; - /** * Determine whether the user can view any models. - * - * @param \App\Models\User $user - * @return \Illuminate\Auth\Access\Response|bool */ - public function viewAny(User $user) + public function viewAny(User $user): bool { return true; } /** * Determine whether the user can view the model. - * - * @param \App\Models\User $user - * @param \App\Models\Item $item - * @return \Illuminate\Auth\Access\Response|bool */ - public function view(User $user, Item $item) + public function view(User $user, Item $item): bool { return true; } /** * Determine whether the user can create models. - * - * @param \App\Models\User $user - * @return \Illuminate\Auth\Access\Response|bool */ - public function create(User $user) + public function create(User $user): bool { // TODO Auth Задание: Разрешить добавление продуктов только пользователю с id = 10 @@ -48,48 +35,32 @@ public function create(User $user) /** * Determine whether the user can update the model. - * - * @param \App\Models\User $user - * @param \App\Models\Item $item - * @return \Illuminate\Auth\Access\Response|bool */ - public function update(User $user, Item $item) + public function update(User $user, Item $item): bool { return true; } /** * Determine whether the user can delete the model. - * - * @param \App\Models\User $user - * @param \App\Models\Item $item - * @return \Illuminate\Auth\Access\Response|bool */ - public function delete(User $user, Item $item) + public function delete(User $user, Item $item): bool { return true; } /** * Determine whether the user can restore the model. - * - * @param \App\Models\User $user - * @param \App\Models\Item $item - * @return \Illuminate\Auth\Access\Response|bool */ - public function restore(User $user, Item $item) + public function restore(User $user, Item $item): bool { return true; } /** * Determine whether the user can permanently delete the model. - * - * @param \App\Models\User $user - * @param \App\Models\Item $item - * @return \Illuminate\Auth\Access\Response|bool */ - public function forceDelete(User $user, Item $item) + public function forceDelete(User $user, Item $item): bool { return true; } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index b179285..452e6b6 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,29 +2,23 @@ namespace App\Providers; -use App\View\Components\HelloWorld; -use Illuminate\Support\Facades\Blade; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. - * - * @return void */ - public function register() + public function register(): void { // } /** * Bootstrap any application services. - * - * @return void */ - public function boot() + public function boot(): void { - + // } } diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index bb79423..54756cd 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -2,31 +2,25 @@ namespace App\Providers; -use App\Models\Item; -use App\Policies\ItemPolicy; +// use Illuminate\Support\Facades\Gate; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\Gate; class AuthServiceProvider extends ServiceProvider { /** - * The policy mappings for the application. + * The model to policy mappings for the application. * - * @var array + * @var array */ protected $policies = [ - // 'App\Models\Model' => 'App\Policies\ModelPolicy', + // ]; /** * Register any authentication / authorization services. - * - * @return void */ - public function boot() + public function boot(): void { - $this->registerPolicies(); - // } } diff --git a/app/Providers/BroadcastServiceProvider.php b/app/Providers/BroadcastServiceProvider.php index 395c518..2be04f5 100644 --- a/app/Providers/BroadcastServiceProvider.php +++ b/app/Providers/BroadcastServiceProvider.php @@ -9,10 +9,8 @@ class BroadcastServiceProvider extends ServiceProvider { /** * Bootstrap any application services. - * - * @return void */ - public function boot() + public function boot(): void { Broadcast::routes(); diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index a9f10a6..2d65aac 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -10,9 +10,9 @@ class EventServiceProvider extends ServiceProvider { /** - * The event listener mappings for the application. + * The event to listener mappings for the application. * - * @var array + * @var array> */ protected $listen = [ Registered::class => [ @@ -22,11 +22,17 @@ class EventServiceProvider extends ServiceProvider /** * Register any events for your application. - * - * @return void */ - public function boot() + public function boot(): void { // } + + /** + * Determine if events and listeners should be automatically discovered. + */ + public function shouldDiscoverEvents(): bool + { + return false; + } } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 3bd3c81..1cf5f15 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -11,53 +11,30 @@ class RouteServiceProvider extends ServiceProvider { /** - * The path to the "home" route for your application. + * The path to your application's "home" route. * - * This is used by Laravel authentication to redirect users after login. + * Typically, users are redirected here after authentication. * * @var string */ public const HOME = '/home'; /** - * The controller namespace for the application. - * - * When present, controller route declarations will automatically be prefixed with this namespace. - * - * @var string|null - */ - // protected $namespace = 'App\\Http\\Controllers'; - - /** - * Define your route model bindings, pattern filters, etc. - * - * @return void + * Define your route model bindings, pattern filters, and other route configuration. */ - public function boot() + public function boot(): void { - $this->configureRateLimiting(); + RateLimiter::for('api', function (Request $request) { + return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); + }); $this->routes(function () { - Route::prefix('api') - ->middleware('api') - ->namespace($this->namespace) + Route::middleware('api') + ->prefix('api') ->group(base_path('routes/api.php')); Route::middleware('web') - ->namespace($this->namespace) ->group(base_path('routes/web.php')); }); } - - /** - * Configure the rate limiters for the application. - * - * @return void - */ - protected function configureRateLimiting() - { - RateLimiter::for('api', function (Request $request) { - return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()); - }); - } } diff --git a/composer.json b/composer.json index 5de1aab..74d373d 100644 --- a/composer.json +++ b/composer.json @@ -1,26 +1,26 @@ { "name": "laravel/laravel", "type": "project", - "description": "The Laravel Framework.", - "keywords": ["framework", "laravel"], + "description": "The skeleton application for the Laravel framework.", + "keywords": ["laravel", "framework"], "license": "MIT", "require": { - "php": "^8.0", + "php": "^8.1", "doctrine/dbal": "^3.1", - "fruitcake/laravel-cors": "^2.0", - "guzzlehttp/guzzle": "^7.0.1", - "laravel/framework": "^9.0", - "laravel/sanctum": "^2.11", - "laravel/tinker": "^2.5" + "guzzlehttp/guzzle": "^7.2", + "laravel/framework": "^10.10", + "laravel/sanctum": "^3.3", + "laravel/tinker": "^2.8" }, "require-dev": { "barryvdh/laravel-debugbar": "^3.13", - "spatie/laravel-ignition": "^1.0", "fakerphp/faker": "^1.9.1", - "laravel/sail": "^1.0.1", + "laravel/pint": "^1.0", + "laravel/sail": "^1.18", "mockery/mockery": "^1.4.4", - "nunomaduro/collision": "^6.1", - "phpunit/phpunit": "^9.5.10" + "nunomaduro/collision": "^7.0", + "phpunit/phpunit": "^10.1", + "spatie/laravel-ignition": "^2.0" }, "autoload": { "psr-4": { @@ -40,7 +40,7 @@ "@php artisan package:discover --ansi" ], "post-update-cmd": [ - "@php artisan vendor:publish --tag=laravel-assets --ansi" + "@php artisan vendor:publish --tag=laravel-assets --ansi --force" ], "post-root-package-install": [ "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" @@ -57,8 +57,12 @@ "config": { "optimize-autoloader": true, "preferred-install": "dist", - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "pestphp/pest-plugin": true, + "php-http/discovery": true + } }, - "minimum-stability": "dev", + "minimum-stability": "stable", "prefer-stable": true } diff --git a/config/app.php b/config/app.php index a8d1a82..9207160 100644 --- a/config/app.php +++ b/config/app.php @@ -1,5 +1,8 @@ env('APP_URL', 'http://localhost'), - 'asset_url' => env('ASSET_URL', null), + 'asset_url' => env('ASSET_URL'), /* |-------------------------------------------------------------------------- @@ -123,6 +126,24 @@ 'cipher' => 'AES-256-CBC', + /* + |-------------------------------------------------------------------------- + | Maintenance Mode Driver + |-------------------------------------------------------------------------- + | + | These configuration options determine the driver used to determine and + | manage Laravel's "maintenance mode" status. The "cache" driver will + | allow maintenance mode to be controlled across multiple machines. + | + | Supported drivers: "file", "cache" + | + */ + + 'maintenance' => [ + 'driver' => 'file', + // 'store' => 'redis', + ], + /* |-------------------------------------------------------------------------- | Autoloaded Service Providers @@ -134,34 +155,7 @@ | */ - '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, - + 'providers' => ServiceProvider::defaultProviders()->merge([ /* * Package Service Providers... */ @@ -174,8 +168,7 @@ // App\Providers\BroadcastServiceProvider::class, App\Providers\EventServiceProvider::class, App\Providers\RouteServiceProvider::class, - - ], + ])->toArray(), /* |-------------------------------------------------------------------------- @@ -188,48 +181,8 @@ | */ - 'aliases' => [ - - 'App' => Illuminate\Support\Facades\App::class, - 'Arr' => Illuminate\Support\Arr::class, - 'Artisan' => Illuminate\Support\Facades\Artisan::class, - 'Auth' => Illuminate\Support\Facades\Auth::class, - 'Blade' => Illuminate\Support\Facades\Blade::class, - 'Broadcast' => Illuminate\Support\Facades\Broadcast::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, - 'Date' => Illuminate\Support\Facades\Date::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, - 'Http' => Illuminate\Support\Facades\Http::class, - 'Js' => Illuminate\Support\Js::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, - 'RateLimiter' => Illuminate\Support\Facades\RateLimiter::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, - 'Str' => Illuminate\Support\Str::class, - 'URL' => Illuminate\Support\Facades\URL::class, - 'Validator' => Illuminate\Support\Facades\Validator::class, - 'View' => Illuminate\Support\Facades\View::class, - - ], + 'aliases' => Facade::defaultAliases()->merge([ + // 'Example' => App\Facades\Example::class, + ])->toArray(), ]; diff --git a/config/auth.php b/config/auth.php index e29a3f7..9548c15 100644 --- a/config/auth.php +++ b/config/auth.php @@ -80,16 +80,20 @@ | 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 + | The expiry time is the number of minutes that each reset token will be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | + | The throttle setting is the number of seconds a user must wait before + | generating more password reset tokens. This prevents the user from + | quickly generating a very large amount of password reset tokens. + | */ 'passwords' => [ 'users' => [ 'provider' => 'users', - 'table' => 'password_resets', + 'table' => 'password_reset_tokens', 'expire' => 60, 'throttle' => 60, ], diff --git a/config/broadcasting.php b/config/broadcasting.php index 2d52982..2410485 100644 --- a/config/broadcasting.php +++ b/config/broadcasting.php @@ -37,7 +37,14 @@ 'app_id' => env('PUSHER_APP_ID'), 'options' => [ 'cluster' => env('PUSHER_APP_CLUSTER'), - 'useTLS' => true, + 'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com', + 'port' => env('PUSHER_PORT', 443), + 'scheme' => env('PUSHER_SCHEME', 'https'), + 'encrypted' => true, + 'useTLS' => env('PUSHER_SCHEME', 'https') === 'https', + ], + 'client_options' => [ + // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html ], ], diff --git a/config/cache.php b/config/cache.php index 8736c7a..d4171e2 100644 --- a/config/cache.php +++ b/config/cache.php @@ -52,6 +52,7 @@ 'file' => [ 'driver' => 'file', 'path' => storage_path('framework/cache/data'), + 'lock_path' => storage_path('framework/cache/data'), ], 'memcached' => [ @@ -99,12 +100,12 @@ | 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. + | When utilizing the APC, database, memcached, Redis, or DynamoDB cache + | stores there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. | */ - 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'), + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), ]; diff --git a/config/database.php b/config/database.php index b42d9b3..137ad18 100644 --- a/config/database.php +++ b/config/database.php @@ -74,7 +74,7 @@ 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, - 'schema' => 'public', + 'search_path' => 'public', 'sslmode' => 'prefer', ], @@ -89,6 +89,8 @@ 'charset' => 'utf8', 'prefix' => '', 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), ], ], @@ -129,7 +131,8 @@ 'default' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), - 'password' => env('REDIS_PASSWORD', null), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_DB', '0'), ], @@ -137,7 +140,8 @@ 'cache' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), - 'password' => env('REDIS_PASSWORD', null), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_CACHE_DB', '1'), ], diff --git a/config/filesystems.php b/config/filesystems.php index cf5abce..e9d9dbd 100644 --- a/config/filesystems.php +++ b/config/filesystems.php @@ -22,7 +22,7 @@ | | 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. + | been set up for each driver as an example of the required values. | | Supported Drivers: "local", "ftp", "sftp", "s3" | @@ -33,6 +33,7 @@ 'local' => [ 'driver' => 'local', 'root' => storage_path('app'), + 'throw' => false, ], 'public' => [ @@ -40,6 +41,7 @@ 'root' => storage_path('app/public'), 'url' => env('APP_URL').'/storage', 'visibility' => 'public', + 'throw' => false, ], 's3' => [ @@ -51,6 +53,7 @@ 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, ], ], diff --git a/config/hashing.php b/config/hashing.php index 8425770..0e8a0bb 100644 --- a/config/hashing.php +++ b/config/hashing.php @@ -29,7 +29,8 @@ */ 'bcrypt' => [ - 'rounds' => env('BCRYPT_ROUNDS', 10), + 'rounds' => env('BCRYPT_ROUNDS', 12), + 'verify' => true, ], /* @@ -44,9 +45,10 @@ */ 'argon' => [ - 'memory' => 1024, - 'threads' => 2, - 'time' => 2, + 'memory' => 65536, + 'threads' => 1, + 'time' => 4, + 'verify' => true, ], ]; diff --git a/config/logging.php b/config/logging.php index 880cd92..c44d276 100644 --- a/config/logging.php +++ b/config/logging.php @@ -3,6 +3,7 @@ use Monolog\Handler\NullHandler; use Monolog\Handler\StreamHandler; use Monolog\Handler\SyslogUdpHandler; +use Monolog\Processor\PsrLogMessageProcessor; return [ @@ -30,7 +31,10 @@ | */ - 'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'deprecations' => [ + 'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + 'trace' => false, + ], /* |-------------------------------------------------------------------------- @@ -58,6 +62,7 @@ 'driver' => 'single', 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, ], 'daily' => [ @@ -65,6 +70,7 @@ 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), 'days' => 14, + 'replace_placeholders' => true, ], 'slack' => [ @@ -73,16 +79,19 @@ 'username' => 'Laravel Log', 'emoji' => ':boom:', 'level' => env('LOG_LEVEL', 'critical'), + 'replace_placeholders' => true, ], 'papertrail' => [ 'driver' => 'monolog', 'level' => env('LOG_LEVEL', 'debug'), - 'handler' => SyslogUdpHandler::class, + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), 'handler_with' => [ 'host' => env('PAPERTRAIL_URL'), 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), ], + 'processors' => [PsrLogMessageProcessor::class], ], 'stderr' => [ @@ -93,16 +102,20 @@ 'with' => [ 'stream' => 'php://stderr', ], + 'processors' => [PsrLogMessageProcessor::class], ], 'syslog' => [ 'driver' => 'syslog', 'level' => env('LOG_LEVEL', 'debug'), + 'facility' => LOG_USER, + 'replace_placeholders' => true, ], 'errorlog' => [ 'driver' => 'errorlog', 'level' => env('LOG_LEVEL', 'debug'), + 'replace_placeholders' => true, ], 'null' => [ diff --git a/config/mail.php b/config/mail.php index e860749..e894b2e 100644 --- a/config/mail.php +++ b/config/mail.php @@ -28,38 +28,46 @@ | sending an e-mail. You will specify which one you are using for your | mailers below. You are free to add additional mailers as required. | - | Supported: "smtp", "sendmail", "mailgun", "ses", - | "postmark", "log", "array", "failover" + | Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2", + | "postmark", "log", "array", "failover", "roundrobin" | */ 'mailers' => [ 'smtp' => [ 'transport' => 'smtp', + 'url' => env('MAIL_URL'), 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'port' => env('MAIL_PORT', 587), 'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), 'timeout' => null, - 'auth_mode' => null, + 'local_domain' => env('MAIL_EHLO_DOMAIN'), ], 'ses' => [ 'transport' => 'ses', ], - 'mailgun' => [ - 'transport' => 'mailgun', - ], - 'postmark' => [ 'transport' => 'postmark', + // 'message_stream_id' => null, + // 'client' => [ + // 'timeout' => 5, + // ], + ], + + 'mailgun' => [ + 'transport' => 'mailgun', + // 'client' => [ + // 'timeout' => 5, + // ], ], 'sendmail' => [ 'transport' => 'sendmail', - 'path' => '/usr/sbin/sendmail -bs', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), ], 'log' => [ @@ -78,6 +86,14 @@ 'log', ], ], + + 'roundrobin' => [ + 'transport' => 'roundrobin', + 'mailers' => [ + 'ses', + 'postmark', + ], + ], ], /* diff --git a/config/queue.php b/config/queue.php index 25ea5a8..01c6b05 100644 --- a/config/queue.php +++ b/config/queue.php @@ -73,6 +73,22 @@ ], + /* + |-------------------------------------------------------------------------- + | Job Batching + |-------------------------------------------------------------------------- + | + | The following options configure the database and table that store job + | batching information. These options can be updated to any database + | connection and table which has been defined by your application. + | + */ + + 'batching' => [ + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'job_batches', + ], + /* |-------------------------------------------------------------------------- | Failed Queue Jobs diff --git a/config/sanctum.php b/config/sanctum.php index 9281c92..aa3df55 100644 --- a/config/sanctum.php +++ b/config/sanctum.php @@ -1,5 +1,8 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', - env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' + Sanctum::currentApplicationUrlWithPort() ))), /* @@ -39,13 +42,28 @@ |-------------------------------------------------------------------------- | | This value controls the number of minutes until an issued token will be - | considered expired. If this value is null, personal access tokens do - | not expire. This won't tweak the lifetime of first-party sessions. + | considered expired. This will override any values set in the token's + | "expires_at" attribute, but first-party sessions are not affected. | */ 'expiration' => null, + /* + |-------------------------------------------------------------------------- + | Token Prefix + |-------------------------------------------------------------------------- + | + | Sanctum can prefix new tokens in order to take advantage of numerous + | security scanning initiatives maintained by open source platforms + | that notify developers if they commit tokens into repositories. + | + | See: https://docs.github.com/en/code-security/secret-scanning/about-secret-scanning + | + */ + + 'token_prefix' => env('SANCTUM_TOKEN_PREFIX', ''), + /* |-------------------------------------------------------------------------- | Sanctum Middleware @@ -59,6 +77,7 @@ 'middleware' => [ 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, + 'authenticate_session' => Laravel\Sanctum\Http\Middleware\AuthenticateSession::class, 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, ], diff --git a/config/services.php b/config/services.php index 2a1d616..0ace530 100644 --- a/config/services.php +++ b/config/services.php @@ -18,6 +18,7 @@ 'domain' => env('MAILGUN_DOMAIN'), 'secret' => env('MAILGUN_SECRET'), 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + 'scheme' => 'https', ], 'postmark' => [ diff --git a/config/session.php b/config/session.php index ac0802b..e738cb3 100644 --- a/config/session.php +++ b/config/session.php @@ -72,7 +72,7 @@ | */ - 'connection' => env('SESSION_CONNECTION', null), + 'connection' => env('SESSION_CONNECTION'), /* |-------------------------------------------------------------------------- @@ -100,7 +100,7 @@ | */ - 'store' => env('SESSION_STORE', null), + 'store' => env('SESSION_STORE'), /* |-------------------------------------------------------------------------- @@ -155,7 +155,7 @@ | */ - 'domain' => env('SESSION_DOMAIN', null), + 'domain' => env('SESSION_DOMAIN'), /* |-------------------------------------------------------------------------- @@ -198,4 +198,17 @@ 'same_site' => 'lax', + /* + |-------------------------------------------------------------------------- + | Partitioned Cookies + |-------------------------------------------------------------------------- + | + | Setting this value to true will tie the cookie to the top-level site for + | a cross-site context. Partitioned cookies are accepted by the browser + | when flagged "secure" and the Same-Site attribute is set to "none". + | + */ + + 'partitioned' => false, + ]; diff --git a/database/factories/ArticleFactory.php b/database/factories/ArticleFactory.php index d44a080..1ff1022 100644 --- a/database/factories/ArticleFactory.php +++ b/database/factories/ArticleFactory.php @@ -9,15 +9,15 @@ class ArticleFactory extends Factory /** * Define the model's default state. * - * @return array + * @return array */ - public function definition() + public function definition(): array { return [ - 'name' => $this->faker->words(2, true), - 'description' => $this->faker->text, - 'active' => $this->faker->boolean, - 'main' => $this->faker->boolean + 'name' => fake()->words(2, true), + 'description' => fake()->text, + 'active' => fake()->boolean, + 'main' => fake()->boolean ]; } } diff --git a/database/factories/CategoryFactory.php b/database/factories/CategoryFactory.php index c964388..434a34a 100644 --- a/database/factories/CategoryFactory.php +++ b/database/factories/CategoryFactory.php @@ -9,12 +9,12 @@ class CategoryFactory extends Factory /** * Define the model's default state. * - * @return array + * @return array */ - public function definition() + public function definition(): array { return [ - 'title' => $this->faker->words(2, true) + 'title' => fake()->words(2, true) ]; } } diff --git a/database/factories/ItemFactory.php b/database/factories/ItemFactory.php index 54833df..e46c6c8 100644 --- a/database/factories/ItemFactory.php +++ b/database/factories/ItemFactory.php @@ -9,13 +9,13 @@ class ItemFactory extends Factory /** * Define the model's default state. * - * @return array + * @return array */ - public function definition() + public function definition(): array { return [ - 'title' => $this->faker->words(2, true), - 'active' => $this->faker->boolean, + 'title' => fake()->words(2, true), + 'active' => fake()->boolean, ]; } } diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index a3eb239..584104c 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -3,37 +3,42 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; +use Illuminate\Support\Facades\Hash; use Illuminate\Support\Str; +/** + * @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User> + */ class UserFactory extends Factory { + /** + * The current password being used by the factory. + */ + protected static ?string $password; + /** * Define the model's default state. * - * @return array + * @return array */ - public function definition() + public function definition(): array { return [ - 'name' => $this->faker->name(), - 'email' => $this->faker->unique()->safeEmail(), + 'name' => fake()->name(), + 'email' => fake()->unique()->safeEmail(), 'email_verified_at' => now(), - 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'password' => static::$password ??= Hash::make('password'), 'remember_token' => Str::random(10), ]; } /** * Indicate that the model's email address should be unverified. - * - * @return \Illuminate\Database\Eloquent\Factories\Factory */ - public function unverified() + public function unverified(): static { - return $this->state(function (array $attributes) { - return [ - 'email_verified_at' => null, - ]; - }); + return $this->state(fn (array $attributes) => [ + 'email_verified_at' => null, + ]); } } diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 621a24e..444fafb 100644 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateUsersTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('users', function (Blueprint $table) { $table->id(); @@ -26,11 +24,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('users'); } -} +}; diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php index 0ee0a36..81a7229 100644 --- a/database/migrations/2014_10_12_100000_create_password_resets_table.php +++ b/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -4,17 +4,15 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreatePasswordResetsTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { - Schema::create('password_resets', function (Blueprint $table) { - $table->string('email')->index(); + Schema::create('password_reset_tokens', function (Blueprint $table) { + $table->string('email')->primary(); $table->string('token'); $table->timestamp('created_at')->nullable(); }); @@ -22,11 +20,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { - Schema::dropIfExists('password_resets'); + Schema::dropIfExists('password_reset_tokens'); } -} +}; diff --git a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php index 6aa6d74..249da81 100644 --- a/database/migrations/2019_08_19_000000_create_failed_jobs_table.php +++ b/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateFailedJobsTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('failed_jobs', function (Blueprint $table) { $table->id(); @@ -26,11 +24,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('failed_jobs'); } -} +}; diff --git a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php index 4315e16..e828ad8 100644 --- a/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php +++ b/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreatePersonalAccessTokensTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('personal_access_tokens', function (Blueprint $table) { $table->id(); @@ -20,17 +18,16 @@ public function up() $table->string('token', 64)->unique(); $table->text('abilities')->nullable(); $table->timestamp('last_used_at')->nullable(); + $table->timestamp('expires_at')->nullable(); $table->timestamps(); }); } /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('personal_access_tokens'); } -} +}; diff --git a/database/migrations/2021_11_18_142420_create_products_table.php b/database/migrations/2021_11_18_142420_create_products_table.php index 3510903..7988558 100644 --- a/database/migrations/2021_11_18_142420_create_products_table.php +++ b/database/migrations/2021_11_18_142420_create_products_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreateProductsTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { Schema::create('products', function (Blueprint $table) { $table->id(); @@ -23,11 +21,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { Schema::dropIfExists('products'); } -} +}; diff --git a/database/migrations/tasks/2021_11_18_122318_create_posts_table.php b/database/migrations/tasks/2021_11_18_122318_create_posts_table.php index 4575166..8435f62 100644 --- a/database/migrations/tasks/2021_11_18_122318_create_posts_table.php +++ b/database/migrations/tasks/2021_11_18_122318_create_posts_table.php @@ -4,14 +4,12 @@ use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; -class CreatePostsTable extends Migration +return new class extends Migration { /** * Run the migrations. - * - * @return void */ - public function up() + public function up(): void { //TODO Migrations Задание 1: Создать таблицу categories с 2 полями id и title (не забыть про timestamps) @@ -42,11 +40,9 @@ public function up() /** * Reverse the migrations. - * - * @return void */ - public function down() + public function down(): void { // TODO Migrations Задание 11: Удалить таблицы categories, articles, article_category если такие существуют } -} +}; diff --git a/package.json b/package.json index 00c6506..56f5ddc 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,13 @@ { "private": true, + "type": "module", "scripts": { - "dev": "npm run development", - "development": "mix", - "watch": "mix watch", - "watch-poll": "mix watch -- --watch-options-poll=1000", - "hot": "mix watch --hot", - "prod": "npm run production", - "production": "mix --production" + "dev": "vite", + "build": "vite build" }, "devDependencies": { - "axios": "^0.21", - "laravel-mix": "^6.0.6", - "lodash": "^4.17.19", - "postcss": "^8.1.14" + "axios": "^1.6.4", + "laravel-vite-plugin": "^1.0.0", + "vite": "^5.0.0" } } diff --git a/phpunit.xml b/phpunit.xml index bbb3870..7c1db36 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,28 +1,29 @@ - ./tests/Feature + tests/Feature - + - ./app + app - + - - - - - - - - - + + + + + + + + + + - \ No newline at end of file + diff --git a/public/index.php b/public/index.php index 002ee24..1d69f3a 100644 --- a/public/index.php +++ b/public/index.php @@ -16,8 +16,8 @@ | */ -if (file_exists(__DIR__.'/../storage/framework/maintenance.php')) { - require __DIR__.'/../storage/framework/maintenance.php'; +if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) { + require $maintenance; } /* diff --git a/resources/views/eloquent/task4.blade.php b/resources/views/eloquent/task4.blade.php index bfa0058..a8ea7ff 100644 --- a/resources/views/eloquent/task4.blade.php +++ b/resources/views/eloquent/task4.blade.php @@ -1 +1,3 @@ -{{ $product->title }} +@isset($product->title) + {{ $product->title }} +@endisset diff --git a/server.php b/server.php deleted file mode 100644 index 5fb6379..0000000 --- a/server.php +++ /dev/null @@ -1,21 +0,0 @@ - - */ - -$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 Laravel -// application without having installed a "real" web server software here. -if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) { - return false; -} - -require_once __DIR__.'/public/index.php'; diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php index 547152f..cc68301 100644 --- a/tests/CreatesApplication.php +++ b/tests/CreatesApplication.php @@ -3,15 +3,14 @@ namespace Tests; use Illuminate\Contracts\Console\Kernel; +use Illuminate\Foundation\Application; trait CreatesApplication { /** * Creates the application. - * - * @return \Illuminate\Foundation\Application */ - public function createApplication() + public function createApplication(): Application { $app = require __DIR__.'/../bootstrap/app.php'; diff --git a/tests/Feature/AuthTest.php b/tests/Feature/AuthTest.php index 3a49ef7..c85e03a 100644 --- a/tests/Feature/AuthTest.php +++ b/tests/Feature/AuthTest.php @@ -5,14 +5,13 @@ use App\Models\Item; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; use Tests\TestCase; class AuthTest extends TestCase { use RefreshDatabase; - public function test_task_1() + public function test_task_1(): void { $user = User::factory()->create(['id' => 1]); diff --git a/tests/Feature/BladeTest.php b/tests/Feature/BladeTest.php index 5550726..fdfb85e 100644 --- a/tests/Feature/BladeTest.php +++ b/tests/Feature/BladeTest.php @@ -4,16 +4,14 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Blade; -use Illuminate\Support\Facades\DB; use Tests\TestCase; class BladeTest extends TestCase { use RefreshDatabase; - public function test_task_1() + public function test_task_1(): void { $response = $this->get('/'); @@ -22,7 +20,7 @@ public function test_task_1() $response->assertViewHas('users'); } - public function test_task_2() + public function test_task_2(): void { $response = $this->get('/table'); @@ -30,7 +28,7 @@ public function test_task_2() $response->assertSee('Layout'); } - public function test_task_3() + public function test_task_3(): void { $response = $this->get('/table'); @@ -38,7 +36,7 @@ public function test_task_3() $response->assertSee('Menu Item 1'); } - public function test_task_4() + public function test_task_4(): void { $user = User::factory()->create(); @@ -51,7 +49,7 @@ public function test_task_4() $response->assertSee($user->id); } - public function test_task_5() + public function test_task_5(): void { $aliases = Blade::getClassComponentAliases(); @@ -63,7 +61,7 @@ public function test_task_5() $response->assertSee(now()->format('Y-m-d')); } - public function test_task_6_7() + public function test_task_6_7(): void { $response = $this->get('/table'); $response->assertDontSee(`class="bg-red-500"`); diff --git a/tests/Feature/MigrationsTest.php b/tests/Feature/MigrationsTest.php index ee1c7cc..6070dd9 100644 --- a/tests/Feature/MigrationsTest.php +++ b/tests/Feature/MigrationsTest.php @@ -4,53 +4,51 @@ use App\Models\Article; use App\Models\Category; -use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Schema; use Tests\TestCase; class MigrationsTest extends TestCase { - public function test_migrate() + public function test_migrate(): void { $this->expectNotToPerformAssertions(); Artisan::call('migrate', ['--path' => 'database/migrations/tasks']); } - public function test_tables_exists() + public function test_tables_exists(): void { $this->assertTrue(Schema::hasTable('categories')); $this->assertTrue(Schema::hasTable('articles')); $this->assertTrue(Schema::hasTable('article_category')); } - public function test_columns_exists() + public function test_columns_exists(): void { $this->assertTrue(Schema::hasColumn('categories', 'title')); $this->assertTrue(Schema::hasColumns('articles', ['name', 'description', 'active', 'main'])); } - public function test_soft_delete() + public function test_soft_delete(): void { $this->assertTrue(Schema::hasColumns('articles', ['deleted_at'])); } - public function test_timestamps() + public function test_timestamps(): void { $this->assertTrue(Schema::hasColumns('articles', ['created_at', 'updated_at'])); } - public function test_default_nullable() + public function test_default_nullable(): void { $article = Article::factory()->create(['name' => null]); $this->assertNull($article->name); } - public function test_relation_table() + public function test_relation_table(): void { $categories = Category::factory()->count(3); diff --git a/tests/Feature/ModelTest.php b/tests/Feature/ModelTest.php index 0d6c163..65ae145 100644 --- a/tests/Feature/ModelTest.php +++ b/tests/Feature/ModelTest.php @@ -10,7 +10,7 @@ class ModelTest extends TestCase { use RefreshDatabase; - public function test_task_1() + public function test_task_1(): void { $item = ['title' => 'Test']; @@ -19,7 +19,7 @@ public function test_task_1() $this->assertDatabaseHas('products', $item); } - public function test_task_2() + public function test_task_2(): void { $item1 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinutes(5)]); $item2 = Item::factory()->create(['active' => true, 'created_at' => now()->subMinutes(4)]); @@ -37,7 +37,7 @@ public function test_task_2() $response->assertSee('3.' . $item2->title); } - public function test_task_3() + public function test_task_3(): void { $item1 = Item::factory()->create(['active' => true]); $item2 = Item::factory()->create(['active' => false]); @@ -48,7 +48,7 @@ public function test_task_3() $response->assertDontSee($item2->title); } - public function test_task_4() + public function test_task_4(): void { $response = $this->get('/eloquent/task4/1'); $response->assertStatus(404); @@ -59,14 +59,14 @@ public function test_task_4() $response->assertViewHas('product', $item); } - public function test_task_5() + public function test_task_5(): void { $response = $this->post('/eloquent/task5', ['title' => 'Test']); $response->assertRedirect(); $this->assertDatabaseHas('products', ['title' => 'Test']); } - public function test_task_6() + public function test_task_6(): void { $item = new Item(); $item->title = 'Old title'; @@ -81,7 +81,7 @@ public function test_task_6() $this->assertDatabaseHas('products', ['title' => 'New title']); } - public function test_task_7() + public function test_task_7(): void { $products = Item::factory(4)->create(); $this->assertDatabaseCount('products', 4); diff --git a/tests/Feature/RouteTest.php b/tests/Feature/RouteTest.php index ca21ae0..e119483 100644 --- a/tests/Feature/RouteTest.php +++ b/tests/Feature/RouteTest.php @@ -4,34 +4,33 @@ use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; -use Illuminate\Foundation\Testing\WithFaker; -use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Hash; use Tests\TestCase; class RouteTest extends TestCase { use RefreshDatabase; - public function test_task_1() + public function test_task_1(): void { $response = $this->get('/hello'); $response->assertViewIs('hello'); } - public function test_task_2() + public function test_task_2(): void { $response = $this->get('/'); $response->assertViewIs('welcome'); $response->assertViewHas('title', 'Welcome'); } - public function test_task_3() + public function test_task_3(): void { $response = $this->get(route('contact')); $response->assertViewIs('pages.contact'); } - public function test_task_4() + public function test_task_4(): void { $user = User::factory()->create(); @@ -41,7 +40,7 @@ public function test_task_4() $response->assertViewIs('users.show'); } - public function test_task_5() + public function test_task_5(): void { $user = User::factory()->create(); @@ -51,20 +50,20 @@ public function test_task_5() $response->assertViewIs('users.show'); } - public function test_tasks_4_5_notfound() + public function test_tasks_4_5_notfound(): void { $response = $this->get('/user/test'); $response->assertNotFound(); } - public function test_task_6() + public function test_task_6(): void { $response = $this->get('/bad'); $response->assertRedirect('/good'); } - public function test_task_7() + public function test_task_7(): void { $user = User::factory()->create(); @@ -99,7 +98,7 @@ public function test_task_7() $response->assertRedirect('/users_crud'); } - public function test_tasks_8_12() + public function test_tasks_8_12(): void { $response = $this->get('/dashboard/admin'); $response->assertViewIs('welcome'); @@ -108,7 +107,6 @@ public function test_tasks_8_12() $response->assertViewIs('welcome'); $response->assertStatus(200); - $response = $this->get('/security/admin/auth'); $response->assertRedirect('login'); @@ -118,7 +116,7 @@ public function test_tasks_8_12() $response->assertStatus(200); } - public function test_task_13() + public function test_task_13(): void { $userAuth = User::factory()->create(); @@ -147,7 +145,7 @@ private function getUserRequestData() return [ 'name' => 'Name ' . random_int(1, 1000), 'email' => uniqid() . '@example.com', - 'password' => '123' + 'password' => Hash::make('123'), ]; } } diff --git a/vite.config.js b/vite.config.js new file mode 100644 index 0000000..421b569 --- /dev/null +++ b/vite.config.js @@ -0,0 +1,11 @@ +import { defineConfig } from 'vite'; +import laravel from 'laravel-vite-plugin'; + +export default defineConfig({ + plugins: [ + laravel({ + input: ['resources/css/app.css', 'resources/js/app.js'], + refresh: true, + }), + ], +}); diff --git a/webpack.mix.js b/webpack.mix.js deleted file mode 100644 index 2a22dc1..0000000 --- a/webpack.mix.js +++ /dev/null @@ -1,17 +0,0 @@ -const mix = require('laravel-mix'); - -/* - |-------------------------------------------------------------------------- - | Mix Asset Management - |-------------------------------------------------------------------------- - | - | Mix provides a clean, fluent API for defining some Webpack build steps - | for your Laravel applications. By default, we are compiling the CSS - | file for the application as well as bundling up all the JS files. - | - */ - -mix.js('resources/js/app.js', 'public/js') - .postCss('resources/css/app.css', 'public/css', [ - // - ]);