Initial commit

This commit is contained in:
Christian Wederka 2023-03-23 18:50:47 +01:00
commit 91ed269683
523 changed files with 69558 additions and 0 deletions

18
.editorconfig Normal file
View File

@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
[docker-compose.yml]
indent_size = 4

52
.env.example Normal file
View File

@ -0,0 +1,52 @@
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
FILESYSTEM_DISK=local
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
MEMCACHED_HOST=127.0.0.1
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

10
.gitattributes vendored Normal file
View File

@ -0,0 +1,10 @@
* text=auto
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore

14
.gitignore vendored Normal file
View File

@ -0,0 +1,14 @@
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
/.idea
/.vscode

32
.lando.yml Normal file
View File

@ -0,0 +1,32 @@
name: larabb
services:
appserver:
type: php:8.1
via: apache:2.4
ssl: true
webroot: ./public
xdebug: true
composer_version: 2-latest
config:
php: .lando/php.ini
build_as_root:
# Note that you will want to use the script for the major version of node you want to install
# See: https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions
- curl -sL https://deb.nodesource.com/setup_18.x | bash -
- apt-get install -y nodejs
database:
portforward: 33061
type: mariadb:10.5.15
proxy:
appserver:
- larabb.lando
tooling:
setup:
description: Sets up the Contao instance
cmd:
- database: zcat .lando/database.sql.gz | mysql -u mariadb -pmariadb database
- appserver: composer install
node:
service: appserver
npm:
service: appserver

BIN
.lando/database.sql.gz Normal file

Binary file not shown.

18
.lando/php.ini Normal file
View File

@ -0,0 +1,18 @@
memory_limit = -1
xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.collect_params = 0
xdebug.mode = debug
xdebug.client_host = ${LANDO_HOST_IP}
xdebug.client_port = 9003
xdebug.start_with_request = yes
xdebug.log = /tmp/xdebug.log
; brauche ich (rolf), damit debugging funktioniert
; Remote settings
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = ${LANDO_HOST_IP}
; xdebug.remote_connect_back = 1
xdebug.remote_log = /tmp/xdebug_remote.log

12
.styleci.yml Normal file
View File

@ -0,0 +1,12 @@
php:
preset: laravel
disabled:
- no_unused_imports
finder:
not-name:
- index.php
js:
finder:
not-name:
- webpack.mix.js
css: true

64
README.md Normal file
View File

@ -0,0 +1,64 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
- **[OP.GG](https://op.gg)**
- **[WebReinvent](https://webreinvent.com/?utm_source=laravel&utm_medium=github&utm_campaign=patreon-sponsors)**
- **[Lendio](https://lendio.com)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).

17897
_ide_helper.php Normal file

File diff suppressed because it is too large Load Diff

32
app/Console/Kernel.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
/**
* A list of exception types with their corresponding custom log levels.
*
* @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
*/
protected $levels = [
//
];
/**
* A list of the exception types that are not reported.
*
* @var array<int, class-string<\Throwable>>
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed to the session on validation exceptions.
*
* @var array<int, string>
*/
protected $dontFlash = [
'current_password',
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
$this->reportable(function (Throwable $e) {
//
});
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}

67
app/Http/Kernel.php Normal file
View File

@ -0,0 +1,67 @@
<?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<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* @var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}

View File

@ -0,0 +1,21 @@
<?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|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login');
}
}
}

View File

@ -0,0 +1,17 @@
<?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

@ -0,0 +1,17 @@
<?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<int, string>
*/
protected $except = [
//
];
}

View File

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

View File

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

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use LaraBB\Forum\Models\Permission;
use LaraBB\Group\Models\Group;
use LaraBB\User\Models\User;
class SetUser
{
public function handle(Request $request, Closure $next)
{
app()->setLocale('de');
/** @var User $currentUser */
$currentUser = $request->user();
if(is_null($currentUser)) {
$currentUser = auth()->loginUsingId('8d306ec3-26ee-4bc3-918b-c8f79a3c3315');
}
$currentUser->load(['profile', 'groups.permissions']);
if(!$currentUser->isInGroup(['Guest'])) {
$currentUser->lastactive_at = now();
$currentUser->lastactive_ip = $request->ip();
$currentUser->save();
}
/** @var Collection forumPermissions */
$currentUser->forumPermissions = collect();
$currentUser->groups->sortBy('priority')->map(function(Group $group) use($currentUser) {
$group->permissions->map(function(Permission $permission) use($currentUser) {
$currentUser->forumPermissions->put($permission->forum_uuid, $permission);
});
});
view()->share('currentUser', $currentUser);
return $next($request);
}
}

View File

