More updates for laravel 11

This commit is contained in:
2024-11-04 18:25:49 +11:00
parent 0bd2f6e82c
commit dc2e84386f
50 changed files with 870 additions and 1320 deletions

View File

@@ -1,46 +0,0 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
use App\Jobs\{AddressIdleDomain,MailSend,SystemHeartbeat};
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->job(new MailSend(TRUE))->everyMinute()->withoutOverlapping();
$schedule->job(new MailSend(FALSE))->twiceDaily(1,13);
$schedule->job(new SystemHeartbeat)->hourly();
$schedule->job(new AddressIdleDomain)->weeklyOn(0,'01:00');
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
}

213
app/Helpers/PageAssets.php Normal file
View File

@@ -0,0 +1,213 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
/**
* Useful tools (js/css) used when rendering pages
*/
class PageAssets
{
// Types that we can handle
private const array types = [
'css',
'js',
];
public const array assets = [
'datatables' => [
'base' => [
'css' => [
'//cdn.datatables.net/2.1.2/css/dataTables.bootstrap4.css',
//'//cdn.datatables.net/2.1.2/css/dataTables.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/2.1.2/js/dataTables.min.js',
'//cdn.datatables.net/2.1.2/js/dataTables.bootstrap4.min.js',
],
],
'buttons' => [
'css' => [
'//cdn.datatables.net/buttons/3.1.0/css/buttons.bootstrap4.min.css',
//'//cdn.datatables.net/buttons/3.1.0/css/buttons.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/buttons/3.1.0/js/dataTables.buttons.min.js',
//'//cdn.datatables.net/buttons/3.1.0/js/buttons.dataTables.min.js',
'//cdn.datatables.net/buttons/3.1.0/js/buttons.bootstrap4.min.js',
'//cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js',
],
],
'conditionalpaging' => [
'js' => [
'//cdn.datatables.net/plug-ins/2.0.5/features/conditionalPaging/dataTables.conditionalPaging.min.js',
],
],
'fixedheader' => [
'css' => [
'//cdn.datatables.net/fixedheader/4.0.1/css/fixedHeader.bootstrap4.min.css',
//'//cdn.datatables.net/fixedheader/4.0.1/css/fixedHeader.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/fixedheader/4.0.1/js/dataTables.fixedHeader.min.js',
//'//cdn.datatables.net/fixedheader/4.0.1/js/fixedHeader.dataTables.min.js',
'//cdn.datatables.net/fixedheader/4.0.1/js/fixedHeader.bootstrap4.min.js',
]
],
'responsive' => [
'css' => [
'//cdn.datatables.net/responsive/3.0.2/css/responsive.bootstrap4.min.css',
//'//cdn.datatables.net/responsive/3.0.2/css/responsive.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/responsive/3.0.2/js/dataTables.responsive.min.js',
//'//cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap.min.js',
'//cdn.datatables.net/responsive/3.0.2/js/responsive.bootstrap4.min.js',
]
],
'rowgroup' => [
'css' => [
'//cdn.datatables.net/rowgroup/1.5.0/css/rowGroup.bootstrap4.min.css',
//'//cdn.datatables.net/rowgroup/1.5.0/css/rowGroup.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/rowgroup/1.5.0/js/dataTables.rowGroup.min.js',
//'//cdn.datatables.net/rowgroup/1.5.0/js/rowGroup.dataTables.min.js',
'//cdn.datatables.net/rowgroup/1.5.0/js/rowGroup.bootstrap4.min.js',
],
],
'searchpanes' => [
'css' => [
'//cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.bootstrap4.min.css',
//'//cdn.datatables.net/searchpanes/2.3.1/css/searchPanes.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/searchpanes/2.3.1/js/dataTables.searchPanes.min.js',
//'//cdn.datatables.net/searchpanes/2.3.1/js/searchPanes.dataTables.min.js',
'//cdn.datatables.net/searchpanes/2.3.1/js/searchPanes.bootstrap4.min.js',
],
],
'searchpanes-left' => [
'css' => [
'/plugin/dataTables/leftSearchPanes.css',
],
],
'select' => [
'css' => [
'//cdn.datatables.net/select/2.0.3/css/select.bootstrap4.min.css',
//'//cdn.datatables.net/select/2.0.3/css/select.dataTables.min.css',
],
'js' => [
'//cdn.datatables.net/select/2.0.3/js/dataTables.select.min.js',
//'//cdn.datatables.net/select/2.0.3/js/select.dataTables.min.js',
'//cdn.datatables.net/select/2.0.3/js/select.bootstrap4.min.js',
]
],
],
'select2' => [
'base' => [
'css' => [
'//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/css/select2.min.css',
],
'js' => [
'//cdnjs.cloudflare.com/ajax/libs/select2/4.0.13/js/select2.min.js',
],
],
'autofocus' => [
'js' => [
'/plugin/select2/fix-autofocus.js',
],
]
],
'simplemde' => [
'base' => [
'css' => [
'//cdn.jsdelivr.net/simplemde/latest/simplemde.min.css',
],
'js' => [
'//cdn.jsdelivr.net/simplemde/latest/simplemde.min.js',
],
],
],
];
// Items to manage
public static Collection $items;
// Add an item to the list
public static function add(string $type,Collection|array|string $asset): void
{
if (! in_array($type,self::types))
throw new \Exception('Invalid type: '.$type);
if (! isset(self::$items))
self::init();
if (is_string($asset))
self::$items
->get($type)
->push($asset)
->unique();
else
self::$items->put($type,
self::$items
->get($type)
->merge($asset->values())
->unique());
}
// Add a predefined asset
public static function asset(string $id): void
{
if (! isset(self::$items))
self::init();
if (str_contains($id,',')) {
[$item,$arguments] = explode(',',$id,2);
$arguments = collect(explode('|',$arguments));
} else {
$item = $id;
$arguments = collect();
}
$arguments = $arguments->prepend('base');
$asset = collect(Arr::get(self::assets,$item))->only($arguments);
foreach (self::types as $type)
if ($x=$asset->pluck($type)->filter()->flatten())
self::add($type,$x);
}
// Render the CSS items
public static function css(): string
{
return isset(self::$items)
? self::$items
->get('css')
->map(fn($item)=>sprintf('<link rel="stylesheet" href="%s">',$item))
->join('')
: '';
}
public static function init(): void
{
self::$items = collect([
'js' => collect(),
'css' => collect(),
]);
}
// Render the JS items
public static function js(): string
{
return isset(self::$items)
? self::$items
->get('js')
->map(fn($item)=>sprintf('<script type="text/javascript" src="%s"></script>',$item))
->join('')
: '';
}
}

