* #1 - project skeleton * #1 - composer fix * #1 - add app key to phpunit config * #1 - change default session driver * #1 - add EXTERNAL_WEBSERVER_PORT variable to .env.example
This commit is contained in:
parent
683b2367ea
commit
8f5f2b88f0
46
.env.example
Normal file
46
.env.example
Normal file
@ -0,0 +1,46 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=toby-db
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=toby
|
||||
DB_USERNAME=toby
|
||||
DB_PASSWORD=password
|
||||
DB_ROOT_PASSWORD=example
|
||||
|
||||
DOCKER_DB_EXTERNAL_PORT=3306
|
||||
DOCKER_DB_DATABASE=${DB_DATABASE}
|
||||
DOCKER_DB_USERNAME=${DB_USERNAME}
|
||||
DOCKER_DB_PASSWORD=${DB_PASSWORD}
|
||||
DOCKER_DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
|
||||
|
||||
EXTERNAL_WEBSERVER_PORT=
|
||||
XDG_CONFIG_HOME=/tmp
|
||||
|
||||
BROADCAST_DRIVER=log
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
SESSION_LIFETIME=120
|
||||
FILESYSTEM_DRIVER=local
|
||||
|
||||
MAILHOG_PORT=1025
|
||||
MAILHOG_DASHBOARD_PORT=8025
|
||||
|
||||
MAIL_MAILER=smtp
|
||||
MAIL_HOST=mailhog
|
||||
MAIL_PORT=${MAILHOG_PORT}
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS=null
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
DOCKER_INSTALL_XDEBUG=false
|
20
.github/dependabot.yml
vendored
Normal file
20
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: composer
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
time: "06:30"
|
||||
commit-message:
|
||||
prefix: "#5 - (php) "
|
||||
target-branch: main
|
||||
open-pull-requests-limit: 1
|
||||
- package-ecosystem: npm
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: monthly
|
||||
time: "06:30"
|
||||
commit-message:
|
||||
prefix: "#5 - (js) "
|
||||
target-branch: main
|
||||
open-pull-requests-limit: 1
|
16
.github/workflows/check-pr-title.yml
vendored
Normal file
16
.github/workflows/check-pr-title.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: Check PR Title
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- edited
|
||||
- synchronize
|
||||
- labeled
|
||||
- unlabeled
|
||||
|
||||
jobs:
|
||||
check-pr-title:
|
||||
name: Check PR title
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- uses: blumilksoftware/action-pr-title@v1.2.0
|
40
.github/workflows/test-and-lint.yml
vendored
Normal file
40
.github/workflows/test-and-lint.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: Build & Test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-composer-dependencies-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: ${{ runner.os }}-composer-dependencies
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.1
|
||||
extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, intl
|
||||
coverage: none
|
||||
|
||||
- name: Install Composer dependencies
|
||||
run: composer install --prefer-dist --no-interaction --no-suggest
|
||||
|
||||
- name: Run linter
|
||||
run: composer ecs
|
||||
|
||||
- name: Execute tests
|
||||
run: php artisan test --env=ci
|
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
/node_modules
|
||||
/public/hot
|
||||
/public/storage
|
||||
/public/js/
|
||||
/public/css/
|
||||
/public/mix-manifest.json
|
||||
/storage/*.key
|
||||
/storage/*.sqlite
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
.idea/
|
||||
.composer
|
83
README.md
83
README.md
@ -1,2 +1,83 @@
|
||||
# toby
|
||||
# Toby
|
||||
|
||||
HR software you love to hate
|
||||
|
||||
## Local setup
|
||||
|
||||
> `dcr` is an alias to `docker-compose run --rm -u "$(id -u):$(id -g)"`
|
||||
|
||||
- clone the repository
|
||||
- initialize `.env` file and customize if needed
|
||||
|
||||
cp .env.example .env
|
||||
|
||||
- build containers
|
||||
|
||||
docker-compose build --no-cache --pull
|
||||
|
||||
- run containers
|
||||
|
||||
docker-compose up -d
|
||||
|
||||
- install composer packages
|
||||
|
||||
dcr php composer install
|
||||
|
||||
- generate app key
|
||||
|
||||
dcr php php artisan key:generate
|
||||
|
||||
- generate storage link
|
||||
|
||||
dcr php php artisan storage:link
|
||||
|
||||
- migrate and seed database
|
||||
|
||||
dcr php php artisan migrate --seed
|
||||
|
||||
## Available containers (local)
|
||||
- **php** - php and composer stuff
|
||||
- **node** - npm stuff
|
||||
- **mysql** - database for local development
|
||||
- **mailhog** - for emails preview
|
||||
|
||||
## Running tests
|
||||
If xDebug is installed, set environment variable **XDEBUG_MODE=off** to improve performance
|
||||
|
||||
dcr -e XDEBUG_MODE=off php php artisan test
|
||||
|
||||
|
||||
## Code style check
|
||||
dcr php php vendor/bin/ecs check
|
||||
dcr php composer ecs
|
||||
dcr php php vendor/bin/ecs check --fix
|
||||
dcr php composer ecsf
|
||||
|
||||
## xDebug
|
||||
|
||||
To use xDebug you need to set `DOCKER_INSTALL_XDEBUG` to `true` in `.env` file.\
|
||||
Then rebuild php container `docker-compose up --build -d php`.\
|
||||
You can also set up xDebug params (see docs https://xdebug.org/docs/all_settings) in `docker/dev/php/php.ini` file:
|
||||
|
||||
Default values for xDebug:
|
||||
```
|
||||
xdebug.client_host=host.docker.internal
|
||||
xdebug.client_port=9003
|
||||
xdebug.mode=debug
|
||||
xdebug.start_with_request=yes
|
||||
xdebug.log_level=0
|
||||
```
|
||||
|
||||
### Disable xDebug
|
||||
it is possible to disable the Xdebug completely by setting the option **xdebug.mode** to **off**,
|
||||
or by setting the environment variable **XDEBUG_MODE=off**\
|
||||
See docs (https://xdebug.org/docs/all_settings#mode)
|
||||
|
||||
CLI:
|
||||
```
|
||||
XDEBUG_MODE=off php artisan test
|
||||
```
|
||||
Docker container:
|
||||
```
|
||||
docker-compose run --rm -e XDEBUG_MODE=off php php artisan test
|
||||
```
|
20
app/Console/Kernel.php
Normal file
20
app/Console/Kernel.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
}
|
||||
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__ . "/Commands");
|
||||
}
|
||||
}
|
16
app/Exceptions/Handler.php
Normal file
16
app/Exceptions/Handler.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
protected $dontFlash = [
|
||||
"current_password",
|
||||
"password",
|
||||
"password_confirmation",
|
||||
];
|
||||
}
|
17
app/Http/Controllers/Controller.php
Normal file
17
app/Http/Controllers/Controller.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\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;
|
||||
use DispatchesJobs;
|
||||
use ValidatesRequests;
|
||||
}
|
72
app/Http/Kernel.php
Normal file
72
app/Http/Kernel.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Http;
|
||||
|
||||
use Fruitcake\Cors\HandleCors;
|
||||
use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth;
|
||||
use Illuminate\Auth\Middleware\Authorize;
|
||||
use Illuminate\Auth\Middleware\EnsureEmailIsVerified;
|
||||
use Illuminate\Auth\Middleware\RequirePassword;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull;
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance;
|
||||
use Illuminate\Foundation\Http\Middleware\ValidatePostSize;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Http\Middleware\SetCacheHeaders;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Routing\Middleware\ThrottleRequests;
|
||||
use Illuminate\Routing\Middleware\ValidateSignature;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
|
||||
use Toby\Http\Middleware\Authenticate;
|
||||
use Toby\Http\Middleware\RedirectIfAuthenticated;
|
||||
use Toby\Http\Middleware\TrimStrings;
|
||||
use Toby\Http\Middleware\TrustProxies;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
protected $middleware = [
|
||||
TrustProxies::class,
|
||||
HandleCors::class,
|
||||
PreventRequestsDuringMaintenance::class,
|
||||
ValidatePostSize::class,
|
||||
TrimStrings::class,
|
||||
ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
protected $middlewareGroups = [
|
||||
"web" => [
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
AuthenticateSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
],
|
||||
|
||||
"api" => [
|
||||
EnsureFrontendRequestsAreStateful::class,
|
||||
"throttle:api",
|
||||
SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
protected $routeMiddleware = [
|
||||
"auth" => Authenticate::class,
|
||||
"auth.basic" => AuthenticateWithBasicAuth::class,
|
||||
"cache.headers" => SetCacheHeaders::class,
|
||||
"can" => Authorize::class,
|
||||
"guest" => RedirectIfAuthenticated::class,
|
||||
"password.confirm" => RequirePassword::class,
|
||||
"signed" => ValidateSignature::class,
|
||||
"throttle" => ThrottleRequests::class,
|
||||
"verified" => EnsureEmailIsVerified::class,
|
||||
];
|
||||
}
|
17
app/Http/Middleware/Authenticate.php
Normal file
17
app/Http/Middleware/Authenticate.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (!$request->expectsJson()) {
|
||||
return route("login");
|
||||
}
|
||||
}
|
||||
}
|
27
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
27
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Toby\Providers\RouteServiceProvider;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
public function handle(Request $request, Closure $next, ...$guards): Response
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
16
app/Http/Middleware/TrimStrings.php
Normal file
16
app/Http/Middleware/TrimStrings.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
protected $except = [
|
||||
"current_password",
|
||||
"password",
|
||||
"password_confirmation",
|
||||
];
|
||||
}
|
20
app/Http/Middleware/TrustProxies.php
Normal file
20
app/Http/Middleware/TrustProxies.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
protected $proxies;
|
||||
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
32
app/Models/User.php
Normal file
32
app/Models/User.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasApiTokens;
|
||||
use HasFactory;
|
||||
use Notifiable;
|
||||
|
||||
protected $fillable = [
|
||||
"name",
|
||||
"email",
|
||||
"password",
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
"password",
|
||||
"remember_token",
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
"email_verified_at" => "datetime",
|
||||
];
|
||||
}
|
11
app/Providers/AppServiceProvider.php
Normal file
11
app/Providers/AppServiceProvider.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
}
|
17
app/Providers/AuthServiceProvider.php
Normal file
17
app/Providers/AuthServiceProvider.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected $policies = [];
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
$this->registerPolicies();
|
||||
}
|
||||
}
|
12
app/Providers/EventServiceProvider.php
Normal file
12
app/Providers/EventServiceProvider.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected $listen = [];
|
||||
}
|
35
app/Providers/RouteServiceProvider.php
Normal file
35
app/Providers/RouteServiceProvider.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
public const HOME = "/home";
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function (): void {
|
||||
Route::prefix("api")
|
||||
->middleware("api")
|
||||
->group(base_path("routes/api.php"));
|
||||
|
||||
Route::middleware("web")
|
||||
->group(base_path("routes/web.php"));
|
||||
});
|
||||
}
|
||||
|
||||
protected function configureRateLimiting(): void
|
||||
{
|
||||
RateLimiter::for("api", fn(Request $request) => Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip()));
|
||||
}
|
||||
}
|
20
app/Providers/TelescopeServiceProvider.php
Normal file
20
app/Providers/TelescopeServiceProvider.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Laravel\Telescope\TelescopeApplicationServiceProvider;
|
||||
use Laravel\Telescope\TelescopeServiceProvider as BaseTelescopeServiceProvider;
|
||||
|
||||
class TelescopeServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
if ($this->app->environment("local")) {
|
||||
$this->app->register(BaseTelescopeServiceProvider::class);
|
||||
$this->app->register(TelescopeApplicationServiceProvider::class);
|
||||
}
|
||||
}
|
||||
}
|
53
artisan
Executable file
53
artisan
Executable file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The 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 of our classes manually. It's great to relax.
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Artisan Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When we run the console application, the current CLI command will be
|
||||
| executed in this console and the response sent back to a terminal
|
||||
| or another output device for the developers. Here goes nothing!
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
|
||||
$status = $kernel->handle(
|
||||
$input = new Symfony\Component\Console\Input\ArgvInput,
|
||||
new Symfony\Component\Console\Output\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);
|
24
bootstrap/app.php
Normal file
24
bootstrap/app.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$_ENV["APP_BASE_PATH"] ?? dirname(__DIR__),
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
Toby\Http\Kernel::class,
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Console\Kernel::class,
|
||||
Toby\Console\Kernel::class,
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
Toby\Exceptions\Handler::class,
|
||||
);
|
||||
|
||||
return $app;
|
2
bootstrap/cache/.gitignore
vendored
Normal file
2
bootstrap/cache/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
66
composer.json
Normal file
66
composer.json
Normal file
@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "blumilksoftware/toby",
|
||||
"type": "project",
|
||||
"description": "HR software you love to hate",
|
||||
"keywords": ["toby", "laravel", "hr"],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"ext-pdo": "*",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"laravel/framework": "^8.75",
|
||||
"laravel/sanctum": "^2.11",
|
||||
"laravel/telescope": "^4.6",
|
||||
"laravel/tinker": "^2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"blumilksoftware/codestyle": "^0.9.0",
|
||||
"facade/ignition": "^2.5",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^5.10",
|
||||
"phpunit/phpunit": "^9.5.10"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Toby\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"ecs": "./vendor/bin/ecs check --clear-cache",
|
||||
"ecsf": "./vendor/bin/ecs check --clear-cache --fix",
|
||||
"test": "@php artisan test",
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": [
|
||||
"laravel/telescope"
|
||||
]
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
8012
composer.lock
generated
Normal file
8012
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
46
config/app.php
Normal file
46
config/app.php
Normal file
@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"name" => env("APP_NAME", "Laravel"),
|
||||
"env" => env("APP_ENV", "production"),
|
||||
"debug" => (bool)env("APP_DEBUG", false),
|
||||
"url" => env("APP_URL", "http://localhost"),
|
||||
"asset_url" => env("ASSET_URL"),
|
||||
"timezone" => "Europe/Warsaw",
|
||||
"locale" => "pl",
|
||||
"fallback_locale" => "en",
|
||||
"faker_locale" => "pl_PL",
|
||||
"key" => env("APP_KEY"),
|
||||
"cipher" => "AES-256-CBC",
|
||||
"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,
|
||||
Toby\Providers\AppServiceProvider::class,
|
||||
Toby\Providers\AuthServiceProvider::class,
|
||||
Toby\Providers\EventServiceProvider::class,
|
||||
Toby\Providers\RouteServiceProvider::class,
|
||||
Toby\Providers\TelescopeServiceProvider::class,
|
||||
],
|
||||
];
|
31
config/auth.php
Normal file
31
config/auth.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"defaults" => [
|
||||
"guard" => "web",
|
||||
"passwords" => "users",
|
||||
],
|
||||
"guards" => [
|
||||
"web" => [
|
||||
"driver" => "session",
|
||||
"provider" => "users",
|
||||
],
|
||||
],
|
||||
"providers" => [
|
||||
"users" => [
|
||||
"driver" => "eloquent",
|
||||
"model" => Toby\Models\User::class,
|
||||
],
|
||||
],
|
||||
"passwords" => [
|
||||
"users" => [
|
||||
"provider" => "users",
|
||||
"table" => "password_resets",
|
||||
"expire" => 60,
|
||||
"throttle" => 60,
|
||||
],
|
||||
],
|
||||
"password_timeout" => 10800,
|
||||
];
|
15
config/broadcasting.php
Normal file
15
config/broadcasting.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"default" => env("BROADCAST_DRIVER", "null"),
|
||||
"connections" => [
|
||||
"log" => [
|
||||
"driver" => "log",
|
||||
],
|
||||
"null" => [
|
||||
"driver" => "null",
|
||||
],
|
||||
],
|
||||
];
|
26
config/cache.php
Normal file
26
config/cache.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
"default" => env("CACHE_DRIVER", "file"),
|
||||
"stores" => [
|
||||
"array" => [
|
||||
"driver" => "array",
|
||||
"serialize" => false,
|
||||
],
|
||||
"database" => [
|
||||
"driver" => "database",
|
||||
"table" => "cache",
|
||||
"connection" => null,
|
||||
"lock_connection" => null,
|
||||
],
|
||||
"file" => [
|
||||
"driver" => "file",
|
||||
"path" => storage_path("framework/cache/data"),
|
||||
],
|
||||
],
|
||||
"prefix" => env("CACHE_PREFIX", Str::slug(env("APP_NAME", "laravel"), "_") . "_cache"),
|
||||
];
|
14
config/cors.php
Normal file
14
config/cors.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"paths" => ["api/*", "sanctum/csrf-cookie"],
|
||||
"allowed_methods" => ["*"],
|
||||
"allowed_origins" => ["*"],
|
||||
"allowed_origins_patterns" => [],
|
||||
"allowed_headers" => ["*"],
|
||||
"exposed_headers" => [],
|
||||
"max_age" => 0,
|
||||
"supports_credentials" => false,
|
||||
];
|
34
config/database.php
Normal file
34
config/database.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"default" => env("DB_CONNECTION", "mysql"),
|
||||
"connections" => [
|
||||
"testing" => [
|
||||
"driver" => "sqlite",
|
||||
"database" => ":memory:",
|
||||
"prefix" => "",
|
||||
],
|
||||
"mysql" => [
|
||||
"driver" => "mysql",
|
||||
"url" => env("DATABASE_URL"),
|
||||
"host" => env("DB_HOST", "127.0.0.1"),
|
||||
"port" => env("DB_PORT", "3306"),
|
||||
"database" => env("DB_DATABASE", "forge"),
|
||||
"username" => env("DB_USERNAME", "forge"),
|
||||
"password" => env("DB_PASSWORD", ""),
|
||||
"unix_socket" => env("DB_SOCKET", ""),
|
||||
"charset" => "utf8mb4",
|
||||
"collation" => "utf8mb4_unicode_ci",
|
||||
"prefix" => "",
|
||||
"prefix_indexes" => true,
|
||||
"strict" => true,
|
||||
"engine" => null,
|
||||
"options" => extension_loaded("pdo_mysql") ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env("MYSQL_ATTR_SSL_CA"),
|
||||
]) : [],
|
||||
],
|
||||
],
|
||||
"migrations" => "migrations",
|
||||
];
|
22
config/filesystems.php
Normal file
22
config/filesystems.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"default" => env("FILESYSTEM_DRIVER", "local"),
|
||||
"disks" => [
|
||||
"local" => [
|
||||
"driver" => "local",
|
||||
"root" => storage_path("app"),
|
||||
],
|
||||
"public" => [
|
||||
"driver" => "local",
|
||||
"root" => storage_path("app/public"),
|
||||
"url" => env("APP_URL") . "/storage",
|
||||
"visibility" => "public",
|
||||
],
|
||||
],
|
||||
"links" => [
|
||||
public_path("storage") => storage_path("app/public"),
|
||||
],
|
||||
];
|
15
config/hashing.php
Normal file
15
config/hashing.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"driver" => "bcrypt",
|
||||
"bcrypt" => [
|
||||
"rounds" => env("BCRYPT_ROUNDS", 10),
|
||||
],
|
||||
"argon" => [
|
||||
"memory" => 1024,
|
||||
"threads" => 2,
|
||||
"time" => 2,
|
||||
],
|
||||
];
|
54
config/logging.php
Normal file
54
config/logging.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
|
||||
return [
|
||||
"default" => env("LOG_CHANNEL", "stack"),
|
||||
"deprecations" => env("LOG_DEPRECATIONS_CHANNEL", "null"),
|
||||
|
||||
"channels" => [
|
||||
"stack" => [
|
||||
"driver" => "stack",
|
||||
"channels" => ["single"],
|
||||
"ignore_exceptions" => false,
|
||||
],
|
||||
"single" => [
|
||||
"driver" => "single",
|
||||
"path" => storage_path("logs/laravel.log"),
|
||||
"level" => env("LOG_LEVEL", "debug"),
|
||||
],
|
||||
"daily" => [
|
||||
"driver" => "daily",
|
||||
"path" => storage_path("logs/laravel.log"),
|
||||
"level" => env("LOG_LEVEL", "debug"),
|
||||
"days" => 14,
|
||||
],
|
||||
"stderr" => [
|
||||
"driver" => "monolog",
|
||||
"level" => env("LOG_LEVEL", "debug"),
|
||||
"handler" => StreamHandler::class,
|
||||
"formatter" => env("LOG_STDERR_FORMATTER"),
|
||||
"with" => [
|
||||
"stream" => "php://stderr",
|
||||
],
|
||||
],
|
||||
"syslog" => [
|
||||
"driver" => "syslog",
|
||||
"level" => env("LOG_LEVEL", "debug"),
|
||||
],
|
||||
"errorlog" => [
|
||||
"driver" => "errorlog",
|
||||
"level" => env("LOG_LEVEL", "debug"),
|
||||
],
|
||||
"null" => [
|
||||
"driver" => "monolog",
|
||||
"handler" => NullHandler::class,
|
||||
],
|
||||
"emergency" => [
|
||||
"path" => storage_path("logs/laravel.log"),
|
||||
],
|
||||
],
|
||||
];
|
43
config/mail.php
Normal file
43
config/mail.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"default" => env("MAIL_MAILER", "smtp"),
|
||||
"mailers" => [
|
||||
"smtp" => [
|
||||
"transport" => "smtp",
|
||||
"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,
|
||||
],
|
||||
"log" => [
|
||||
"transport" => "log",
|
||||
"channel" => env("MAIL_LOG_CHANNEL"),
|
||||
],
|
||||
"array" => [
|
||||
"transport" => "array",
|
||||
],
|
||||
"failover" => [
|
||||
"transport" => "failover",
|
||||
"mailers" => [
|
||||
"smtp",
|
||||
"log",
|
||||
],
|
||||
],
|
||||
],
|
||||
"from" => [
|
||||
"address" => env("MAIL_FROM_ADDRESS", "hello@example.com"),
|
||||
"name" => env("MAIL_FROM_NAME", "Example"),
|
||||
],
|
||||
"markdown" => [
|
||||
"theme" => "default",
|
||||
"paths" => [
|
||||
resource_path("views/vendor/mail"),
|
||||
],
|
||||
],
|
||||
];
|
17
config/queue.php
Normal file
17
config/queue.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"default" => env("QUEUE_CONNECTION", "sync"),
|
||||
"connections" => [
|
||||
"sync" => [
|
||||
"driver" => "sync",
|
||||
],
|
||||
],
|
||||
"failed" => [
|
||||
"driver" => env("QUEUE_FAILED_DRIVER", "database-uuids"),
|
||||
"database" => env("DB_CONNECTION", "mysql"),
|
||||
"table" => "failed_jobs",
|
||||
],
|
||||
];
|
17
config/sanctum.php
Normal file
17
config/sanctum.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"stateful" => 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) : "",
|
||||
))),
|
||||
"guard" => ["web"],
|
||||
"expiration" => null,
|
||||
"middleware" => [
|
||||
"verify_csrf_token" => Toby\Http\Middleware\VerifyCsrfToken::class,
|
||||
"encrypt_cookies" => Toby\Http\Middleware\EncryptCookies::class,
|
||||
],
|
||||
];
|
5
config/services.php
Normal file
5
config/services.php
Normal file
@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [];
|
26
config/session.php
Normal file
26
config/session.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
"driver" => env("SESSION_DRIVER", "file"),
|
||||
"lifetime" => env("SESSION_LIFETIME", 120),
|
||||
"expire_on_close" => false,
|
||||
"encrypt" => false,
|
||||
"files" => storage_path("framework/sessions"),
|
||||
"connection" => env("SESSION_CONNECTION"),
|
||||
"table" => "sessions",
|
||||
"store" => env("SESSION_STORE"),
|
||||
"lottery" => [2, 100],
|
||||
"cookie" => env(
|
||||
"SESSION_COOKIE",
|
||||
Str::slug(env("APP_NAME", "laravel"), "_") . "_session",
|
||||
),
|
||||
"path" => "/",
|
||||
"domain" => env("SESSION_DOMAIN"),
|
||||
"secure" => env("SESSION_SECURE_COOKIE"),
|
||||
"http_only" => true,
|
||||
"same_site" => "lax",
|
||||
];
|
82
config/telescope.php
Normal file
82
config/telescope.php
Normal file
@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Laravel\Telescope\Http\Middleware\Authorize;
|
||||
use Laravel\Telescope\Watchers;
|
||||
|
||||
return [
|
||||
"domain" => env("TELESCOPE_DOMAIN"),
|
||||
"path" => env("TELESCOPE_PATH", "telescope"),
|
||||
"driver" => env("TELESCOPE_DRIVER", "database"),
|
||||
"storage" => [
|
||||
"database" => [
|
||||
"connection" => env("DB_CONNECTION", "mysql"),
|
||||
"chunk" => 1000,
|
||||
],
|
||||
],
|
||||
"enabled" => env("TELESCOPE_ENABLED", true),
|
||||
"middleware" => [
|
||||
"web",
|
||||
Authorize::class,
|
||||
],
|
||||
"only_paths" => [],
|
||||
"ignore_paths" => [
|
||||
"nova-api*",
|
||||
],
|
||||
"ignore_commands" => [],
|
||||
"watchers" => [
|
||||
Watchers\BatchWatcher::class => env("TELESCOPE_BATCH_WATCHER", true),
|
||||
Watchers\CacheWatcher::class => env("TELESCOPE_CACHE_WATCHER", true),
|
||||
Watchers\ClientRequestWatcher::class => env("TELESCOPE_CLIENT_REQUEST_WATCHER", true),
|
||||
|
||||
Watchers\CommandWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_COMMAND_WATCHER", true),
|
||||
"ignore" => [],
|
||||
],
|
||||
|
||||
Watchers\DumpWatcher::class => env("TELESCOPE_DUMP_WATCHER", true),
|
||||
|
||||
Watchers\EventWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_EVENT_WATCHER", true),
|
||||
"ignore" => [],
|
||||
],
|
||||
|
||||
Watchers\ExceptionWatcher::class => env("TELESCOPE_EXCEPTION_WATCHER", true),
|
||||
|
||||
Watchers\GateWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_GATE_WATCHER", true),
|
||||
"ignore_abilities" => [],
|
||||
"ignore_packages" => true,
|
||||
],
|
||||
|
||||
Watchers\JobWatcher::class => env("TELESCOPE_JOB_WATCHER", true),
|
||||
Watchers\LogWatcher::class => env("TELESCOPE_LOG_WATCHER", true),
|
||||
Watchers\MailWatcher::class => env("TELESCOPE_MAIL_WATCHER", true),
|
||||
|
||||
Watchers\ModelWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_MODEL_WATCHER", true),
|
||||
"events" => ["eloquent.*"],
|
||||
"hydrations" => true,
|
||||
],
|
||||
|
||||
Watchers\NotificationWatcher::class => env("TELESCOPE_NOTIFICATION_WATCHER", true),
|
||||
|
||||
Watchers\QueryWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_QUERY_WATCHER", true),
|
||||
"ignore_packages" => true,
|
||||
"slow" => 100,
|
||||
],
|
||||
|
||||
Watchers\RedisWatcher::class => env("TELESCOPE_REDIS_WATCHER", true),
|
||||
|
||||
Watchers\RequestWatcher::class => [
|
||||
"enabled" => env("TELESCOPE_REQUEST_WATCHER", true),
|
||||
"size_limit" => env("TELESCOPE_RESPONSE_SIZE_LIMIT", 64),
|
||||
"ignore_status_codes" => [],
|
||||
],
|
||||
|
||||
Watchers\ScheduleWatcher::class => env("TELESCOPE_SCHEDULE_WATCHER", true),
|
||||
Watchers\ViewWatcher::class => env("TELESCOPE_VIEW_WATCHER", true),
|
||||
],
|
||||
];
|
13
config/view.php
Normal file
13
config/view.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"paths" => [
|
||||
resource_path("views"),
|
||||
],
|
||||
"compiled" => env(
|
||||
"VIEW_COMPILED_PATH",
|
||||
realpath(storage_path("framework/views")),
|
||||
),
|
||||
];
|
1
database/.gitignore
vendored
Normal file
1
database/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.sqlite*
|
23
database/factories/UserFactory.php
Normal file
23
database/factories/UserFactory.php
Normal file
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
"name" => $this->faker->name(),
|
||||
"email" => $this->faker->unique()->safeEmail(),
|
||||
"email_verified_at" => now(),
|
||||
"password" => Hash::make("secret123"),
|
||||
"remember_token" => Str::random(10),
|
||||
];
|
||||
}
|
||||
}
|
27
database/migrations/2014_10_12_000000_create_users_table.php
Normal file
27
database/migrations/2014_10_12_000000_create_users_table.php
Normal file
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class() extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create("users", function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string("name");
|
||||
$table->string("email")->unique();
|
||||
$table->timestamp("email_verified_at")->nullable();
|
||||
$table->string("password");
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists("users");
|
||||
}
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class() extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create("password_resets", function (Blueprint $table): void {
|
||||
$table->string("email")->index();
|
||||
$table->string("token");
|
||||
$table->timestamp("created_at")->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists("password_resets");
|
||||
}
|
||||
};
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class() extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create("failed_jobs", function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string("uuid")->unique();
|
||||
$table->text("connection");
|
||||
$table->text("queue");
|
||||
$table->longText("payload");
|
||||
$table->longText("exception");
|
||||
$table->timestamp("failed_at")->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists("failed_jobs");
|
||||
}
|
||||
};
|
@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class() extends Migration {
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create("personal_access_tokens", function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->morphs("tokenable");
|
||||
$table->string("name");
|
||||
$table->string("token", 64)->unique();
|
||||
$table->text("abilities")->nullable();
|
||||
$table->timestamp("last_used_at")->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists("personal_access_tokens");
|
||||
}
|
||||
};
|
16
database/seeders/DatabaseSeeder.php
Normal file
16
database/seeders/DatabaseSeeder.php
Normal file
@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Toby\Models\User;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
User::factory(10)->create();
|
||||
}
|
||||
}
|
79
docker-compose.yml
Normal file
79
docker-compose.yml
Normal file
@ -0,0 +1,79 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
web:
|
||||
image: nginx:1.21-alpine
|
||||
container_name: toby-web
|
||||
working_dir: /application
|
||||
volumes:
|
||||
- ./docker/dev/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
- .:/application
|
||||
networks:
|
||||
- toby-dev
|
||||
ports:
|
||||
- ${EXTERNAL_WEBSERVER_PORT:-80}:80
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- php
|
||||
- database
|
||||
|
||||
php:
|
||||
build:
|
||||
context: docker/dev/php
|
||||
args:
|
||||
INSTALL_XDEBUG: ${DOCKER_INSTALL_XDEBUG:-false}
|
||||
container_name: toby-php
|
||||
working_dir: /application
|
||||
user: ${CURRENT_UID:-1000}
|
||||
volumes:
|
||||
- .:/application
|
||||
- ./docker/dev/php/php.ini:/usr/local/etc/php/conf.d/php.ini
|
||||
networks:
|
||||
- toby-dev
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
restart: unless-stopped
|
||||
|
||||
database:
|
||||
image: mysql:8.0
|
||||
container_name: toby-db
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=${DOCKER_DB_ROOT_PASSWORD}
|
||||
- MYSQL_DATABASE=${DOCKER_DB_DATABASE}
|
||||
- MYSQL_USER=${DOCKER_DB_USERNAME}
|
||||
- MYSQL_PASSWORD=${DOCKER_DB_PASSWORD}
|
||||
ports:
|
||||
- ${DOCKER_DB_EXTERNAL_PORT:-3306}:3306
|
||||
volumes:
|
||||
- toby-mysql-data:/var/lib/mysql
|
||||
networks:
|
||||
- toby-dev
|
||||
restart: unless-stopped
|
||||
|
||||
node:
|
||||
image: node:17.2.0-alpine3.14
|
||||
container_name: toby-node
|
||||
working_dir: /application
|
||||
volumes:
|
||||
- .:/application
|
||||
networks:
|
||||
- toby-dev
|
||||
restart: unless-stopped
|
||||
|
||||
mailhog:
|
||||
image: mailhog/mailhog:v1.0.1
|
||||
container_name: toby-mailhog
|
||||
ports:
|
||||
- ${MAIL_PORT}:1025
|
||||
- ${MAILHOG_DASHBOARD_PORT}:8025
|
||||
networks:
|
||||
- toby-dev
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
toby-dev:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
toby-mysql-data:
|
||||
name: toby-mysql-data
|
24
docker/dev/nginx/nginx.conf
Normal file
24
docker/dev/nginx/nginx.conf
Normal file
@ -0,0 +1,24 @@
|
||||
server {
|
||||
listen 80 default;
|
||||
server_name localhost;
|
||||
|
||||
client_max_body_size 108M;
|
||||
|
||||
access_log /dev/stdout;
|
||||
|
||||
root /application/public;
|
||||
index index.php;
|
||||
|
||||
if (!-e $request_filename) {
|
||||
rewrite ^.*$ /index.php last;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass toby-php:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param PHP_VALUE "error_log=/dev/stdout";
|
||||
fastcgi_buffers 16 16k;
|
||||
fastcgi_buffer_size 32k;
|
||||
include fastcgi_params;
|
||||
}
|
||||
}
|
20
docker/dev/php/Dockerfile
Normal file
20
docker/dev/php/Dockerfile
Normal file
@ -0,0 +1,20 @@
|
||||
FROM ghcr.io/blumilksoftware/php:8.1
|
||||
|
||||
ARG XDEBUG_VERSION=3.1.2
|
||||
ARG INSTALL_XDEBUG=false
|
||||
|
||||
RUN if [ ${INSTALL_XDEBUG} = true ]; then \
|
||||
apk --no-cache add $PHPIZE_DEPS \
|
||||
&& pecl install xdebug-${XDEBUG_VERSION} \
|
||||
&& docker-php-ext-enable xdebug \
|
||||
;fi
|
||||
|
||||
RUN apk --no-cache add \
|
||||
zip \
|
||||
libzip-dev \
|
||||
libpng-dev \
|
||||
&& docker-php-ext-install \
|
||||
zip \
|
||||
gd \
|
||||
&& docker-php-ext-configure \
|
||||
zip
|
9
docker/dev/php/php.ini
Normal file
9
docker/dev/php/php.ini
Normal file
@ -0,0 +1,9 @@
|
||||
[PHP]
|
||||
memory_limit = 1G
|
||||
|
||||
[xdebug]
|
||||
xdebug.client_host=host.docker.internal
|
||||
xdebug.client_port=9003
|
||||
xdebug.mode=debug
|
||||
xdebug.start_with_request=yes
|
||||
xdebug.log_level=0
|
13
ecs.php
Normal file
13
ecs.php
Normal file
@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Blumilk\Codestyle\Config;
|
||||
use Blumilk\Codestyle\Configuration\Defaults\LaravelPaths;
|
||||
|
||||
$paths = (new LaravelPaths())->add("public", "bootstrap/app.php", "ecs.php");
|
||||
$config = new Config(
|
||||
paths: $paths,
|
||||
);
|
||||
|
||||
return $config->config();
|
15966
package-lock.json
generated
Normal file
15966
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"private": true,
|
||||
"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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.21",
|
||||
"laravel-mix": "^6.0.6",
|
||||
"lodash": "^4.17.19",
|
||||
"postcss": "^8.1.14"
|
||||
}
|
||||
}
|
32
phpunit.xml
Normal file
32
phpunit.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory>./tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory>./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./app</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<php>
|
||||
<server name="APP_ENV" value="testing"/>
|
||||
<server name="APP_KEY" value="base64:SKEJSy9oF9chQBCMbxqgj5zhtAvug9kwZ+cDiP1Y8A8="/>
|
||||
<server name="BCRYPT_ROUNDS" value="4"/>
|
||||
<server name="CACHE_DRIVER" value="array"/>
|
||||
<server name="DB_CONNECTION" value="sqlite"/>
|
||||
<server name="DB_DATABASE" value=":memory:"/>
|
||||
<server name="MAIL_MAILER" value="array"/>
|
||||
<server name="QUEUE_CONNECTION" value="sync"/>
|
||||
<server name="SESSION_DRIVER" value="array"/>
|
||||
<server name="TELESCOPE_ENABLED" value="false"/>
|
||||
</php>
|
||||
</phpunit>
|
21
public/.htaccess
Normal file
21
public/.htaccess
Normal file
@ -0,0 +1,21 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
<IfModule mod_negotiation.c>
|
||||
Options -MultiViews -Indexes
|
||||
</IfModule>
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
# Handle Authorization Header
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
||||
# Redirect Trailing Slashes If Not A Folder...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [L,R=301]
|
||||
|
||||
# Send Requests To Front Controller...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
0
public/favicon.ico
Normal file
0
public/favicon.ico
Normal file
24
public/index.php
Normal file
24
public/index.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Contracts\Http\Kernel;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
define("LARAVEL_START", microtime(true));
|
||||
|
||||
if (file_exists(__DIR__ . "/../storage/framework/maintenance.php")) {
|
||||
require __DIR__ . "/../storage/framework/maintenance.php";
|
||||
}
|
||||
|
||||
require __DIR__ . "/../vendor/autoload.php";
|
||||
|
||||
$app = require_once __DIR__ . "/../bootstrap/app.php";
|
||||
|
||||
$kernel = $app->make(Kernel::class);
|
||||
|
||||
$response = $kernel->handle(
|
||||
$request = Request::capture(),
|
||||
)->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
2
public/robots.txt
Normal file
2
public/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow:
|
7
public/vendor/telescope/app-dark.css
vendored
Normal file
7
public/vendor/telescope/app-dark.css
vendored
Normal file
File diff suppressed because one or more lines are too long
7
public/vendor/telescope/app.css
vendored
Normal file
7
public/vendor/telescope/app.css
vendored
Normal file
File diff suppressed because one or more lines are too long
2
public/vendor/telescope/app.js
vendored
Normal file
2
public/vendor/telescope/app.js
vendored
Normal file
File diff suppressed because one or more lines are too long
BIN
public/vendor/telescope/favicon.ico
vendored
Normal file
BIN
public/vendor/telescope/favicon.ico
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
5
public/vendor/telescope/mix-manifest.json
vendored
Normal file
5
public/vendor/telescope/mix-manifest.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"/app.js": "/app.js?id=d3ff915bff3de87b87cc",
|
||||
"/app-dark.css": "/app-dark.css?id=3ae28ef5f7b987d68dc6",
|
||||
"/app.css": "/app.css?id=7c970f699ed9cf60d80b"
|
||||
}
|
0
resources/css/app.css
Normal file
0
resources/css/app.css
Normal file
1
resources/js/app.js
Normal file
1
resources/js/app.js
Normal file
@ -0,0 +1 @@
|
||||
require('./bootstrap');
|
28
resources/js/bootstrap.js
vendored
Normal file
28
resources/js/bootstrap.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
window._ = require('lodash');
|
||||
|
||||
/**
|
||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||
* to our Laravel back-end. This library automatically handles sending the
|
||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||
*/
|
||||
|
||||
window.axios = require('axios');
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Echo exposes an expressive API for subscribing to channels and listening
|
||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo';
|
||||
|
||||
// window.Pusher = require('pusher-js');
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||
// forceTLS: true
|
||||
// });
|
9
resources/lang/en/auth.php
Normal file
9
resources/lang/en/auth.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"failed" => "These credentials do not match our records.",
|
||||
"password" => "The provided password is incorrect.",
|
||||
"throttle" => "Too many login attempts. Please try again in :seconds seconds.",
|
||||
];
|
8
resources/lang/en/pagination.php
Normal file
8
resources/lang/en/pagination.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"previous" => "« Previous",
|
||||
"next" => "Next »",
|
||||
];
|
11
resources/lang/en/passwords.php
Normal file
11
resources/lang/en/passwords.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"reset" => "Your password has been reset!",
|
||||
"sent" => "We have emailed your password reset link!",
|
||||
"throttled" => "Please wait before retrying.",
|
||||
"token" => "This password reset token is invalid.",
|
||||
"user" => "We can't find a user with that email address.",
|
||||
];
|
122
resources/lang/en/validation.php
Normal file
122
resources/lang/en/validation.php
Normal file
@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
"accepted" => "The :attribute must be accepted.",
|
||||
"accepted_if" => "The :attribute must be accepted when :other is :value.",
|
||||
"active_url" => "The :attribute is not a valid URL.",
|
||||
"after" => "The :attribute must be a date after :date.",
|
||||
"after_or_equal" => "The :attribute must be a date after or equal to :date.",
|
||||
"alpha" => "The :attribute must only contain letters.",
|
||||
"alpha_dash" => "The :attribute must only contain letters, numbers, dashes and underscores.",
|
||||
"alpha_num" => "The :attribute must only contain letters and numbers.",
|
||||
"array" => "The :attribute must be an array.",
|
||||
"before" => "The :attribute must be a date before :date.",
|
||||
"before_or_equal" => "The :attribute must be a date before or equal to :date.",
|
||||
"between" => [
|
||||
"numeric" => "The :attribute must be between :min and :max.",
|
||||
"file" => "The :attribute must be between :min and :max kilobytes.",
|
||||
"string" => "The :attribute must be between :min and :max characters.",
|
||||
"array" => "The :attribute must have between :min and :max items.",
|
||||
],
|
||||
"boolean" => "The :attribute field must be true or false.",
|
||||
"confirmed" => "The :attribute confirmation does not match.",
|
||||
"current_password" => "The password is incorrect.",
|
||||
"date" => "The :attribute is not a valid date.",
|
||||
"date_equals" => "The :attribute must be a date equal to :date.",
|
||||
"date_format" => "The :attribute does not match the format :format.",
|
||||
"declined" => "The :attribute must be declined.",
|
||||
"declined_if" => "The :attribute must be declined when :other is :value.",
|
||||
"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.",
|
||||
"ends_with" => "The :attribute must end with one of the following: :values.",
|
||||
"enum" => "The selected :attribute is invalid.",
|
||||
"exists" => "The selected :attribute is invalid.",
|
||||
"file" => "The :attribute must be a file.",
|
||||
"filled" => "The :attribute field must have a value.",
|
||||
"gt" => [
|
||||
"numeric" => "The :attribute must be greater than :value.",
|
||||
"file" => "The :attribute must be greater than :value kilobytes.",
|
||||
"string" => "The :attribute must be greater than :value characters.",
|
||||
"array" => "The :attribute must have more than :value items.",
|
||||
],
|
||||
"gte" => [
|
||||
"numeric" => "The :attribute must be greater than or equal to :value.",
|
||||
"file" => "The :attribute must be greater than or equal to :value kilobytes.",
|
||||
"string" => "The :attribute must be greater than or equal to :value characters.",
|
||||
"array" => "The :attribute must have :value items or more.",
|
||||
],
|
||||
"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.",
|
||||
"ipv4" => "The :attribute must be a valid IPv4 address.",
|
||||
"ipv6" => "The :attribute must be a valid IPv6 address.",
|
||||
"mac_address" => "The :attribute must be a valid MAC address.",
|
||||
"json" => "The :attribute must be a valid JSON string.",
|
||||
"lt" => [
|
||||
"numeric" => "The :attribute must be less than :value.",
|
||||
"file" => "The :attribute must be less than :value kilobytes.",
|
||||
"string" => "The :attribute must be less than :value characters.",
|
||||
"array" => "The :attribute must have less than :value items.",
|
||||
],
|
||||
"lte" => [
|
||||
"numeric" => "The :attribute must be less than or equal to :value.",
|
||||
"file" => "The :attribute must be less than or equal to :value kilobytes.",
|
||||
"string" => "The :attribute must be less than or equal to :value characters.",
|
||||
"array" => "The :attribute must not have more than :value items.",
|
||||
],
|
||||
"max" => [
|
||||
"numeric" => "The :attribute must not be greater than :max.",
|
||||
"file" => "The :attribute must not be greater than :max kilobytes.",
|
||||
"string" => "The :attribute must not be greater than :max characters.",
|
||||
"array" => "The :attribute must 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.",
|
||||
"string" => "The :attribute must be at least :min characters.",
|
||||
"array" => "The :attribute must have at least :min items.",
|
||||
],
|
||||
"multiple_of" => "The :attribute must be a multiple of :value.",
|
||||
"not_in" => "The selected :attribute is invalid.",
|
||||
"not_regex" => "The :attribute format is invalid.",
|
||||
"numeric" => "The :attribute must be a number.",
|
||||
"password" => "The password is incorrect.",
|
||||
"present" => "The :attribute field must be present.",
|
||||
"prohibited" => "The :attribute field is prohibited.",
|
||||
"prohibited_if" => "The :attribute field is prohibited when :other is :value.",
|
||||
"prohibited_unless" => "The :attribute field is prohibited unless :other is in :values.",
|
||||
"prohibits" => "The :attribute field prohibits :other from being 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 are present.",
|
||||
"required_without" => "The :attribute field is required when :values is not present.",
|
||||
"required_without_all" => "The :attribute field is required when none of :values are present.",
|
||||
"same" => "The :attribute and :other must match.",
|
||||
"size" => [
|
||||
"numeric" => "The :attribute must be :size.",
|
||||
"file" => "The :attribute must be :size kilobytes.",
|
||||
"string" => "The :attribute must be :size characters.",
|
||||
"array" => "The :attribute must contain :size items.",
|
||||
],
|
||||
"starts_with" => "The :attribute must start with one of the following: :values.",
|
||||
"string" => "The :attribute must be a string.",
|
||||
"timezone" => "The :attribute must be a valid timezone.",
|
||||
"unique" => "The :attribute has already been taken.",
|
||||
"uploaded" => "The :attribute failed to upload.",
|
||||
"url" => "The :attribute must be a valid URL.",
|
||||
"uuid" => "The :attribute must be a valid UUID.",
|
||||
"attributes" => [],
|
||||
];
|
112
resources/views/welcome.blade.php
Normal file
112
resources/views/welcome.blade.php
Normal file
@ -0,0 +1,112 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Laravel</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}a{background-color:transparent}[hidden]{display:none}html{font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}*,:after,:before{box-sizing:border-box;border:0 solid #e2e8f0}a{color:inherit;text-decoration:inherit}svg,video{display:block;vertical-align:middle}video{max-width:100%;height:auto}.bg-white{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity))}.bg-gray-100{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.border-gray-200{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity))}.border-t{border-top-width:1px}.flex{display:flex}.grid{display:grid}.hidden{display:none}.items-center{align-items:center}.justify-center{justify-content:center}.font-semibold{font-weight:600}.h-5{height:1.25rem}.h-8{height:2rem}.h-16{height:4rem}.text-sm{font-size:.875rem}.text-lg{font-size:1.125rem}.leading-7{line-height:1.75rem}.mx-auto{margin-left:auto;margin-right:auto}.ml-1{margin-left:.25rem}.mt-2{margin-top:.5rem}.mr-2{margin-right:.5rem}.ml-2{margin-left:.5rem}.mt-4{margin-top:1rem}.ml-4{margin-left:1rem}.mt-8{margin-top:2rem}.ml-12{margin-left:3rem}.-mt-px{margin-top:-1px}.max-w-6xl{max-width:72rem}.min-h-screen{min-height:100vh}.overflow-hidden{overflow:hidden}.p-6{padding:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.pt-8{padding-top:2rem}.fixed{position:fixed}.relative{position:relative}.top-0{top:0}.right-0{right:0}.shadow{box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}.text-center{text-align:center}.text-gray-200{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.text-gray-300{--text-opacity:1;color:#e2e8f0;color:rgba(226,232,240,var(--text-opacity))}.text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.text-gray-500{--text-opacity:1;color:#a0aec0;color:rgba(160,174,192,var(--text-opacity))}.text-gray-600{--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity))}.text-gray-700{--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity))}.text-gray-900{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.underline{text-decoration:underline}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.w-5{width:1.25rem}.w-8{width:2rem}.w-auto{width:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}@media (min-width:640px){.sm\:rounded-lg{border-radius:.5rem}.sm\:block{display:block}.sm\:items-center{align-items:center}.sm\:justify-start{justify-content:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:h-20{height:5rem}.sm\:ml-0{margin-left:0}.sm\:px-6{padding-left:1.5rem;padding-right:1.5rem}.sm\:pt-0{padding-top:0}.sm\:text-left{text-align:left}.sm\:text-right{text-align:right}}@media (min-width:768px){.md\:border-t-0{border-top-width:0}.md\:border-l{border-left-width:1px}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:1024px){.lg\:px-8{padding-left:2rem;padding-right:2rem}}@media (prefers-color-scheme:dark){.dark\:bg-gray-800{--bg-opacity:1;background-color:#2d3748;background-color:rgba(45,55,72,var(--bg-opacity))}.dark\:bg-gray-900{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity))}.dark\:border-gray-700{--border-opacity:1;border-color:#4a5568;border-color:rgba(74,85,104,var(--border-opacity))}.dark\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}.dark\:text-gray-400{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity))}.dark\:text-gray-500{--tw-text-opacity:1;color:#6b7280;color:rgba(107,114,128,var(--tw-text-opacity))}}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="antialiased">
|
||||
<div class="relative flex items-top justify-center min-h-screen bg-gray-100 dark:bg-gray-900 sm:items-center py-4 sm:pt-0">
|
||||
<div class="max-w-6xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="flex justify-center pt-8 sm:justify-start sm:pt-0">
|
||||
<svg viewBox="0 0 651 192" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-16 w-auto text-gray-700 sm:h-20">
|
||||
<g clip-path="url(#clip0)" fill="#EF3B2D">
|
||||
<path d="M248.032 44.676h-16.466v100.23h47.394v-14.748h-30.928V44.676zM337.091 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.431 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162-.001 2.863-.479 5.584-1.432 8.161zM463.954 87.202c-2.101-3.341-5.083-5.965-8.949-7.875-3.865-1.909-7.756-2.864-11.669-2.864-5.062 0-9.69.931-13.89 2.792-4.201 1.861-7.804 4.417-10.811 7.661-3.007 3.246-5.347 6.993-7.016 11.239-1.672 4.249-2.506 8.713-2.506 13.389 0 4.774.834 9.26 2.506 13.459 1.669 4.202 4.009 7.925 7.016 11.169 3.007 3.246 6.609 5.799 10.811 7.66 4.199 1.861 8.828 2.792 13.89 2.792 3.913 0 7.804-.955 11.669-2.863 3.866-1.908 6.849-4.533 8.949-7.875v9.021h15.607V78.182h-15.607v9.02zm-1.432 32.503c-.955 2.578-2.291 4.821-4.009 6.73-1.719 1.91-3.795 3.437-6.229 4.582-2.435 1.146-5.133 1.718-8.091 1.718-2.96 0-5.633-.572-8.019-1.718-2.387-1.146-4.438-2.672-6.156-4.582-1.719-1.909-3.032-4.152-3.938-6.73-.909-2.577-1.36-5.298-1.36-8.161 0-2.864.451-5.585 1.36-8.162.905-2.577 2.219-4.819 3.938-6.729 1.718-1.908 3.77-3.437 6.156-4.582 2.386-1.146 5.059-1.718 8.019-1.718 2.958 0 5.656.572 8.091 1.718 2.434 1.146 4.51 2.674 6.229 4.582 1.718 1.91 3.054 4.152 4.009 6.729.953 2.577 1.432 5.298 1.432 8.162 0 2.863-.479 5.584-1.432 8.161zM650.772 44.676h-15.606v100.23h15.606V44.676zM365.013 144.906h15.607V93.538h26.776V78.182h-42.383v66.724zM542.133 78.182l-19.616 51.096-19.616-51.096h-15.808l25.617 66.724h19.614l25.617-66.724h-15.808zM591.98 76.466c-19.112 0-34.239 15.706-34.239 35.079 0 21.416 14.641 35.079 36.239 35.079 12.088 0 19.806-4.622 29.234-14.688l-10.544-8.158c-.006.008-7.958 10.449-19.832 10.449-13.802 0-19.612-11.127-19.612-16.884h51.777c2.72-22.043-11.772-40.877-33.023-40.877zm-18.713 29.28c.12-1.284 1.917-16.884 18.589-16.884 16.671 0 18.697 15.598 18.813 16.884h-37.402zM184.068 43.892c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002-35.648-20.524a2.971 2.971 0 00-2.964 0l-35.647 20.522-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v38.979l-29.706 17.103V24.493a3 3 0 00-.103-.776c-.024-.088-.073-.165-.104-.25-.058-.157-.108-.316-.191-.46-.056-.097-.137-.176-.203-.265-.087-.117-.161-.242-.265-.345-.085-.086-.194-.148-.29-.223-.109-.085-.206-.182-.327-.252l-.002-.001-.002-.002L40.098 1.396a2.971 2.971 0 00-2.964 0L1.487 21.919l-.002.002-.002.001c-.121.07-.219.167-.327.252-.096.075-.205.138-.29.223-.103.103-.178.228-.265.345-.066.089-.147.169-.203.265-.083.144-.133.304-.191.46-.031.085-.08.162-.104.25-.067.249-.103.51-.103.776v122.09c0 1.063.568 2.044 1.489 2.575l71.293 41.045c.156.089.324.143.49.202.078.028.15.074.23.095a2.98 2.98 0 001.524 0c.069-.018.132-.059.2-.083.176-.061.354-.119.519-.214l71.293-41.045a2.971 2.971 0 001.489-2.575v-38.979l34.158-19.666a2.971 2.971 0 001.489-2.575V44.666a3.075 3.075 0 00-.106-.774zM74.255 143.167l-29.648-16.779 31.136-17.926.001-.001 34.164-19.669 29.674 17.084-21.772 12.428-43.555 24.863zm68.329-76.259v33.841l-12.475-7.182-17.231-9.92V49.806l12.475 7.182 17.231 9.92zm2.97-39.335l29.693 17.095-29.693 17.095-29.693-17.095 29.693-17.095zM54.06 114.089l-12.475 7.182V46.733l17.231-9.92 12.475-7.182v74.537l-17.231 9.921zM38.614 7.398l29.693 17.095-29.693 17.095L8.921 24.493 38.614 7.398zM5.938 29.632l12.475 7.182 17.231 9.92v79.676l.001.005-.001.006c0 .114.032.221.045.333.017.146.021.294.059.434l.002.007c.032.117.094.222.14.334.051.124.088.255.156.371a.036.036 0 00.004.009c.061.105.149.191.222.288.081.105.149.22.244.314l.008.01c.084.083.19.142.284.215.106.083.202.178.32.247l.013.005.011.008 34.139 19.321v34.175L5.939 144.867V29.632h-.001zm136.646 115.235l-65.352 37.625V148.31l48.399-27.628 16.953-9.677v33.862zm35.646-61.22l-29.706 17.102V66.908l17.231-9.92 12.475-7.182v33.841z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 bg-white dark:bg-gray-800 overflow-hidden shadow sm:rounded-lg">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2">
|
||||
<div class="p-6">
|
||||
<div class="flex items-center">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"></path></svg>
|
||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel.com/docs" class="underline text-gray-900 dark:text-white">Documentation</a></div>
|
||||
</div>
|
||||
|
||||
<div class="ml-12">
|
||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
||||
Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-t-0 md:border-l">
|
||||
<div class="flex items-center">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z"></path><path d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
|
||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laracasts.com" class="underline text-gray-900 dark:text-white">Laracasts</a></div>
|
||||
</div>
|
||||
|
||||
<div class="ml-12">
|
||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
||||
Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700">
|
||||
<div class="flex items-center">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z"></path></svg>
|
||||
<div class="ml-4 text-lg leading-7 font-semibold"><a href="https://laravel-news.com/" class="underline text-gray-900 dark:text-white">Laravel News</a></div>
|
||||
</div>
|
||||
|
||||
<div class="ml-12">
|
||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
||||
Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-6 border-t border-gray-200 dark:border-gray-700 md:border-l">
|
||||
<div class="flex items-center">
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="w-8 h-8 text-gray-500"><path d="M3.055 11H5a2 2 0 012 2v1a2 2 0 002 2 2 2 0 012 2v2.945M8 3.935V5.5A2.5 2.5 0 0010.5 8h.5a2 2 0 012 2 2 2 0 104 0 2 2 0 012-2h1.064M15 20.488V18a2 2 0 012-2h3.064M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
|
||||
<div class="ml-4 text-lg leading-7 font-semibold text-gray-900 dark:text-white">Vibrant Ecosystem</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-12">
|
||||
<div class="mt-2 text-gray-600 dark:text-gray-400 text-sm">
|
||||
Laravel's robust library of first-party tools and libraries, such as <a href="https://forge.laravel.com" class="underline">Forge</a>, <a href="https://vapor.laravel.com" class="underline">Vapor</a>, <a href="https://nova.laravel.com" class="underline">Nova</a>, and <a href="https://envoyer.io" class="underline">Envoyer</a> help you take your projects to the next level. Pair them with powerful open source libraries like <a href="https://laravel.com/docs/billing" class="underline">Cashier</a>, <a href="https://laravel.com/docs/dusk" class="underline">Dusk</a>, <a href="https://laravel.com/docs/broadcasting" class="underline">Echo</a>, <a href="https://laravel.com/docs/horizon" class="underline">Horizon</a>, <a href="https://laravel.com/docs/sanctum" class="underline">Sanctum</a>, <a href="https://laravel.com/docs/telescope" class="underline">Telescope</a>, and more.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-center mt-4 sm:items-center sm:justify-between">
|
||||
<div class="text-center text-sm text-gray-500 sm:text-left">
|
||||
<div class="flex items-center">
|
||||
<svg fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" stroke="currentColor" class="-mt-px w-5 h-5 text-gray-400">
|
||||
<path d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"></path>
|
||||
</svg>
|
||||
|
||||
<a href="https://laravel.bigcartel.com" class="ml-1 underline">
|
||||
Shop
|
||||
</a>
|
||||
|
||||
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" viewBox="0 0 24 24" class="ml-4 -mt-px w-5 h-5 text-gray-400">
|
||||
<path d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
|
||||
</svg>
|
||||
|
||||
<a href="https://github.com/sponsors/taylorotwell" class="ml-1 underline">
|
||||
Sponsor
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
|
||||
Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
8
routes/api.php
Normal file
8
routes/api.php
Normal file
@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware("auth:sanctum")->get("/user", fn(Request $request) => $request->user());
|
7
routes/web.php
Normal file
7
routes/web.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get("/", fn() => view("welcome"));
|
21
server.php
Normal file
21
server.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* 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 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';
|
3
storage/app/.gitignore
vendored
Normal file
3
storage/app/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!public/
|
||||
!.gitignore
|
2
storage/app/public/.gitignore
vendored
Normal file
2
storage/app/public/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
9
storage/framework/.gitignore
vendored
Normal file
9
storage/framework/.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
compiled.php
|
||||
config.php
|
||||
down
|
||||
events.scanned.php
|
||||
maintenance.php
|
||||
routes.php
|
||||
routes.scanned.php
|
||||
schedule-*
|
||||
services.json
|
3
storage/framework/cache/.gitignore
vendored
Normal file
3
storage/framework/cache/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*
|
||||
!data/
|
||||
!.gitignore
|
2
storage/framework/cache/data/.gitignore
vendored
Normal file
2
storage/framework/cache/data/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
storage/framework/sessions/.gitignore
vendored
Normal file
2
storage/framework/sessions/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
storage/framework/testing/.gitignore
vendored
Normal file
2
storage/framework/testing/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
storage/framework/views/.gitignore
vendored
Normal file
2
storage/framework/views/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
2
storage/logs/.gitignore
vendored
Normal file
2
storage/logs/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
20
tests/CreatesApplication.php
Normal file
20
tests/CreatesApplication.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Foundation\Application;
|
||||
|
||||
trait CreatesApplication
|
||||
{
|
||||
public function createApplication(): Application
|
||||
{
|
||||
$app = require __DIR__ . "/../bootstrap/app.php";
|
||||
|
||||
$app->make(Kernel::class)->bootstrap();
|
||||
|
||||
return $app;
|
||||
}
|
||||
}
|
17
tests/Feature/ExampleTest.php
Normal file
17
tests/Feature/ExampleTest.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
public function testExample(): void
|
||||
{
|
||||
$response = $this->get("/");
|
||||
|
||||
$response->assertStatus(200);
|
||||
}
|
||||
}
|
12
tests/TestCase.php
Normal file
12
tests/TestCase.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests;
|
||||
|
||||
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
|
||||
|
||||
abstract class TestCase extends BaseTestCase
|
||||
{
|
||||
use CreatesApplication;
|
||||
}
|
15
tests/Unit/ExampleTest.php
Normal file
15
tests/Unit/ExampleTest.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Tests\Unit;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
public function testExample(): void
|
||||
{
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
}
|
17
webpack.mix.js
Normal file
17
webpack.mix.js
Normal file
@ -0,0 +1,17 @@
|
||||
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', [
|
||||
//
|
||||
]);
|
Loading…
x
Reference in New Issue
Block a user