empty laravel app
This commit is contained in:
133
app/Console/Commands/GenerateSchemaCommand.php
Normal file
133
app/Console/Commands/GenerateSchemaCommand.php
Normal file
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\File;
|
||||
|
||||
class GenerateSchemaCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'app:schema-generate';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Generate a schema.md file documenting all database tables';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
$this->info('Generating database schema documentation...');
|
||||
|
||||
// Get all tables
|
||||
$tables = DB::select('SHOW TABLES');
|
||||
$tableKey = 'Tables_in_' . DB::getDatabaseName();
|
||||
|
||||
$tableNames = [];
|
||||
foreach ($tables as $table) {
|
||||
$tableNames[] = $table->$tableKey;
|
||||
}
|
||||
|
||||
// Sort tables alphabetically
|
||||
sort($tableNames);
|
||||
|
||||
// Build markdown content
|
||||
$markdown = "# Database Schema Documentation\n\n";
|
||||
$markdown .= '> Generated: ' . date('Y-m-d H:i:s') . "\n";
|
||||
$markdown .= '> Database: ' . DB::getDatabaseName() . "\n";
|
||||
$markdown .= '> Total Tables: ' . count($tableNames) . "\n\n";
|
||||
$markdown .= "## Table of Contents\n\n";
|
||||
|
||||
// Add table of contents
|
||||
foreach ($tableNames as $tableName) {
|
||||
$markdown .= "- [{$tableName}](#{$tableName})\n";
|
||||
}
|
||||
$markdown .= "\n---\n\n";
|
||||
|
||||
// Process each table
|
||||
foreach ($tableNames as $tableName) {
|
||||
$this->line("Processing table: {$tableName}");
|
||||
|
||||
$markdown .= "## {$tableName}\n\n";
|
||||
|
||||
// Get columns
|
||||
$columns = DB::select("SHOW COLUMNS FROM `{$tableName}`");
|
||||
|
||||
// Get foreign keys
|
||||
$foreignKeys = DB::select('
|
||||
SELECT
|
||||
CONSTRAINT_NAME,
|
||||
COLUMN_NAME,
|
||||
REFERENCED_TABLE_NAME,
|
||||
REFERENCED_COLUMN_NAME
|
||||
FROM
|
||||
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
WHERE
|
||||
TABLE_NAME = ?
|
||||
AND TABLE_SCHEMA = DATABASE()
|
||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
', [$tableName]);
|
||||
|
||||
// Build FK lookup array
|
||||
$fkLookup = [];
|
||||
foreach ($foreignKeys as $fk) {
|
||||
$fkLookup[$fk->COLUMN_NAME] = [
|
||||
'table' => $fk->REFERENCED_TABLE_NAME,
|
||||
'column' => $fk->REFERENCED_COLUMN_NAME,
|
||||
'constraint' => $fk->CONSTRAINT_NAME,
|
||||
];
|
||||
}
|
||||
|
||||
// Build columns table
|
||||
$markdown .= "| Field | Type | Null | Key | Default | Extra | Foreign Key |\n";
|
||||
$markdown .= "|-------|------|------|-----|---------|-------|-------------|\n";
|
||||
|
||||
foreach ($columns as $column) {
|
||||
$fkInfo = '';
|
||||
if (isset($fkLookup[$column->Field])) {
|
||||
$fk = $fkLookup[$column->Field];
|
||||
$fkInfo = "→ {$fk['table']}.{$fk['column']}";
|
||||
}
|
||||
|
||||
$markdown .= "| {$column->Field} | {$column->Type} | {$column->Null} | {$column->Key} | ";
|
||||
$markdown .= ($column->Default === null ? 'NULL' : $column->Default) . ' | ';
|
||||
$markdown .= "{$column->Extra} | {$fkInfo} |\n";
|
||||
}
|
||||
|
||||
// Add foreign key details if any
|
||||
if (! empty($foreignKeys)) {
|
||||
$markdown .= "\n### Foreign Key Constraints\n\n";
|
||||
foreach ($foreignKeys as $fk) {
|
||||
$markdown .= "- **{$fk->CONSTRAINT_NAME}**: `{$fk->COLUMN_NAME}` → `{$fk->REFERENCED_TABLE_NAME}.{$fk->REFERENCED_COLUMN_NAME}`\n";
|
||||
}
|
||||
}
|
||||
|
||||
$markdown .= "\n---\n\n";
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
$directory = base_path('database');
|
||||
if (! File::exists($directory)) {
|
||||
File::makeDirectory($directory, 0755, true);
|
||||
}
|
||||
|
||||
// Write to file
|
||||
$filePath = $directory . '/schema.md';
|
||||
File::put($filePath, $markdown);
|
||||
|
||||
$this->info('✅ Schema documentation generated successfully!');
|
||||
$this->line("📄 File saved to: {$filePath}");
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
}
|
||||
8
app/Http/Controllers/Controller.php
Normal file
8
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
49
app/Models/User.php
Normal file
49
app/Models/User.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Fortify\TwoFactorAuthenticatable;
|
||||
|
||||
class User extends Authenticatable implements MustVerifyEmail
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable, TwoFactorAuthenticatable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
}
|
||||
21
app/Nova/Dashboards/Main.php
Normal file
21
app/Nova/Dashboards/Main.php
Normal file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Nova\Dashboards;
|
||||
|
||||
use Laravel\Nova\Cards\Help;
|
||||
use Laravel\Nova\Dashboards\Main as Dashboard;
|
||||
|
||||
class Main extends Dashboard
|
||||
{
|
||||
/**
|
||||
* Get the cards for the dashboard.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Card>
|
||||
*/
|
||||
public function cards(): array
|
||||
{
|
||||
return [
|
||||
new Help,
|
||||
];
|
||||
}
|
||||
}
|
||||
45
app/Nova/Resource.php
Normal file
45
app/Nova/Resource.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
use Laravel\Nova\Resource as NovaResource;
|
||||
use Laravel\Scout\Builder as ScoutBuilder;
|
||||
|
||||
abstract class Resource extends NovaResource
|
||||
{
|
||||
/**
|
||||
* Build an "index" query for the given resource.
|
||||
*/
|
||||
public static function indexQuery(NovaRequest $request, Builder $query): Builder
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Scout search query for the given resource.
|
||||
*/
|
||||
public static function scoutQuery(NovaRequest $request, ScoutBuilder $query): ScoutBuilder
|
||||
{
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a "detail" query for the given resource.
|
||||
*/
|
||||
public static function detailQuery(NovaRequest $request, Builder $query): Builder
|
||||
{
|
||||
return parent::detailQuery($request, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a "relatable" query for the given resource.
|
||||
*
|
||||
* This query determines which instances of the model may be attached to other resources.
|
||||
*/
|
||||
public static function relatableQuery(NovaRequest $request, Builder $query): Builder
|
||||
{
|
||||
return parent::relatableQuery($request, $query);
|
||||
}
|
||||
}
|
||||
105
app/Nova/User.php
Normal file
105
app/Nova/User.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Nova;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Laravel\Nova\Auth\PasswordValidationRules;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Password;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
|
||||
class User extends Resource
|
||||
{
|
||||
use PasswordValidationRules;
|
||||
|
||||
/**
|
||||
* The model the resource corresponds to.
|
||||
*
|
||||
* @var class-string<\App\Models\User>
|
||||
*/
|
||||
public static $model = \App\Models\User::class;
|
||||
|
||||
/**
|
||||
* The single value that should be used to represent the resource when being displayed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $title = 'name';
|
||||
|
||||
/**
|
||||
* The columns that should be searched.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $search = [
|
||||
'id', 'name', 'email',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Fields\Field|\Laravel\Nova\Panel|\Laravel\Nova\ResourceTool|\Illuminate\Http\Resources\MergeValue>
|
||||
*/
|
||||
public function fields(NovaRequest $request): array
|
||||
{
|
||||
return [
|
||||
ID::make()->sortable(),
|
||||
|
||||
Text::make('Name')
|
||||
->sortable()
|
||||
->rules('required', 'max:255'),
|
||||
|
||||
Text::make('Email')
|
||||
->sortable()
|
||||
->rules('required', 'email', 'max:254')
|
||||
->creationRules('unique:users,email')
|
||||
->updateRules('unique:users,email,{{resourceId}}'),
|
||||
|
||||
Password::make('Password')
|
||||
->onlyOnForms()
|
||||
->creationRules($this->passwordRules())
|
||||
->updateRules($this->optionalPasswordRules()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cards available for the request.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Card>
|
||||
*/
|
||||
public function cards(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filters available for the resource.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Filters\Filter>
|
||||
*/
|
||||
public function filters(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lenses available for the resource.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Lenses\Lens>
|
||||
*/
|
||||
public function lenses(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions available for the resource.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Actions\Action>
|
||||
*/
|
||||
public function actions(NovaRequest $request): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
24
app/Providers/AppServiceProvider.php
Normal file
24
app/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
94
app/Providers/NovaServiceProvider.php
Normal file
94
app/Providers/NovaServiceProvider.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Fortify\Features;
|
||||
use Laravel\Nova\Nova;
|
||||
use Laravel\Nova\NovaApplicationServiceProvider;
|
||||
|
||||
class NovaServiceProvider extends NovaApplicationServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the configurations for Laravel Fortify.
|
||||
*/
|
||||
protected function fortify(): void
|
||||
{
|
||||
Nova::fortify()
|
||||
->features([
|
||||
Features::updatePasswords(),
|
||||
Features::emailVerification(),
|
||||
Features::twoFactorAuthentication(['confirm' => true, 'confirmPassword' => true]),
|
||||
])
|
||||
->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Nova routes.
|
||||
*/
|
||||
protected function routes(): void
|
||||
{
|
||||
Nova::routes()
|
||||
->withAuthenticationRoutes(default: true)
|
||||
->withPasswordResetRoutes()
|
||||
->withEmailVerificationRoutes()
|
||||
->register();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Nova gate.
|
||||
*
|
||||
* This gate determines who can access Nova in non-local environments.
|
||||
*/
|
||||
protected function gate(): void
|
||||
{
|
||||
Gate::define('viewNova', function (User $user) {
|
||||
return in_array($user->email, [
|
||||
'jonathan@blijnder.nl',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dashboards that should be listed in the Nova sidebar.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Dashboard>
|
||||
*/
|
||||
protected function dashboards(): array
|
||||
{
|
||||
return [
|
||||
new \App\Nova\Dashboards\Main,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tools that should be listed in the Nova sidebar.
|
||||
*
|
||||
* @return array<int, \Laravel\Nova\Tool>
|
||||
*/
|
||||
public function tools(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
parent::register();
|
||||
|
||||
//
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user