View File

@@ -1,83 +0,0 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\AddUserToView::class,
],
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'activeuser' => \App\Http\Middleware\ActiveUser::class,
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces the listed middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}

View File

@@ -1,21 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
class Authenticate extends Middleware
{
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* @param \Illuminate\Http\Request $request
* @return string
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
class CheckForMaintenanceMode extends Middleware
{
/**
* The URIs that should be reachable while maintenance mode is enabled.
*
* @var array
*/
protected $except = [
//
];
}

View File

@@ -1,17 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
class EncryptCookies extends Middleware
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}

View File

@@ -1,28 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Providers\RouteServiceProvider;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle(Request $request,\Closure $next,?string $guard=NULL)
{
if (Auth::guard($guard)->check()) {
return redirect(RouteServiceProvider::HOME);
}
return $next($request);
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
class TrimStrings extends Middleware
{
/**
* The names of the attributes that should not be trimmed.
*
* @var array
*/
protected $except = [
'password',
'password_confirmation',
];
}

View File

@@ -1,28 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array
*/
protected $proxies;
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
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;
}

View File

@@ -1,24 +0,0 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
*
* @var bool
*/
protected $addHttpCookie = true;
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
//
];
}

View File

@@ -1,8 +1,9 @@
<?php
namespace App\Casts;
namespace App\Models\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class CollectionOrNull implements CastsAttributes
@@ -10,13 +11,13 @@ class CollectionOrNull implements CastsAttributes
/**
* Cast the given value.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return Collection
*/
public function get($model,string $key,$value,array $attributes): Collection
public function get(Model $model,string $key,$value,array $attributes): Collection
{
return collect(json_decode($value, true));
}
@@ -30,7 +31,7 @@ class CollectionOrNull implements CastsAttributes
* @param array $attributes
* @return string|null
*/
public function set($model,string $key,$value,array $attributes): ?string
public function set(Model $model,string $key,$value,array $attributes): ?string
{
return ($value->count()) ? json_encode($value) : NULL;
}

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Casts;
namespace App\Models\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Casts;
namespace App\Models\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

View File