@ -0,0 +1,19 @@
<?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<int, string>
*/
protected $except = [
'current_password',
'password',
'password_confirmation',
];
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustHosts as Middleware;
class TrustHosts extends Middleware
{
/**
* Get the host patterns that should be trusted.
*
* @return array<int, string|null>
*/
public function hosts()
{
return [
$this->allSubdomainsOfApplicationUrl(),
];
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Middleware\TrustProxies as Middleware;
use Illuminate\Http\Request;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array<int, string>|string|null
*/
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

@ -0,0 +1,17 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array<int, string>
*/
protected $except = [
//
];
}

View File

@ -0,0 +1,27 @@
<?php
namespace LaraBB\Admin\Middleware;
use Closure;
use Illuminate\Http\RedirectResponse;
/**
* Class CheckAdmin
* @package LaraBB\Admin\Middleware
*/
class CheckAdmin
{
/**
* @param $request
* @param Closure $next
* @return RedirectResponse|mixed
*/
public function handle($request, Closure $next)
{
if(!$request->user()->isInGroup(['Administrator'])) {
return redirect()->route('index');
}
return $next($request);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace LaraBB\Admin;
use App\Providers\BaseServiceProvider;
/**
* Class ServiceProvider
* @package LaraBB\Admin
*/
class ServiceProvider extends BaseServiceProvider
{
/**
* @var string
*/
protected string $modulePath = __DIR__;
/**
* @var string
*/
protected string $moduleKey = 'admin';
}

View File

@ -0,0 +1,32 @@
<?php
namespace LaraBB\Admin\UI\Web\Handlers;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
/**
* Class DashboardHandler
* @package LaraBB\Admin\UI\Web\Handlers
*/
class DashboardHandler extends Controller
{
/**
* @param Factory $view
*/
public function __construct(private readonly Factory $view)
{
}
/**
* @return View
*/
public function __invoke(): View
{
return $this->view->make('admin::dashboard', [
'active' => 'dashboard'
]);
}
}

View File

@ -0,0 +1,46 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Purpleload</title>
<link rel="stylesheet" type="text/css" href="{{ asset('css/app.css') }}">
<link href="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAuwAAAAAAAADdAAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAERERERERERERERARERERERERAgERERERERAjIBERERERAjIyARERERAjICMgERERAjIBAjIBERECIBEQIyAREQABERECMgERERERERAjIBEREREREQIyARERERERECMgERERERERAiAREREREREQABERERERERERERERERERERH//wAA+/8AAPH/AADg/wAAwH8AAIA/AAAEHwAADg8AAB8HAAD/gwAA/8EAAP/gAAD/8AAA//gAAP//AAD//wAA" rel="icon" type="image/x-icon" />
@yield('pagecss')
</head>
<body>
<header class="global-header sticky-top">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-center" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link text-center{{ $active == 'dashboard' ? ' active' : '' }}" href="{{ route('admin') }}">
<span class="fas fa-fw fa-tachometer-alt"></span><br>Dashboard
</a>
<a class="nav-item nav-link text-center{{ $active == 'forums' ? ' active' : '' }}" href="{{ route('admin.forums') }}">
<span class="fas fa-fw fa-list-alt"></span><br>Forum
</a>
<a class="nav-item nav-link text-center{{ $active == 'users' ? ' active' : '' }}" href="{{ route('admin.users') }}">
<span class="fas fa-fw fa-user"></span><br>Benutzer
</a>
<a class="nav-item nav-link text-center{{ $active == 'groups' ? ' active' : '' }}" href="{{ route('admin.groups') }}">
<span class="fas fa-fw fa-users"></span><br>Gruppen
</a>
<a class="nav-item nav-link text-center{{ $active == 'settings' ? ' active' : '' }}" href="{{ route('admin.settings') }}">
<span class="fas fa-fw fa-cogs"></span><br>Einstellungen
</a>
</div>
</div>
</nav>
</header>
@yield('content')
<script src="{{ asset('js/jquery-3.6.0.min.js') }}"></script>
<script src="{{ asset('js/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('js/bootbox.all.min.js') }}"></script>
<script src="{{ asset('js/larabb.js') }}"></script>
@yield('pagejs')
</body>
</html>

View File

@ -0,0 +1 @@
@extends('admin::Layouts.master')

View File

@ -0,0 +1,3 @@
<?php
Route::get('/', DashboardHandler::class)->name('admin');

View File

@ -0,0 +1,13 @@
<?php
use LaraBB\Admin\Middleware\CheckAdmin;
Route::group([
'namespace' => 'LaraBB\Admin\UI\Web\Handlers',
'middleware' => [
'web',
'auth',
CheckAdmin::class
],
'prefix' => 'admin'
], __DIR__ . '/UI/Web/routes.php');

View File

@ -0,0 +1,532 @@
<?php
namespace LaraBB\Application;
/**
*
*/
class Button
{
/**
* @var string|null
*/
private ?string $strText = null;
/**
* @var bool
*/
private bool $boolAutoFocus = false;
/**
* @var bool
*/
private bool $boolDisabled = false;
/**
* @var string|null
*/
private ?string $strFormId = null;
/**
* @var string|null
*/
private ?string $strFormAction = null;
/**
* @var string|null
*/
private ?string $strFormMethod = null;
/**
* @var string|null
*/
private ?string $strFormEncType = null;
/**
* @var bool|null
*/
private ?bool $boolFormNoValidate = null;
/**
* @var string|null
*/
private ?string $strFormTarget = null;
/**
* @var string|null
*/
private ?string $strName = null;
/**
* @var string
*/
private string $strType = 'submit';
/**
* @var string|null
*/
private ?string $strValue = null;
/**
* @var string|null
*/
private ?string $strTarget = null;
/**
* @var bool
*/
private bool $boolDropdown = false;
/**
* @var array
*/
private array $arrDropdownItems = [];
/**
* @var string|null
*/
private ?string $strDropDirection = null;
/**
* @var string|null
*/
private ?string $strClass = null;
/**
* @var string|null
*/
private ?string $strId = null;
/**
* @var string|null
*/
private ?string $strIcon = null;
/**
* @var string|null
*/
private ?string $strHref = null;
/**
* @var bool|null
*/
private ?bool $boolPermission = true;
/**
* @var array
*/
private array $arrData;
/**
* @param string $strText
*/
public function __construct(string $strText = '')
{
$this->text($strText);
$this->arrData = [];
}
/**
* @param string $strText
* @return Button
*/
public function text(string $strText): static
{
$this->strText = $strText;
return $this;
}
/**
* @param bool $boolAutoFocus
* @return Button
*/
public function autofocus(bool $boolAutoFocus = true): static
{
$this->boolAutoFocus = $boolAutoFocus;
return $this;
}
/**
* @param bool $boolDisabled
* @return Button
*/
public function disabled(bool $boolDisabled = true): static
{
$this->boolDisabled = $boolDisabled;
return $this;
}
/**
* @param string $strFormId
* @return Button
*/
public function form(string $strFormId): static
{
$this->strFormId = $strFormId;
return $this;
}
/**
* @param string $strFormAction
* @return Button
*/
public function formaction(string $strFormAction): static
{
$this->strFormAction = $strFormAction;
return $this;
}
/**
* @param string $strFormEncType
* @return $this
*/
public function formenctype(string $strFormEncType): static
{
$this->strFormEncType = $strFormEncType;
return $this;
}
/**
* @param string $strFormMethod
* @return Button
*/
public function formmethod(string $strFormMethod): static
{
$this->strFormMethod = $strFormMethod;
return $this;
}
/**
* @param bool $boolFormNoValidate
* @return Button
*/
public function formnovalidate(bool $boolFormNoValidate = true): static
{
$this->boolFormNoValidate = $boolFormNoValidate;
return $this;
}
/**
* @param string $strFormTarget
* @return Button
*/
public function formtarget(string $strFormTarget): static
{
$this->strFormTarget = $strFormTarget;
return $this;
}
/**
* @param string $strId
* @return Button
*/
public function id(string $strId): static
{
$this->strId = $strId;
return $this;
}
/**
* @param string $strClass
* @return Button
*/
public function class(string $strClass): static
{
$this->strClass = $strClass;
return $this;
}
/**
* @param string $strType
* @return Button
*/
public function type(string $strType): static
{
$this->strType = $strType;
return $this;
}
/**
* @param string $strName
* @param string $strValue
* @return $this
*/
public function data(string $strName, string $strValue): static
{
$this->arrData[$strName] = $strValue;
return $this;
}
/**
* @return string|null
*/
public function getData(): ?string
{
if (count($this->arrData)) {
$strRet = '';
foreach ($this->arrData as $strIndex => $strValue) {
$strRet .= sprintf(' data-%s="%s" ', $strIndex, $strValue);
}
return $strRet;
}
return '';
}
/**
* @param string $strName
* @return Button
*/
public function name(string $strName): static
{
$this->strName = $strName;
return $this;
}
/**
* @param string $strValue
* @return Button
*/
public function value(string $strValue): static
{
$this->strValue = $strValue;
return $this;
}
/**
* @param string $strDropDirection
* @param array $arrDropdownItems
* @return Button
*/
public function dropdown(array $arrDropdownItems, string $strDropDirection = 'down'): static
{
$this->boolDropdown = true;
$this->strDropDirection = $strDropDirection === 'down' ? null : $strDropDirection;
$this->arrDropdownItems = $arrDropdownItems;
return $this;
}
/**
* @param string $strIcon
* @return Button
*/
public function icon(string $strIcon): static
{
$this->strIcon = $strIcon;
return $this;
}
/**
* @param string $strHref
* @return $this
*/
public function href(string $strHref): static
{
$this->strHref = $strHref;
return $this;
}
/**
* @param string $strTarget
* @return $this
*/
public function target(string $strTarget): static
{
$this->strTarget = $strTarget;
return $this;
}
/**
* @param $boolPermission
* @return $this
*/
public function permission($boolPermission): static
{
$this->boolPermission = $boolPermission;
return $this;
}
/**
* @return string|null
*/
public function getText(): ?string
{
return $this->strText;
}
/**
* @return bool
*/
public function getAutoFocus(): bool
{
return $this->boolAutoFocus;
}
/**
* @return bool
*/
public function getDisabled(): bool
{
return $this->boolDisabled;
}
/**
* @return string|null
*/
public function getForm(): ?string
{
return $this->strFormId;
}
/**
* @return string|null
*/
public function getFormAction(): ?string
{
return $this->strFormAction;
}
/**
* @return string|null
*/
public function getFormEnctype(): ?string
{
return $this->strFormEncType;
}
/**
* @return string|null
*/
public function getFormMethod(): ?string
{
return $this->strFormMethod;
}
/**
* @return bool|null
*/
public function getFormNoValidate(): ?bool
{
return $this->boolFormNoValidate;
}
/**
* @return string|null
*/
public function getFormTarget(): ?string
{
return $this->strFormTarget;
}
/**
* @return string|null
*/
public function getName(): ?string
{
return $this->strName;
}
/**
* @return string|null
*/
public function getType(): ?string
{
return $this->strType;
}
/**
* @return string|null
*/
public function getValue(): ?string
{
return $this->strValue;
}
/**
* @return string|null
*/
public function getClass(): ?string
{
return $this->strClass;
}
/**
* @return string|null
*/
public function getId(): ?string
{
return $this->strId;
}
/**
* @return string|null
*/
public function getHref(): ?string
{
return $this->strHref;
}
/**
* @return string|null
*/
public function getTarget(): ?string
{
return $this->strTarget;
}
/**
* @return bool
*/
public function hasDropdown(): bool
{
return $this->boolDropdown;
}
/**
* @return string|null
*/
public function getDropDirection(): ?string
{
return $this->strDropDirection;
}
/**
* @return array
*/
public function getDropdownItems(): array
{
return $this->arrDropdownItems;
}
/**
* @return string|null
*/
public function getIcon(): ?string
{
return $this->strIcon;
}
/**
* @return bool|null
*/
public function getPermission(): ?bool
{
return $this->boolPermission;
}
/**
* @return string
*/
public function render(): string
{
return view('components.atomic.button', [
'btn' => $this
])->render();
}
/**
* @return string
*/
public function __toString()
{
return $this->render();
}
}

View File

@ -0,0 +1,102 @@
<?php
return [
'global' => [
'layout' => 'fixed'
],
'validation' => [
'rules' => [
/** User */
'user' => [
'uuid' => [
'required',
'uuid',
'exists:users,uuid',
],
'username' => [
'required',
'unique:users,username'
],
'email' => [
'required',
'email'
],
'password' => [
'nullable',
'confirmed',
'min:8',
],
'groups' => [
'required',
],
],
/** Kategorien */
'categories' => [
'uuid' => [
'required',
'uuid',
'exists:categories,uuid'
],
'title' => [
'required',
'max:255'
],
'slug' => [
'required',
'exists:categories,slug',
'max:255'
]
],
'forum' => [
''
]
],
'messages' => [
/** User */
'user' => [
'uuid' => [
'required' => 'Es wurde keine UUID übergeben.',
'uuid' => 'Die übergebene UUID ist ungültig.',
'exists' => 'Der Benutzer existiert nicht.',
],
'username' => [
'required' => 'Bitte geben Sie einen Benutzernamen an!',
'unique' => 'Dieser Benutzername ist bereits vergeben.'
],
'email' => [
'required' => 'Bitte geben Sie eine E-Mail Adresse an!',
'email' => 'Die angegebene E-Mail Adresse hat ein ungültiges Format.',
],
'password' => [
'required' => 'Bitte geben Sie ein Passwort an!',
'confirmed' => 'Bitte bestätigen Sie das angegebene Passwort.',
'min' => 'Das angegebene Passwort muss mindestens :min Zeichen lang sein.',
],
'groups' => [
'required' => 'Bitte wählen Sie mindestens eine Benutzergruppe aus.',
],
'groups.*' => [
'in' => 'Die :index Benutzergruppe ist ungültig.'
]
],
/** Kategorien */
'categories' => [
'uuid' => [
'required' => 'Es wurde keine UUID übergeben.',
'uuid' => 'Die übergebene UUID ist ungültig.',
'exists' => 'Diese Kategorie existiert nicht.',
],
'title' => [
'required' => 'Bitte geben Sie eine Bezeichnung an!',
'max' => 'Die angegebene Bezeichnung ist zu lang (max. :max Zeichen).'
],
'slug' => [
'required' => __('Please specify a category.'),
'exists' => __('The desired category does not exist.'),
'max' => 'Die angegebene URL ist zu lang (max. :max Zeichen).'
]
]
]
]
];

View File

@ -0,0 +1,22 @@
<?php
namespace LaraBB\Application;
use App\Providers\BaseServiceProvider;
/**
* Class ServiceProvider
* @package LaraBB\Base
*/
class ServiceProvider extends BaseServiceProvider
{
/**
* @var string
*/
protected string $modulePath = __DIR__;
/**
* @var string
*/
protected string $moduleKey = 'application';
}

View File

@ -0,0 +1,67 @@
<?php
namespace LaraBB\Application\Traits;
/**
*
*/
trait Request
{
/**
* @param string $identifier
* @param array $except
* @return array
*/
public function getRules(string $identifier, array $except = []): array
{
$rules = config('application.validation.rules.' . $identifier);
$parts = explode('.', $identifier);
$field = $parts[1] ?? null;
// Mappe Einzelfeld-Regel so, als wären es mehrere Felder
if(!is_null($field)) {
$rules = [$field => $rules];
}
// Baue neues Regel-Array mit Regel-Bezeichner als Indizes auf
$rulesWithNameIndices = [];
foreach($rules as $field => $fieldRules) {
foreach($fieldRules as $index => $rule) {
$ruleWithParamters = explode(':', $rule);
$ruleIndex = count($ruleWithParamters) > 1 ? $ruleWithParamters[0] : $rule;
$rulesWithNameIndices[$field][$ruleIndex] = $rule;
}
}
return collect($rulesWithNameIndices)->except($except)->map(function($rules) {
return implode('|', $rules);
})->toArray();
}
/**
* @param string $identifier
* @param array $except
* @return array
*/
public function getMessages(string $identifier, array $except = []): array
{
$messages = config('application.validation.messages.' . $identifier);
$parts = explode('.', $identifier);
$field = $parts[1] ?? null;
return collect($messages)->except($except)->mapWithKeys(function($message, $key) use($field) {
// Messages für einzelnes Feld wurde angefordert ($mixedMessage = string)
if(!is_null($field)) {
return [$field . '.' . $key => $message];
}
$messageItems = [];
foreach($message as $messageKey => $messageValue) {
$messageItems[$key . '.' . $messageKey] = $messageValue;
}
return $messageItems;
})->toArray();
}
}

View File

@ -0,0 +1,14 @@
<?php
use LaraBB\Application\Button;
if(!function_exists('button')) {
/**
* @param string $strText
* @return Button
*/
function button(string $strText = ''): Button
{
return new Button($strText);
}
}

View File

@ -0,0 +1,49 @@
<?php
namespace LaraBB\Category\Actions\Admin;
use Exception;
use Illuminate\Database\Connection;
use LaraBB\Category\Tasks\DestroyTask as DestroyCategoryTask;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Category\UI\Web\Requests\Destroy;
use Throwable;
/**
* Class DestroyAction
* @package LaraBB\Category\Actions\Admin
*/
class DestroyAction
{
/**
* DestroyAction constructor.
* @param FindCategoryTask $findCategoryTask
* @param DestroyCategoryTask $destroyCategoryTask
* @param Connection $connection
*/
public function __construct(
private readonly FindCategoryTask $findCategoryTask,
private readonly DestroyCategoryTask $destroyCategoryTask,
private readonly Connection $connection
) {
}
/**
* @param Destroy $request
* @return bool|null
* @throws Exception
*/
public function run(Destroy $request): ?bool
{
$category = $this->findCategoryTask->byUuid($request->post('uuid'));
try {
$this->connection->transaction(function() use($category) {
$this->destroyCategoryTask->run($category);
});
} catch(Throwable $t) {
return false;
}
return true;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace LaraBB\Category\Actions\Admin;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Category\UI\Web\Requests\Edit;
/**
* Class EditAction
* @package LaraBB\Category\Actions\Admin
*/
class EditAction
{
/**
* EditAction constructor.
* @param FindCategoryTask $findCategoryTask
*/
public function __construct(private readonly FindCategoryTask $findCategoryTask)
{
}
/**
* @param Edit $request
* @return array
*/
#[ArrayShape([
'category' => "\LaraBB\Category\Models\Category",
'active' => "string"
])]
public function run(Edit $request): array
{
return [
'category' => $this->findCategoryTask->byUuid($request->route('uuid')),
'active' => 'forums'
];
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace LaraBB\Category\Actions\Admin;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
/**
* Class OverviewAction
* @package LaraBB\Category\Actions\Admin
*/
class IndexAction
{
/**
* OverviewAction constructor.
* @param FindCategoryTask $findCategoryTask
*/
public function __construct(private readonly FindCategoryTask $findCategoryTask)
{
}
/**
* @return array
*/
#[ArrayShape([
'categories' => "array|\Illuminate\Database\Eloquent\Collection",
'active' => "string"
])]
public function run()
{
return [
'categories' => $this->findCategoryTask->all(['forums']),
'active' => 'forums'
];
}
}

View File

@ -0,0 +1,60 @@
<?php
namespace LaraBB\Category\Actions\Admin;
use Illuminate\Database\Connection;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\StoreTask;
use LaraBB\Category\UI\Web\Requests\Store;
use Throwable;
/**
* Class StoreAction
* @package LaraBB\Category\Actions\Admin
*/
class StoreAction
{
/**
* StoreAction constructor.
* @param StoreTask $storeCategoryTask
* @param Connection $connection
*/
public function __construct(
private readonly StoreTask $storeCategoryTask,
private readonly Connection $connection
) {
}
/**
* @param Store $request
* @return bool
*/
public function run(Store $request): bool
{
try {
$this->connection->transaction(function () use ($request) {
$this->storeCategoryTask->run($this->prepareCategoryData($request));
});
} catch (Throwable $t) {
return false;
}
return true;
}
#[ArrayShape([
'created_uuid' => "mixed",
'updated_uuid' => "mixed",
'title' => "array|null|string",
'slug' => "array|null|string"
])]
private function prepareCategoryData(Store $request): array
{
return [
'created_uuid' => $request->user()->uuid,
'updated_uuid' => $request->user()->uuid,
'title' => $request->post('title'),
'slug' => $request->post('slug')
];
}
}

