Add missing files

This commit is contained in:
DariusIII
2025-10-27 13:42:04 +01:00
parent 6498f84bc8
commit 9717d53d4b
7 changed files with 217 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class SetUserTimezone
{
/**
* Handle an incoming request.
*
* Note: We do NOT set the global timezone here because it would interfere
* with database operations and helper functions. Instead, the timezone
* conversion happens in the userDate() and userDateDiffForHumans() helpers.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// Timezone conversion is handled by helper functions, not middleware
// This middleware is kept for future enhancements if needed
return $next($request);
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
namespace App\Rules;
use App\Services\TurnstileService;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;
class TurnstileRule implements ValidationRule
{
/**
* Run the validation rule.
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (empty($value)) {
$fail('Please complete the captcha verification.');
return;
}
if (! TurnstileService::verify($value)) {
$fail('The captcha verification failed. Please try again.');
}
}
}
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('system_metrics', function (Blueprint $table) {
$table->id();
$table->string('metric_type', 50)->index(); // 'cpu' or 'ram'
$table->decimal('value', 8, 2); // The metric value (percentage or GB)
$table->timestamp('recorded_at')->index(); // When the metric was recorded
$table->timestamps();
// Composite index for efficient querying
$table->index(['metric_type', 'recorded_at']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('system_metrics');
}
};
@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('signup_stats', function (Blueprint $table) {
$table->date('sort_date')->nullable()->after('month');
$table->index('sort_date');
});
// Populate sort_date for existing records
// Parse month strings like "October 2025" to create sortable dates
DB::statement("
UPDATE signup_stats
SET sort_date = STR_TO_DATE(CONCAT('01 ', month), '%d %M %Y')
WHERE sort_date IS NULL AND month IS NOT NULL
");
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('signup_stats', function (Blueprint $table) {
$table->dropIndex(['sort_date']);
$table->dropColumn('sort_date');
});
}
};
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
if (! Schema::hasColumn('users', 'timezone')) {
Schema::table('users', function (Blueprint $table) {
$table->string('timezone', 50)->default('UTC')->after('style');
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('timezone');
});
}
};
@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
if (! Schema::hasColumn('users', 'movie_layout')) {
Schema::table('users', function (Blueprint $table) {
$table->tinyInteger('movie_layout')->default(2)->comment('1=1-column, 2=2-columns')->after('timezone');
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('movie_layout');
});
}
};
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('user_activity_stats', function (Blueprint $table) {
$table->id();
$table->date('stat_date')->index();
$table->integer('downloads_count')->default(0);
$table->integer('api_hits_count')->default(0);
$table->timestamps();
// Ensure one record per date
$table->unique('stat_date');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('user_activity_stats');
}
};