@@ -5,7 +5,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use App\Casts\CollectionOrNull;
use App\Models\Casts\CollectionOrNull;
class Dynamic extends Model
{

View File

@@ -9,10 +9,10 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
use App\Classes\FTN\Message;
use App\Events\Echomail as EchomailEvent;
use App\Interfaces\Packet;
use App\Models\Casts\{CompressedStringOrNull,CollectionOrNull,UTF8StringOrNull};
use App\Traits\{MessageAttributes,MsgID,ParseAddresses,QueryCacheableConfig};
final class Echomail extends Model implements Packet
@@ -250,6 +250,7 @@ final class Echomail extends Model implements Packet
}
// See if we need to export this message.
// @todo We need to limit exporting if address/system is not active
if ($model->echoarea->sec_read) {
$exportto = $model
->echoarea

View File

@@ -11,7 +11,7 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use App\Casts\{CollectionOrNull,CompressedStringOrNull};
use App\Models\Casts\{CompressedStringOrNull,CollectionOrNull};
class File extends Model
{

View File

@@ -10,9 +10,9 @@ use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Casts\{CollectionOrNull,CompressedStringOrNull,UTF8StringOrNull};
use App\Interfaces\Packet;
use App\Pivots\ViaPivot;
use App\Models\Casts\{CompressedStringOrNull,CollectionOrNull,UTF8StringOrNull};
use App\Models\Pivots\ViaPivot;
use App\Traits\{MessageAttributes,MsgID};
final class Netmail extends Model implements Packet

View File

@@ -2,10 +2,9 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Casts\UTF8StringOrNull;
use App\Models\Casts\UTF8StringOrNull;
class Origin extends Model
{

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Pivots;
namespace App\Models\Pivots;
use Illuminate\Database\Eloquent\Relations\Pivot;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Policies;
namespace App\Models\Policies;
use Illuminate\Auth\Access\HandlesAuthorization;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Policies;
namespace App\Models\Policies;
use Illuminate\Auth\Access\HandlesAuthorization;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Policies;
namespace App\Models\Policies;
use Illuminate\Auth\Access\HandlesAuthorization;

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Policies;
namespace App\Models\Policies;
use App\Models\User;

View File

@@ -2,10 +2,9 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Casts\UTF8StringOrNull;
use App\Models\Casts\UTF8StringOrNull;
class Tagline extends Model
{

View File

@@ -2,10 +2,9 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Casts\UTF8StringOrNull;
use App\Models\Casts\UTF8StringOrNull;
class Tearline extends Model
{

View File

@@ -5,15 +5,18 @@ namespace App\Providers;
use Illuminate\Http\Request;
use Illuminate\Notifications\ChannelManager;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\ServiceProvider;
use App\Events\Echomail as EchomailEvent;
use App\Events\Matrix\Message;
use App\Listeners\EchomailListener;
use App\Listeners\Matrix\MessageListener;
use App\Notifications\Channels\{EchomailChannel,MatrixChannel,NetmailChannel};
use App\Models\{Echomail,Netmail};
use App\Models\{Echomail,Netmail,User};
use App\Traits\SingleOrFail;
class AppServiceProvider extends ServiceProvider
@@ -51,10 +54,21 @@ class AppServiceProvider extends ServiceProvider
{
static::bootSingleOrFail();
// Add our page assets
Blade::directive('pa',function($expression) {
return sprintf('<?php PageAssets::asset(\'%s\') ?>',$expression);
});
Auth::viaRequest('matrix-token',function (Request $request) {
return (config('matrix.hs_token') && ($request->bearerToken() === config('matrix.hs_token'))) ? TRUE : NULL;
});
// Mailer Admin
Gate::define('admin',fn(User $o)=>($o->admin === TRUE));
// ZC of a Zone
Gate::define('zc',fn(User $o)=>(($o->admin === TRUE) || $o->ZC()));
Event::listen(
Message::class,
MessageListener::class,
@@ -62,7 +76,7 @@ class AppServiceProvider extends ServiceProvider
// @todo This should be detected automatically?
Event::listen(
\App\Events\Echomail::class,
EchomailEvent::class,
EchomailListener::class,
);
}

View File

@@ -1,36 +0,0 @@
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Models\User;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
//'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
// Mailer Admin
Gate::define('admin',fn(User $o)=>($o->admin === TRUE));
// ZC of a Zone
Gate::define('zc',fn(User $o)=>(($o->admin === TRUE) || $o->ZC()));
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Broadcast;
class BroadcastServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Broadcast::routes();
require base_path('routes/channels.php');
}
}

View File

@@ -1,63 +0,0 @@
<?php
namespace App\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
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/';
/**
* The controller namespace for the application.
*
* When present, controller route declarations will automatically be prefixed with this namespace.
*
* @var string|null
*/
// protected $namespace = 'App\\Http\\Controllers';
/**
* Define your route model bindings, pattern filters, etc.
*
* @return void
*/
public function boot()
{
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('api')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
/**
* Configure the rate limiters for the application.
*
* @return void
*/
protected function configureRateLimiting()
{
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
});
}
}

View File

@@ -13,6 +13,7 @@ trait SingleOrFail
private static function bootSingleOrFail(): void
{
// When a query should return 1 object, or FAIL if it doesnt
// @deprecated use sole()
Builder::macro('singleOrFail',function () {
$result = $this->get();