View File

@ -0,0 +1,66 @@
<?php
namespace LaraBB\Category\Actions\Admin;
use Illuminate\Database\Connection;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Category\Tasks\UpdateTask as UpdateCategoryTask;
use LaraBB\Category\UI\Web\Requests\Update;
use Throwable;
/**
* Class UpdateAction
* @package LaraBB\Category\Actions\Admin
*/
class UpdateAction
{
/**
* UpdateAction constructor.
* @param FindCategoryTask $findCategoryTask
* @param UpdateCategoryTask $updateCategoryTask
* @param Connection $connection
*/
public function __construct(
private readonly FindCategoryTask $findCategoryTask,
private readonly UpdateCategoryTask $updateCategoryTask,
private readonly Connection $connection
) {
}
/**
* @param Update $request
* @return bool
*/
public function run(Update $request): bool
{
$category = $this->findCategoryTask->byUuid($request->post('uuid'));
try {
$this->connection->transaction(function () use ($category, $request) {
$this->updateCategoryTask->run($category, $this->prepareCategoryData($request));
});
} catch (Throwable $t) {
return false;
}
return true;
}
/**
* @param Update $request
* @return array
*/
#[ArrayShape([
'updated_uuid' => "mixed",
'title' => "array|null|string",
'slug' => "array|null|string"
])]
private function prepareCategoryData(Update $request): array
{
return [
'updated_uuid' => $request->user()->uuid,
'title' => $request->post('title'),
'slug' => $request->post('slug')
];
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace LaraBB\Category\Actions;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Models\Category;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Category\Traits\ForumsTrait;
use LaraBB\Category\UI\Web\Requests\Index;
use LaraBB\Forum\Models\Forum;
/**
* Class IndexAction
* @package LaraBB\Category\Actions
*/
class IndexAction
{
use ForumsTrait;
/**
* IndexAction constructor.
* @param FindCategoryTask $findCategoryTask
*/
public function __construct(private readonly FindCategoryTask $findCategoryTask)
{
}
/**
* @param Index $request
* @return array
*/
#[ArrayShape([
'categories' => "array|\Illuminate\Database\Eloquent\Collection"
])]
public function run(Index $request): array
{
$categories = $this->findCategoryTask->all([
'forums' => function ($query) {
$query->with([
'users',
'lastpost' => function ($query) {
return $query->with(['thread', 'createdBy']);
}
]);
}
])->filter(function (Category $category) use ($request) {
$category->forums = $this->getForums($category, $request);
return $category->forums->count() > 0;
});
return [
'categories' => $categories
];
}
}

View File

@ -0,0 +1,53 @@
<?php
namespace LaraBB\Category\Actions;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Category\Traits\ForumsTrait;
use LaraBB\Category\UI\Web\Requests\Show;
use LaraBB\Forum\Models\Forum;
/**
* Class CategoryAction
* @package LaraBB\Category\Actions
*/
class ShowAction
{
use ForumsTrait;
/**
* CategoryAction constructor.
* @param FindCategoryTask $findCategoryTask
*/
public function __construct(private readonly FindCategoryTask $findCategoryTask)
{
}
/**
* @param Show $request
* @return array
*/
#[ArrayShape([
'category' => "\LaraBB\Category\Models\Category"
])]
public function run(Show $request): array
{
$category = $this->findCategoryTask->bySlug($request->route('slug'), [
'forums' => function ($query) {
return $query->with([
'users',
'lastpost' => function ($query) {
return $query->with(['thread', 'createdBy']);
}
]);
}
]);
$category->forums = $this->getForums($category, $request);
return [
'category' => $category
];
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateCategoriesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->index('uuid');
$table->dateTime('created_at');
$table->uuid('created_uuid')->index('created_uuid');
$table->dateTime('updated_at');
$table->uuid('updated_uuid')->index('updated_uuid');
$table->string('title', 255);
$table->string('slug', 255);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('categories');
}
}

View File

@ -0,0 +1,58 @@
<?php
namespace LaraBB\Category\Models;
use App\Traits\Uuid;
use App\Traits\Who;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use LaraBB\Forum\Models\Forum;
use Str;
/**
* Class Category
*
* @property int $id
* @property string $uuid
* @property Carbon $created_at
* @property string $created_uuid
* @property Carbon $updated_at
* @property string $updated_uuid
* @property string $title
* @property string $slug
* @property Collection $forums
*
* @package LaraBB\Category\Models
*/
class Category extends Model
{
use Uuid;
use Who;
/**
* @var string
*/
protected $table = 'categories';
/**
* @var string
*/
protected $primaryKey = 'uuid';
/**
* @return HasMany
*/
public function forums(): HasMany
{
return $this->hasMany(Forum::class, 'category_uuid', 'uuid');
}
/**
* @param $value
*/
public function setSlugAttribute($value)
{
$this->attributes['slug'] = Str::slug($value);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace LaraBB\Category;
use App\Providers\BaseServiceProvider;
/**
* Class ServiceProvider
* @package LaraBB\Category
*/
class ServiceProvider extends BaseServiceProvider
{
/**
* @var string
*/
protected string $modulePath = __DIR__;
/**
* @var string
*/
protected string $moduleKey = 'category';
}

View File

@ -0,0 +1,23 @@
<?php
namespace LaraBB\Category\Tasks;
use Exception;
use LaraBB\Category\Models\Category;
/**
* Class DestroyCategoryTask
* @package LaraBB\Category\Tasks
*/
class DestroyTask
{
/**
* @param Category $category
* @return bool|null
* @throws Exception
*/
public function run(Category $category): ?bool
{
return $category->delete();
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace LaraBB\Category\Tasks;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Category\Models\Category;
/**
* Class GetCategoryTask
* @package LaraBB\Category\Tasks
*/
class FindTask
{
/**
* GetCategoryTask constructor.
* @param Category $category
*/
public function __construct(private readonly Category $category)
{
}
/**
* @param array $with
* @return Collection|array
*/
public function all(array $with = []): Collection|array
{
return $this->category->query()->with($with)->get();
}
/**
* @param string $uuid
* @param array $with
* @return Category
*/
public function byUuid(string $uuid, array $with = []): Category
{
return $this->category->query()->with($with)->where('uuid', $uuid)->get()->first();
}
/**
* @param string $slug
* @param array $with
* @return Category
*/
public function bySlug(string $slug, array $with = []): Category
{
return $this->category->query()->with($with)->where('slug', $slug)->get()->first();
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace LaraBB\Category\Tasks;
use LaraBB\Category\Models\Category;
/**
* Class StoreCategoryTask
* @package LaraBB\Category\Tasks
*/
class StoreTask
{
/**
* @var Category
*/
private Category $category;
/**
* StoreCategoryTask constructor.
* @param Category $category
*/
public function __construct(Category $category)
{
$this->category = $category;
}
/**
* @param array $data
* @return Category
*/
public function run(array $data = []): Category
{
$this->category->created_uuid = $data['created_uuid'];
$this->category->updated_uuid = $data['updated_uuid'];
$this->category->title = $data['title'];
$this->category->slug = $data['slug'];
$this->category->save();
return $this->category;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace LaraBB\Category\Tasks;
use LaraBB\Category\Models\Category;
/**
* Class UpdateCategoryTask
* @package LaraBB\Category\Tasks
*/
class UpdateTask
{
/**
* @param Category $category
* @param array $data
* @return bool
*/
public function run(Category $category, array $data = []): bool
{
$category->updated_uuid = $data['updated_uuid'];
$category->title = $data['title'];
$category->slug = $data['slug'];
return $category->save();
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace LaraBB\Category\Traits;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Category\Models\Category;
use LaraBB\Category\UI\Web\Requests\Index;
use LaraBB\Category\UI\Web\Requests\Show;
use LaraBB\Forum\Models\Forum;
/**
*
*/
trait ForumsTrait
{
/**
* @param Category $category
* @param Index|Show $request
* @return Collection
*/
public function getForums(Category $category, Index|Show $request): Collection
{
return $category->forums->filter(function (Forum $forum) use ($request) {
if (!isset($request->user()->forumPermissions[$forum->uuid])) {
return false;
}
if ($request->user()->forumPermissions[$forum->uuid]->show_forum) {
return $forum->users->isEmpty() || $forum->users->contains('uuid', $request->user()->uuid) || $request->user()->isInGroup(['Administrator', 'Moderator']);
}
return false;
});
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
/**
* Class CreateHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class CreateHandler extends Controller
{
/**
* @param Factory $view
*/
public function __construct(private readonly Factory $view)
{
}
/**
* @return View
*/
public function __invoke(): View
{
return $this->view->make('category::admin.create-edit', [
'active' => 'forums'
]);
}
}

View File

@ -0,0 +1,34 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\RedirectResponse;
use LaraBB\Category\Actions\Admin\DestroyAction;
use LaraBB\Category\UI\Web\Requests\Destroy;
/**
* Class DestroyHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class DestroyHandler extends Controller
{
/**
* DestroyHandler constructor.
* @param DestroyAction $destroyAction
*/
public function __construct(private readonly DestroyAction $destroyAction)
{
}
/**
* @param Destroy $request
* @return RedirectResponse
* @throws Exception
*/
public function __invoke(Destroy $request): RedirectResponse
{
return $this->destroyAction->run($request) ? $request->success() : $request->failed();
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
use LaraBB\Category\Actions\Admin\EditAction;
use LaraBB\Category\UI\Web\Requests\Edit;
/**
* Class EditHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class EditHandler extends Controller
{
/**
* EditHandler constructor.
* @param EditAction $editAction
* @param Factory $view
*/
public function __construct(
private readonly EditAction $editAction,
private readonly Factory $view
) {
}
/**
* @param Edit $request
* @return View
*/
public function __invoke(Edit $request): View
{
return $this->view->make('category::admin.create-edit', $this->editAction->run($request));
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
use LaraBB\Category\Actions\Admin\IndexAction;
/**
* Class OverviewHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class IndexHandler extends Controller
{
/**
* @param IndexAction $indexAction
* @param Factory $view
*/
public function __construct(
private readonly IndexAction $indexAction,
private readonly Factory $view
) {
}
/**
* @return View
*/
public function __invoke(): View
{
return $this->view->make('category::admin.index', $this->indexAction->run());
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use LaraBB\Category\Actions\Admin\StoreAction;
use LaraBB\Category\UI\Web\Requests\Store;
/**
* Class StoreHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class StoreHandler extends Controller
{
/**
* StoreHandler constructor.
* @param StoreAction $storeAction
*/
public function __construct(private readonly StoreAction $storeAction)
{
}
/**
* @param Store $request
* @return RedirectResponse
*/
public function __invoke(Store $request): RedirectResponse
{
return $this->storeAction->run($request) ? $request->success() : $request->failed();
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use LaraBB\Category\Actions\Admin\UpdateAction;
use LaraBB\Category\UI\Web\Requests\Update;
/**
* Class UpdateHandler
* @package LaraBB\Category\UI\Web\Handlers\Admin
*/
class UpdateHandler extends Controller
{
/**
* UpdateHandler constructor.
* @param UpdateAction $updateAction
*/
public function __construct(private readonly UpdateAction $updateAction)
{
}
/**
* @param Update $request
* @return RedirectResponse
*/
public function __invoke(Update $request): RedirectResponse
{
return $this->updateAction->run($request) ? $request->success() : $request->failed();
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
use LaraBB\Category\Actions\IndexAction;
use LaraBB\Category\UI\Web\Requests\Index;
/**
* Class IndexHandler
* @package LaraBB\Category\UI\Web\Handlers
*/
class IndexHandler extends Controller
{
/**
* IndexHandler constructor.
* @param IndexAction $indexAction
* @param Factory $view
*/
public function __construct(
private readonly IndexAction $indexAction,
private readonly Factory $view
) {
}
/**
* @param Index $request
* @return View
*/
public function __invoke(Index $request): View
{
return $this->view->make('category::index', $this->indexAction->run($request));
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace LaraBB\Category\UI\Web\Handlers;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\Factory;
use LaraBB\Category\Actions\ShowAction;
use LaraBB\Category\UI\Web\Requests\Show;
/**
* Class CategoryHandler
* @package LaraBB\Category\UI\Web\Handlers
*/
class ShowHandler extends Controller
{
/**
* CategoryHandler constructor.
* @param ShowAction $showAction
* @param Factory $view
*/
public function __construct(
private readonly ShowAction $showAction,
private readonly Factory $view
) {
}
/**
* @param Show $request
* @param $slug
* @return View|RedirectResponse
*/
public function __invoke(Show $request, $slug): View|RedirectResponse
{
return $this->view->make('category::show', $this->showAction->run($request));
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\RedirectResponse;
use LaraBB\Application\Traits\Request;
/**
* Class Destroy
* @package LaraBB\Category\UI\Web\Requests
*/
class Destroy extends FormRequest
{
use Request;
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return string[]
*/
public function rules(): array
{
return $this->getRules('categories.uuid');
}
/**
* @return array|string[]
*/
public function messages(): array
{
return $this->getMessages('categories.uuid');
}
/**
* @return RedirectResponse
*/
public function success(): RedirectResponse
{
return redirect()->route('admin.forums')->with([
'success' => 'Die Kategorie wurde erfolgreich gelöscht.',
'alert-options' => 'aside'
]);
}
/**
* @return RedirectResponse
*/
public function failed(): RedirectResponse
{
return redirect()->route('admin.forums')->with([
'error' => 'Die Kategorie konnte aufgrund einer technischen Störung nicht gelöscht werden.',
]);
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
use LaraBB\Application\Traits\Request;
/**
* Class Edit
* @package LaraBB\Category\UI\Web\Requests
*/
class Edit extends FormRequest
{
use Request;
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return array
*/
public function rules(): array
{
return $this->getRules('categories.uuid');
}
/**
* @return array
*/
public function messages(): array
{
return $this->getMessages('categories.uuid');
}
/**
* @param null $keys
* @return array
*/
public function all($keys = null): array
{
$data = parent::all($keys);
$data['uuid'] = $this->route('uuid');
return $data;
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
/**
* Class Index
* @package LaraBB\Category\UI\Web\Requests
*/
class Index extends FormRequest
{
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return array
*/
public function rules(): array
{
return [];
}
/**
* @return array
*/
public function messages(): array
{
return [];
}
}

View File

@ -0,0 +1,51 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
use LaraBB\Application\Traits\Request;
/**
* Class Show
* @package LaraBB\Category\UI\Web\Requests
*/
class Show extends FormRequest
{
use Request;
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return array
*/
public function rules(): array
{
return $this->getRules('categories.slug');
}
/**
* @return array
*/
public function messages(): array
{
return $this->getMessages('categories.slug');
}
/**
* @param null $keys
* @return array
*/
public function all($keys = null): array
{
$data = parent::all($keys);
$data['slug'] = $this->route('slug');
return $data;
}
}

View File

@ -0,0 +1,61 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\RedirectResponse;
use LaraBB\Application\Traits\Request;
/**
* Class Store
* @package LaraBB\Category\UI\Web\Requests
*/
class Store extends FormRequest
{
use Request;
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return array
*/
public function rules(): array
{
return $this->getRules('categories', ['uuid']);
}
/**
* @return array
*/
public function messages(): array
{
return $this->getMessages('categories', ['uuid']);
}
/**
* @return RedirectResponse
*/
public function success(): RedirectResponse
{
return redirect()->route('admin.forums')->with([
'success' => 'Die Kategorie wurde erfolgreich erstellt.',
'alert-options' => 'aside'
]);
}
/**
* @return RedirectResponse
*/
public function failed(): RedirectResponse
{
return redirect()->route('admin.forums.category.create')->with([
'error' => 'Die Kategorie konnte aufgrund einer technischen Störung nicht erstellt werden.',
]);
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace LaraBB\Category\UI\Web\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\RedirectResponse;
/**
* Class Update
* @package LaraBB\Category\UI\Web\Requests
*/
class Update extends FormRequest
{
/**
* @return bool
*/
public function authorize(): bool
{
return true;
}
/**
* @return array
*/
public function rules(): array
{
return [
'uuid' => 'required|uuid|exists:categories,uuid',
'title' => 'required|max:255',
'slug' => 'required|max:255'
];
}
/**
* @return array
*/
public function messages(): array
{
return [
'uuid.required' => 'Es wurde keine UUID übergeben.',
'uuid.uuid' => 'Die übergebene UUID ist ungültig.',
'uuid.exists' => 'Die zu bearbeitende Kategorie existiert nicht.',
'title.required' => 'Bitte geben Sie eine Bezeichnung an!',
'title.max' => 'Die angegebene Bezeichnung ist zu lang (max. :max Zeichen).',
'slug.required' => 'Bitte geben Sie eine URL an!',
'slug.max' => 'Die angegebene URL ist zu lang (max. :max Zeichen).'
];
}
/**
* @return RedirectResponse
*/
public function success(): RedirectResponse
{
return redirect()->route('admin.forums')->with([
'success' => 'Die Kategorie wurde erfolgreich bearbeitet.',
'alert-options' => 'aside'
]);
}
/**
* @return RedirectResponse
*/
public function failed(): RedirectResponse
{
return redirect()->route('admin.forums.category.edit', [$this->post('uuid')])->with([
'error' => 'Die Kategorie konnte aufgrund einer technischen Störung nicht bearbeitet werden.',
]);
}
}

View File

@ -0,0 +1,53 @@
@extends('admin::Layouts.master')
@section('content')
<div class="container-fluid pt-4">
@include('partials.messages')
<form action="{{ route('admin.forums.category.' . (isset($category) ? 'update' : 'store')) }}" method="post">
@csrf
<input type="hidden" name="uuid" id="uuid" value="{{ $category->uuid ?? '' }}">
<div class="row">
<div class="col-12 col-md-6">
<label for="title" class="required">Bezeichnung:</label>
<input id="title" name="title" class="form-control @error('title') is-invalid @enderror" value="{{ old('title', $category->title ?? '') }}">
</div>
<div class="col-12 col-md-6">
<label for="slug" class="required">URL:</label>
<div class="input-group">
<div class="input-group-text">{{ env('APP_FURL') }}/category/</div>
<input id="slug" name="slug" class="form-control @error('slug') is-invalid @enderror" value="{{ old('slug', $category->slug ?? '') }}" readonly>
<button type="button" class="btn btn-outline-secondary js-edit-slug">
<span class="fas fa-fw fa-edit"></span>
</button>
</div>
</div>
<div class="col-12 col-sm-3 col-md-2 col-lg-2 col-xl-1 mt-3">
<button class="btn btn-primary btn-block">
<span class="fas fa-fw fa-save"></span> Speichern
</button>
</div>
</div>
</form>
</div>
@stop
@section('pagejs')
<script>
$('#title').on('keyup', function() {
let $this = $(this);
if($(this).val().length > 0) {
delay(function() {
$.get('{{ route('slug') }}/' + $this.val(), function($return) {
$('#slug').val($return.slug);
});
}, 200);
} else {
$('#slug').val('');
}
});
$('.js-edit-slug').on('click', function() {
let $readonly = $(this).parents('.input-group').find('.form-control').prop('readonly');
$(this).parents('.input-group').find('.form-control').prop('readonly', !$readonly);
$(this).find('.fas').toggleClass('fa-edit fa-check');
});
</script>
@stop

View File

@ -0,0 +1,69 @@
@php /** @var LaraBB\Forum\Models\Forum $forum */ @endphp
@extends('admin::Layouts.master')
@section('content')
<div class="container-fluid py-4">
@include('partials.messages')
@include('partials.button', ['context' => 'primary', 'href' => 'admin.forums.category.create', 'parameters' => [], 'icon' => 'plus', 'label' => 'Neue Kategorie erstellen'])
@include('partials.button', ['context' => 'primary', 'href' => 'admin.forums.create', 'parameters' => [], 'icon' => 'plus', 'label' => 'Neues Forum erstellen'])
<div class="d-none d-lg-flex mt-4 py-2">
<div class="col-12 col-lg-9 font-weight-bold">Forum</div>
<div class="col-12 col-lg-1 font-weight-bold text-center">Themen</div>
<div class="col-12 col-lg-1 font-weight-bold text-center">Beiträge</div>
</div>
@forelse($categories as $category)
<div class="d-flex hover align-items-center{{ $loop->last && $category->forums->isEmpty() ? ' mb-3' : '' }}">
<div class="col-12 col-lg-11 font-weight-bold">
<a href="{{ route('admin.forums.category.edit', [$category->uuid]) }}">{{ $category->title }}</a>
</div>
<div class="col-12 col-lg-1 text-right">
<form action="{{ route('admin.forums.category.destroy') }}" method="post" class="delete" data-message="Wollen Sie diese Kategorie wirklich löschen?">
@csrf
<input type="hidden" name="uuid" value="{{ $category->uuid }}">
<button class="btn">
<span class="far fa-fw fa-trash-alt"></span>
</button>
</form>
</div>
</div>
@forelse($category->forums as $forum)
<div class="d-flex hover align-items-center{{ $loop->last ? ' mb-3' : '' }}">
<div class="col-12 col-lg-9">
<a href="{{ route('admin.forums.edit', [$forum->uuid]) }}">
<span class="fw-lighter"></span> {{ $forum->title }}
</a>
</div>
<div class="col-12 col-lg-1 text-center">
{{ $forum->thread_count }}
</div>
<div class="col-12 col-lg-1 text-center">
{{ $forum->posting_count }}
</div>
<div class="col-12 col-lg-1 text-right">
<form action="{{ route('admin.forums.destroy') }}" method="post" class="delete" data-message="Wollen Sie dieses Forum wirklich löschen?">
@csrf
<input type="hidden" name="uuid" value="{{ $forum->uuid }}">
<button class="btn">
<span class="far fa-fw fa-trash-alt"></span>
</button>
</form>
</div>
</div>
@if(!$loop->last) <hr class="my-0"> @endif
@empty
<div class="row mb-3">
<div class="col-12 text-center">
Es sind keine Foren in dieser Kategorie vorhanden.
</div>
</div>
@endforelse
@empty
<div class="row mb-3">
<div class="col-12 text-center">
Es sind keine Kategorien in der Datenbank vorhanden.
</div>
</div>
@endforelse
@include('partials.button', ['context' => 'primary', 'href' => 'admin.forums.category.create', 'parameters' => [], 'icon' => 'plus', 'label' => 'Neue Kategorie erstellen'])
@include('partials.button', ['context' => 'primary', 'href' => 'admin.forums.create', 'parameters' => [], 'icon' => 'plus', 'label' => 'Neues Forum erstellen'])
</div>
@stop

View File

@ -0,0 +1,23 @@
@php
use LaraBB\Category\Models\Category;
use LaraBB\Forum\Models\Forum;
/** @var Category $category */
/** @var Forum $forum */
@endphp
@extends('layouts.master')
@section('content')
@include('partials.messages')
@foreach($categories as $category)
<div class="card mb-5 shadow-sm">
<x-molecule.breadcrumb :items="[
['href' => 'category', 'parameters' => [$category->slug], 'label' => $category->title, 'mobile' => true],
]" />
<div class="card-body p-0">
@foreach($category->forums as $forum)
<x-molecule.thread-or-forum :forum="$forum" :loop="$loop" />
@endforeach
</div>
</div>
@endforeach
@stop

View File

@ -0,0 +1,27 @@
@php
use LaraBB\Category\Models\Category;
use LaraBB\Forum\Models\Forum;
/** @var Category $category */
/** @var Forum $forum */
@endphp
@extends('layouts.master')
@section('content')
<x-atomic.card>
<x-molecule.breadcrumb :items="[
['href' => 'index', 'icon' => 'home', 'mobile' => true],
['label' => $category->title, 'mobile' => true]
]"/>
<div class="card-body p-0">
@forelse($category->forums as $forum)
<x-molecule.thread-or-forum :forum="$forum" :loop="$loop"/>
@empty
<div class="row hover align-items-center">
<div class="col text-center">
@lang('There are no forums in this category.')
</div>
</div>
@endforelse
</div>
</x-atomic.card>
@stop

View File

@ -0,0 +1,35 @@
<?php
use LaraBB\Admin\Middleware\CheckAdmin;
use LaraBB\Category\UI\Web\Handlers\Admin\CreateHandler;
use LaraBB\Category\UI\Web\Handlers\Admin\DestroyHandler;
use LaraBB\Category\UI\Web\Handlers\Admin\EditHandler;
use LaraBB\Category\UI\Web\Handlers\Admin\StoreHandler;
use LaraBB\Category\UI\Web\Handlers\Admin\UpdateHandler;
use LaraBB\Category\UI\Web\Handlers\IndexHandler;
use LaraBB\Category\UI\Web\Handlers\Admin\IndexHandler as AdminIndexHandler;
use LaraBB\Category\UI\Web\Handlers\ShowHandler;
Route::group([], function() {
Route::get('/', IndexHandler::class)->name('index');
Route::get('category/{slug}', ShowHandler::class)->name('category');
});
Route::group([
'middleware' => [
'auth',
CheckAdmin::class
],
'prefix' => 'admin/forums'
], function() {
Route::get('/', AdminIndexHandler::class)->name('admin.forums');
Route::group([
'prefix' => 'categories'
], function() {
Route::get('create', CreateHandler::class)->name('admin.forums.category.create');
Route::post('store', StoreHandler::class)->name('admin.forums.category.store');
Route::get('edit/{uuid}', EditHandler::class)->name('admin.forums.category.edit');
Route::post('update', UpdateHandler::class)->name('admin.forums.category.update');
Route::post('destroy', DestroyHandler::class)->name('admin.forums.category.destroy');
});
});

View File

@ -0,0 +1,7 @@
<?php
Route::group([
'middleware' => [
'web'
]
], __DIR__ . '/UI/Web/routes.php');

View File

@ -0,0 +1,62 @@
<?php
namespace LaraBB\Forum\Actions\Admin;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Group\Models\Group;
use LaraBB\Group\Tasks\FindTask as FindGroupTask;
use LaraBB\User\Models\User;
/**
* Class CreateAction
* @package LaraBB\Forum\Actions\Admin
*/
class CreateAction
{
/**
* CreateAction constructor.
* @param FindGroupTask $findGroupTask
* @param FindCategoryTask $findCategoryTask
*/
public function __construct(
private readonly FindGroupTask $findGroupTask,
private readonly FindCategoryTask $findCategoryTask
) {
}
/**
* @return array
*/
#[ArrayShape([
'categories' => "array|\Illuminate\Database\Eloquent\Collection",
'users' => "mixed",
'groups' => "array|\Illuminate\Database\Eloquent\Collection",
'active' => "string"
])]
public function run(): array
{
$users = collect();
$groups = $this->findGroupTask->all(['users']);
$groups->map(function ($group) use ($users) {
/** @var Group $group */
$group->users->map(function ($user) use ($users) {
/** @var User $user */
if (!$users->contains('uuid', $user->uuid)) {
$users->push($user);
}
});
$group->unsetRelation('users');
});
return [
'categories' => $this->findCategoryTask->all(),
'users' => $users,
'groups' => $groups,
'active' => 'forums',
];
}
}

View File

@ -0,0 +1,70 @@
<?php
namespace LaraBB\Forum\Actions\Admin;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Forum\Tasks\Forum\FindTask as FindForumTask;
use LaraBB\Category\Tasks\FindTask as FindCategoryTask;
use LaraBB\Forum\UI\Web\Requests\Edit;
use LaraBB\Group\Models\Group;
use LaraBB\Group\Tasks\FindTask as FindGroupTask;
use LaraBB\User\Models\User;
/**
* Class EditAction
* @package LaraBB\Forum\Actions\Admin
*/
class EditAction
{
/**
* EditAction constructor.
* @param FindCategoryTask $findCategoryTask
* @param FindForumTask $findForumTask
* @param FindGroupTask $findGroupTask
*/
public function __construct(
private readonly FindCategoryTask $findCategoryTask,
private readonly FindForumTask $findForumTask,
private readonly FindGroupTask $findGroupTask
) {
}
/**
* @param Edit $request
* @return array
*/
#[ArrayShape([
'forum' => "\LaraBB\Forum\Models\Forum",
'categories' => "array|\Illuminate\Database\Eloquent\Collection",
'users' => "mixed",
'groups' => "array|\Illuminate\Database\Eloquent\Collection",
'active' => "string"
])]
public function run(Edit $request): array
{
$users = collect();
$groups = $this->findGroupTask->all(['users']);
$groups->map(function ($group) use ($users) {
/** @var Group $group */
$group->users->map(function ($user) use ($users) {
/** @var User $user */
if (!$users->contains('uuid', $user->uuid)) {
$users->push($user);
}
});
$group->unsetRelation('users');
});
return [
'forum' => $this->findForumTask->byUuid($request->route('uuid'), ['users', 'permissions']),
'categories' => $this->findCategoryTask->all(),
'users' => $users,
'groups' => $groups,
'active' => 'forums',
];
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace LaraBB\Forum\Actions\Admin;
use LaraBB\Forum\Tasks\Forum\FindTask as FindForumTask;
use JetBrains\PhpStorm\ArrayShape;
/**
* Class OverviewAction
* @package LaraBB\Forum\Actions\Admin
*/
class IndexAction
{
/**
* OverviewAction constructor.
* @param FindForumTask $findForumTask
*/
public function __construct(private readonly FindForumTask $findForumTask)
{
}
/**
* @return array
*/
#[ArrayShape([
'forums' => "\Illuminate\Database\Eloquent\Collection|\LaraBB\Forum\Models\Forum|null",
'active' => "string"
])]
public function run(): array
{
return [
'forums' => $this->findForumTask->all(),
'active' => 'forums'
];
}
}

View File

@ -0,0 +1,130 @@
<?php
namespace LaraBB\Forum\Actions\Admin;
use Illuminate\Database\Connection;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Forum\Tasks\Forum\StoreTask as StoreForumTask;
use LaraBB\Forum\Tasks\Permission\StoreTask as StoreForumPermissionTask;
use LaraBB\Forum\Tasks\User\StoreTask as StoreForumUserTask;
use LaraBB\Forum\Models\Forum;
use LaraBB\Forum\UI\Web\Requests\Store;
use Ramsey\Uuid\Uuid;
use Throwable;
/**
* Class StoreAction
* @package LaraBB\Forum\Actions\Admin
*/
class StoreAction
{
/**
* StoreAction constructor.
* @param StoreForumTask $storeForumTask
* @param StoreForumPermissionTask $storeForumPermissionTask
* @param StoreForumUserTask $storeForumUserTask
* @param Connection $connection
*/
public function __construct(
private readonly StoreForumTask $storeForumTask,
private readonly StoreForumPermissionTask $storeForumPermissionTask,
private readonly StoreForumUserTask $storeForumUserTask,
private readonly Connection $connection
) {
}
/**
* @param Store $request
* @return bool
*/
public function run(Store $request): bool
{
try {
$this->connection->transaction(function() use($request) {
$forum = $this->storeForumTask->run($this->prepareForumData($request));
$this->storeForumPermissionTask->run($forum, $this->prepareForumPermissionData($forum, $request));
$this->storeForumUserTask->run($forum, $this->prepareForumUsersData($request));
});
} catch(Throwable $t) {
return false;
}
return true;
}
/**
* @param Store $request
* @return array
*/
#[ArrayShape([
'category_uuid' => "array|null|string",
'created_uuid' => "mixed",
'updated_uuid' => "mixed",
'title' => "array|null|string",
'description' => "array|null|string",
'slug' => "array|null|string"
])]
private function prepareForumData(Store $request): array
{
return [
'category_uuid' => $request->post('category'),
'created_uuid' => $request->user()->uuid,
'updated_uuid' => $request->user()->uuid,
'title' => $request->post('title'),
'description' => $request->post('description'),
'slug' => $request->post('slug'),
];
}
/**
* @param Forum $forum
* @param Store $request
* @return array|false
*/
private function prepareForumPermissionData(Forum $forum, Store $request): bool|array
{
if (!$request->has('permissions')) {
return [];
}
$permissions = [];
foreach ($request->post('permissions') as $groupUuid => $groupPermissions) {
$permissions[] = [
'created_uuid' => $request->user()->uuid,
'updated_uuid' => $request->user()->uuid,
'group_uuid' => $groupUuid,
'forum_uuid' => $forum->uuid,
'show_forum' => $groupPermissions['show_forum'] ?? 0,
'show_threads' => $groupPermissions['show_threads'] ?? 0,
'show_posts' => $groupPermissions['show_posts'] ?? 0,
'create_threads' => $groupPermissions['create_threads'] ?? 0,
'create_posts' => $groupPermissions['create_posts'] ?? 0,
'edit_threads' => $groupPermissions['edit_threads'] ?? 0,
'edit_posts' => $groupPermissions['edit_posts'] ?? 0,
'delete_threads' => $groupPermissions['delete_threads'] ?? 0,
'delete_posts' => $groupPermissions['delete_posts'] ?? 0
];
}
return $permissions;
}
private function prepareForumUsersData(Store $request): array
{
$return = [];
foreach($request->post('users') as $user) {
$return[$user] = [
'uuid' => Uuid::uuid4(),
'created_at' => now(),
'created_uuid' => $request->user()->uuid,
'updated_at' => now(),
'updated_uuid' => $request->user()->uuid
];
}
return $return;
}
}

View File

@ -0,0 +1,144 @@
<?php
namespace LaraBB\Forum\Actions\Admin;
use Illuminate\Database\Connection;
use JetBrains\PhpStorm\ArrayShape;
use LaraBB\Forum\Tasks\Forum\FindTask as FindForumTask;
use LaraBB\Forum\Tasks\Forum\UpdateTask as UpdateForumTask;
use LaraBB\Forum\Tasks\Permission\UpdateTask as UpdateForumPermissionTask;
use LaraBB\Forum\Tasks\User\UpdateTask as UpdateForumUserTask;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Forum\UI\Web\Requests\Update;
use Ramsey\Uuid\Uuid;
use Throwable;
/**
* Class UpdateAction
* @package LaraBB\Forum\Actions\Admin
*/
class UpdateAction
{
/**
* UpdateAction constructor.
* @param FindForumTask $findForumTask
* @param UpdateForumTask $updateForumTask
* @param UpdateForumPermissionTask $updateForumPermissionTask
* @param UpdateForumUserTask $updateForumUserTask
* @param Connection $connection
*/
public function __construct(
private readonly FindForumTask $findForumTask,
private readonly UpdateForumTask $updateForumTask,
private readonly UpdateForumPermissionTask $updateForumPermissionTask,
private readonly UpdateForumUserTask $updateForumUserTask,
private readonly Connection $connection
) {
}
/**
* @param Update $request
* @return bool
*/
public function run(Update $request): bool
{
$forum = $this->findForumTask->byUuid($request->post('uuid'), [
'users',
'permissions'
]);
try {
$this->connection->transaction(function() use($forum, $request) {
$this->updateForumPermissionTask->run($forum->permissions, $this->prepareForumPermissionData($forum->permissions, $request));
$this->updateForumUserTask->run($forum, $this->prepareForumUsersData($request));
$this->updateForumTask->run($forum, $this->prepareForumData($request));
});
} catch(Throwable $t) {
return false;
}
return true;
}
/**
* @param Update $request
* @return array
*/
#[ArrayShape([
'category_uuid' => "array|null|string",
'updated_uuid' => "mixed",
'title' => "array|null|string",
'description' => "array|null|string",
'slug' => "array|null|string"
])]
private function prepareForumData(Update $request): array
{
return [
'category_uuid' => $request->post('category'),
'updated_uuid' => $request->user()->uuid,
'title' => $request->post('title'),
'description' => $request->post('description'),
'slug' => $request->post('slug')
];
}
/**
* @param Collection $forumPermissions
* @param Update $request
* @return array
*/
private function prepareForumPermissionData(Collection $forumPermissions, Update $request): array
{
if (!$request->has('permissions')) {
return [];
}
$permissions = [];
foreach ($request->post('permissions') as $groupUuid => $groupPermissions) {
$permissionUuid = $forumPermissions->where('group_uuid', $groupUuid)->first()->uuid;
$permissions[$permissionUuid] = [
'updated_uuid' => $request->user()->uuid,
'show_forum' => $groupPermissions['show_forum'] ?? 0,
'show_threads' => $groupPermissions['show_threads'] ?? 0,
'show_posts' => $groupPermissions['show_posts'] ?? 0,
'create_threads' => $groupPermissions['create_threads'] ?? 0,
'create_posts' => $groupPermissions['create_posts'] ?? 0,
'edit_threads' => $groupPermissions['edit_threads'] ?? 0,
'edit_posts' => $groupPermissions['edit_posts'] ?? 0,
'delete_threads' => $groupPermissions['delete_threads'] ?? 0,
'delete_posts' => $groupPermissions['delete_posts'] ?? 0
];
}
return $permissions;
}
/**
* @param Update $request
* @return array
*/
private function prepareForumUsersData(Update $request): array
{
if(!$request->has('users')) {
return [];
}
$return = [];
foreach($request->post('users') as $user) {
$return[$user] = [
'uuid' => Uuid::uuid4(),
'created_at' => now(),
'created_uuid' => $request->user()->uuid,
'updated_at' => now(),
'updated_uuid' => $request->user()->uuid
];
}
return $return;
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace LaraBB\Forum\Actions;
use LaraBB\Forum\UI\Web\Requests\Show;
use LaraBB\Thread\Models\Thread;
/**
* Class IndexAction
* @package LaraBB\Forum\Actions
*/
class IndexAction
{
public function __construct()
{
}
/**
* @param Show $request
* @return array
*/
public function run(Show $request): array
{
$request->forum->threads = $request->forum->threads->filter(function(Thread $thread) use($request) {
if($thread->groups->isEmpty() && $thread->users->isEmpty()) {
return true;
}
return $thread->groups->min('priority') <= $request->user()->groups->max('priority') || $thread->users->contains('uuid', $request->user()->uuid);
});
return [
'forum' => $request->forum
];
}
}

View File

@ -0,0 +1,41 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateForumsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('forums', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->index('uuid');
$table->uuid('category_uuid')->index('category_uuid');
$table->dateTime('created_at');
$table->uuid('created_uuid')->index('created_uuid');
$table->dateTime('updated_at');
$table->uuid('updated_uuid')->index('updated_uuid');
$table->string('title', 255);
$table->string('description', 255)->nullable();
$table->string('slug', 255)->index('slug');
$table->integer('thread_count')->default(0);
$table->integer('posting_count')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('forums');
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateForumsHasUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('forums_has_users', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->index('uuid');
$table->dateTime('created_at');
$table->uuid('created_uuid')->index('created_uuid');
$table->dateTime('updated_at');
$table->uuid('updated_uuid')->index('updated_uuid');
$table->uuid('forum_uuid')->index('forum_uuid');
$table->uuid('user_uuid')->index('user_uuid');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('forums_has_users');
}
}

View File

@ -0,0 +1,46 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateGroupsHasForumsPermissionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('forums_has_group_permissions', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->index('uuid');
$table->dateTime('created_at');
$table->uuid('created_uuid')->index('created_uuid');
$table->dateTime('updated_at');
$table->uuid('updated_uuid')->index('updated_uuid');
$table->uuid('group_uuid')->index('group_uuid');
$table->uuid('forum_uuid')->index('forum_uuid');
$table->boolean('show_forum')->default(0);
$table->boolean('show_threads')->default(0);
$table->boolean('show_posts')->default(0);
$table->boolean('create_threads')->default(0);
$table->boolean('create_posts')->default(0);
$table->boolean('edit_threads')->default(0);
$table->boolean('edit_posts')->default(0);
$table->boolean('delete_threads')->default(0);
$table->boolean('delete_posts')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('groups_has_forums_permissions');
}
}

View File

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddLastpostToForumsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('forums', function (Blueprint $table) {
$table->uuid('lastpost_uuid')->after('category_uuid')->index('lastpost_uuid')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('forums', function (Blueprint $table) {
$table->dropColumn('lastpost_uuid');
});
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateForumsHasPrefixesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('forums_has_prefixes', function (Blueprint $table) {
$table->id();
$table->uuid('uuid')->index('uuid');
$table->dateTime('created_at');
$table->uuid('created_uuid')->index('created_uuid');
$table->dateTime('updated_at');
$table->uuid('updated_uuid')->index('updated_uuid');
$table->uuid('forum_uuid')->index('forum_uuid');
$table->uuid('prefix_uuid')->index('prefix_uuid');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('forums_has_prefixes');
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace LaraBB\Forum\Models;
use App\Traits\Uuid;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use LaraBB\Category\Models\Category;
use LaraBB\Post\Models\Post;
use LaraBB\Settings\Models\Prefix;
use LaraBB\Thread\Models\Thread;
use LaraBB\User\Models\User;
/**
* Class Forum
*
* @property int $id
* @property string $uuid
* @property string $category_uuid
* @property Carbon $created_at
* @property string $created_uuid
* @property Carbon $updated_at
* @property string $updated_uuid
* @property Carbon $lastpost_at
* @property string $lastpost_uuid
* @property string $title
* @property string $description
* @property string $slug
* @property integer $thread_count
* @property integer $posting_count
* @property Category $category
* @property Collection $permissions
* @property Collection $users
* @property Collection $threads
* @property Post $lastpost
* @property Collection $prefixes
*
* @package LaraBB\Forum\Models
*/
class Forum extends Model
{
use Uuid;
/**
* @var string
*/
protected $table = 'forums';
/**
* @var string
*/
protected $primaryKey = 'uuid';
/**
* @return BelongsTo
*/
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_uuid', 'uuid');
}
/**
* @return HasMany
*/
public function permissions(): HasMany
{
return $this->hasMany(Permission::class, 'forum_uuid', 'uuid');
}
/**
* @return BelongsToMany
*/
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'forums_has_users', 'forum_uuid', 'user_uuid')->withTimestamps();
}
/**
* @return HasMany
*/
public function threads(): HasMany
{
return $this->hasMany(Thread::class, 'forum_uuid', 'uuid');
}
/**
* @return BelongsTo
*/
public function lastpost(): BelongsTo
{
return $this->belongsTo(Post::class, 'lastpost_uuid', 'uuid');
}
/**
* @return BelongsToMany
*/
public function prefixes(): BelongsToMany
{
return $this->belongsToMany(Prefix::class, 'forums_has_prefixes', 'forum_uuid', 'prefix_uuid');
}
}

View File

@ -0,0 +1,67 @@
<?php
namespace LaraBB\Forum\Models;
use App\Traits\Uuid;
use App\Traits\Who;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
/**
* Class Permission
*
* @property int $id
* @property string $uuid
* @property Carbon $created_at
* @property string $created_uuid
* @property Carbon $updated_at
* @property string $updated_uuid
* @property string $group_uuid
* @property string $forum_uuid
* @property boolean $show_forum
* @property boolean $show_threads
* @property boolean $show_posts
* @property boolean $create_threads
* @property boolean $create_posts
* @property boolean $edit_threads
* @property boolean $edit_posts
* @property boolean $delete_threads
* @property boolean $delete_posts
*
* @package LaraBB\Forum\Models
*/
class Permission extends Model
{
use Uuid;
use Who;
/**
* @var string
*/
protected $table = 'forums_has_group_permissions';
/**
* @var string
*/
protected $primaryKey = 'uuid';
/**
* @var string[]
*/
protected $fillable = [
'uuid',
'created_at',
'created_uuid',
'updated_at',
'updated_uuid',
'group_uuid',
'forum_uuid',
'show_forum',
'show_threads',
'show_posts',
'create_threads',
'create_posts',
'edit_threads',
'edit_posts',
'delete_threads',
'delete_posts'
];
}

View File

@ -0,0 +1,21 @@
<?php
namespace LaraBB\Forum;
use App\Providers\BaseServiceProvider;
/**
* Class ServiceProvider
* @package LaraBB\Category
*/
class ServiceProvider extends BaseServiceProvider
{
/**
* @var string
*/
protected string $modulePath = __DIR__;
/**
* @var string
*/
protected string $moduleKey = 'forum';
}

View File

@ -0,0 +1,50 @@
<?php
namespace LaraBB\Forum\Tasks\Forum;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Forum\Models\Forum;
/**
* Class GetForumTask
* @package LaraBB\Forum\Tasks
*/
class FindTask
{
/**
* GetForumTask constructor.
* @param Forum $forum
*/
public function __construct(private readonly Forum $forum)
{
}
/**
* @param array $with
* @return Collection|array
*/
public function all(array $with = []): Collection|array
{
return $this->forum->with($with)->get();
}
/**
* @param string $uuid
* @param array $with
* @return Forum
*/
public function byUuid(string $uuid, array $with = []): Forum
{
return $this->forum->query()->with($with)->where('uuid', $uuid)->get()->first();
}
/**
* @param string $slug
* @param array $with
* @return Forum
*/
public function bySlug(string $slug, array $with = []): Forum
{
return $this->forum->query()->with($with)->where('slug', $slug)->get()->first();
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace LaraBB\Forum\Tasks\Forum;
use LaraBB\Forum\Models\Forum;
/**
* Class StoreForumTask
* @package LaraBB\Forum\Tasks
*/
class StoreTask
{
/**
* StoreForumTask constructor.
* @param Forum $forum
*/
public function __construct(private readonly Forum $forum)
{
}
/**
* @param array $data
* @return Forum
*/
public function run(array $data): Forum
{
$this->forum->category_uuid = $data['category_uuid'];
$this->forum->created_uuid = $data['created_uuid'];
$this->forum->updated_uuid = $data['updated_uuid'];
$this->forum->title = $data['title'];
$this->forum->description = $data['description'];
$this->forum->slug = $data['slug'];
$this->forum->save();
return $this->forum;
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace LaraBB\Forum\Tasks\Forum;
use LaraBB\Forum\Models\Forum;
/**
* Class UpdateForum
* @package LaraBB\Forum\Tasks
*/
class UpdateTask
{
/**
* @param Forum $forum
* @param $data
* @return bool
*/
public function run(Forum $forum, $data): bool
{
$forum->updated_uuid = $data['updated_uuid'] ?? $forum->updated_uuid;
$forum->lastpost_uuid = $data['lastpost_uuid'] ?? $forum->lastpost_uuid;
$forum->category_uuid = $data['category_uuid'] ?? $forum->category_uuid;
$forum->title = $data['title'] ?? $forum->title;
$forum->description = $data['description'] ?? $forum->description;
$forum->slug = $data['slug'] ?? $forum->slug;
$forum->thread_count = $data['thread_count'] ?? $forum->thread_count;
$forum->posting_count = $data['posting_count'] ?? $forum->posting_count;
return $forum->save();
}
}

View File

@ -0,0 +1,23 @@
<?php
namespace LaraBB\Forum\Tasks\Permission;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Forum\Models\Forum;
/**
* Class StoreForumPermissionsTask
* @package LaraBB\Forum\Tasks
*/
class StoreTask
{
/**
* @param Forum $forum
* @param $data
* @return bool|Collection
*/
public function run(Forum $forum, $data): Collection|bool
{
return empty($data) ? true : $forum->permissions()->createMany($data);
}
}

View File

@ -0,0 +1,39 @@
<?php
namespace LaraBB\Forum\Tasks\Permission;
use Illuminate\Database\Eloquent\Collection;
use LaraBB\Forum\Models\Permission;
/**
* Class UpdateForumPermissionsTask
* @package LaraBB\Forum\Tasks
*/
class UpdateTask
{
/**
* @param Collection $permissions
* @param $data
* @return bool
*/
public function run(Collection $permissions, $data): bool
{
if(empty($data)) return true;
$permissions->map(function (Permission $permission) use ($data) {
$permission->updated_uuid = $data[$permission->uuid]['updated_uuid'] ?? $permission->updated_uuid;
$permission->show_forum = $data[$permission->uuid]['show_forum'] ?? $permission->show_forum;
$permission->show_threads = $data[$permission->uuid]['show_threads'] ?? $permission->show_threads;
$permission->show_posts = $data[$permission->uuid]['show_posts'] ?? $permission->show_posts;
$permission->create_threads = $data[$permission->uuid]['create_threads'] ?? $permission->create_threads;
$permission->create_posts = $data[$permission->uuid]['create_posts'] ?? $permission->create_posts;
$permission->edit_threads = $data[$permission->uuid]['edit_threads'] ?? $permission->edit_threads;
$permission->edit_posts = $data[$permission->uuid]['edit_posts'] ?? $permission->edit_posts;
$permission->delete_threads = $data[$permission->uuid]['delete_threads'] ?? $permission->delete_threads;
$permission->delete_posts = $data[$permission->uuid]['delete_posts'] ?? $permission->delete_posts;
$permission->save();
});
return true;
}
}

View File

@ -0,0 +1,26 @@
<?php
namespace LaraBB\Forum\Tasks\User;
use LaraBB\Forum\Models\Forum;
/**
* Class StoreForumUsersTask
* @package LaraBB\Forum\Tasks
*/
class StoreTask
{
/**
* @param Forum $forum
* @param array $data
* @return bool
*/
public function run(Forum $forum, array $data): bool
{
if(empty($data)) return true;
$forum->users()->attach($data);
return true;
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace LaraBB\Forum\Tasks\User;
use LaraBB\Forum\Models\Forum;
/**
* Class UpdateForumUsersTask
* @package LaraBB\Forum\Tasks
*/
class UpdateTask
{
/**
* @param Forum $forum
* @param array $data
* @return bool
*/
public function run(Forum $forum, array $data): bool
{
if(empty($data)) return true;
$forum->users()->detach();
$forum->users()->attach($data);
return true;
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use LaraBB\Forum\Actions\Admin\CreateAction;
/**
* Class CreateHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class CreateHandler extends Controller
{
/**
* CreateHandler constructor.
* @param CreateAction $createAction
* @param Factory $view
*/
public function __construct(
private readonly CreateAction $createAction,
private readonly Factory $view
) {
}
/**
* @return View
*/
public function __invoke(): View
{
return $this->view->make('forum::admin.create-edit', $this->createAction->run());
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
/**
* Class DestroyHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class DestroyHandler extends Controller
{
/**
*
*/
public function __invoke()
{
// TODO: Implement __invoke() method.
}
}

View File

@ -0,0 +1,37 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
use LaraBB\Forum\Actions\Admin\EditAction;
use LaraBB\Forum\UI\Web\Requests\Edit;
/**
* Class EditHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class EditHandler extends Controller
{
/**
* EditHandler constructor.
* @param EditAction $editAction
* @param Factory $view
*/
public function __construct(
private readonly EditAction $editAction,
private readonly Factory $view
) {
}
/**
* @param Edit $request
* @return View
*/
public function __invoke(Edit $request): View
{
return $this->view->make('forum::admin.create-edit', $this->editAction->run($request));
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use LaraBB\Forum\Actions\Admin\IndexAction;
/**
* Class OverviewHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class IndexHandler extends Controller
{
/**
* OverviewHandler constructor.
* @param IndexAction $indexAction
* @param Factory $view
*/
public function __construct(
private readonly IndexAction $indexAction,
private readonly Factory $view
) {
}
/**
* @return View
*/
public function __invoke(): View
{
return $this->view->make('forum::admin.index', $this->indexAction->run());
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use LaraBB\Forum\Actions\Admin\StoreAction;
use LaraBB\Forum\UI\Web\Requests\Store;
/**
* Class StoreHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class StoreHandler extends Controller
{
/**
* StoreHandler constructor.
* @param StoreAction $storeAction
*/
public function __construct(private readonly StoreAction $storeAction)
{
}
/**
* @param Store $request
* @return RedirectResponse
*/
public function __invoke(Store $request): RedirectResponse
{
return $this->storeAction->run($request) ? $request->success() : $request->failed();
}
}

View File

@ -0,0 +1,29 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\RedirectResponse;
use LaraBB\Forum\Actions\Admin\UpdateAction;
use LaraBB\Forum\UI\Web\Requests\Update;
/**
* Class UpdateHandler
* @package LaraBB\Forum\UI\Web\Handlers\Admin
*/
class UpdateHandler extends Controller
{
public function __construct(private readonly UpdateAction $updateAction)
{
}
/**
* @param Update $request
* @return RedirectResponse
*/
public function __invoke(Update $request): RedirectResponse
{
return $this->updateAction->run($request) ? $request->success() : $request->failed();
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers;
use App\Http\Controllers\Controller;
/**
* Class ForumHandler
* @package LaraBB\Forum\UI\Web\Handlers
*/
class ForumHandler extends Controller
{
/**
*
*/
public function __invoke()
{
// TODO: Implement __invoke() method.
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace LaraBB\Forum\UI\Web\Handlers;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\View\View;
use Illuminate\View\Factory;
use LaraBB\Forum\Actions\IndexAction;
use LaraBB\Forum\UI\Web\Requests\Show;
/**
* Class IndexHandler
* @package LaraBB\Forum\UI\Web\Handlers
*/
class IndexHandler extends Controller
{
/**
* IndexHandler constructor.
* @param IndexAction $indexAction
* @param Factory $view
*/
public function __construct(
private readonly IndexAction $indexAction,
private readonly Factory $view
) {
}
/**
* @param Show $request
* @param $slug
* @return View
*/
public function __invoke(Show $request, $slug): View
{
return $this->view->make('forum::index', $this->indexAction->run($request));
}
}

Some files were not shown because too many files have changed in this diff Show More