initial commit
This commit is contained in:
commit
1e1aa7d461
215 changed files with 35140 additions and 0 deletions
51
app/Console/Commands/CreateUser.php
Normal file
51
app/Console/Commands/CreateUser.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class CreateUser extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'user:create {username} {password} {--admin}';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Create a user';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$username = $this->argument('username');
|
||||
$password = $this->argument('password');
|
||||
|
||||
$role = 'user';
|
||||
if ($this->option('admin')) {
|
||||
$role = 'admin';
|
||||
}
|
||||
|
||||
User::create([
|
||||
'username' => $username,
|
||||
'password' => Hash::make($password),
|
||||
'role' => $role
|
||||
]);
|
||||
|
||||
$this->info('Created');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
39
app/Console/Kernel.php
Normal file
39
app/Console/Kernel.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
}
|
||||
}
|
||||
41
app/Exceptions/Handler.php
Normal file
41
app/Exceptions/Handler.php
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
44
app/Http/Controllers/Auth/SessionController.php
Normal file
44
app/Http/Controllers/Auth/SessionController.php
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Requests\Auth\LoginRequest;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class SessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handle an incoming authentication request.
|
||||
*
|
||||
* @param \App\Http\Requests\Auth\LoginRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(LoginRequest $request)
|
||||
{
|
||||
$request->authenticate();
|
||||
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an authenticated session.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
40
app/Http/Controllers/CharacterController.php
Normal file
40
app/Http/Controllers/CharacterController.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Character;
|
||||
use App\Http\Requests\CharacterRequest;
|
||||
|
||||
class CharacterController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('character.list', [
|
||||
'items' => Character::with('professions')->orderBy('name')->get(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(Character $character)
|
||||
{
|
||||
return view('character.show', [
|
||||
'character' => $character
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$this->authorize('create', Character::class);
|
||||
|
||||
return view('character.create');
|
||||
}
|
||||
|
||||
public function destroy(Character $character)
|
||||
{
|
||||
$this->authorize('delete', $character);
|
||||
|
||||
$character->delete();
|
||||
|
||||
return redirect()->back()
|
||||
->with(['success' => "<strong>{$character->name}</strong> was deleted!"]);
|
||||
}
|
||||
}
|
||||
63
app/Http/Controllers/CharacterProfessionController.php
Normal file
63
app/Http/Controllers/CharacterProfessionController.php
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Character;
|
||||
use App\Models\Profession;
|
||||
use App\Models\Recipe;
|
||||
use App\Models\CharacterProfession;
|
||||
use App\Http\Requests\CharacterProfessionRequest;
|
||||
use App\Jobs\ImportProfession;
|
||||
|
||||
class CharacterProfessionController extends Controller
|
||||
{
|
||||
public function show(Character $character, Profession $profession)
|
||||
{
|
||||
$ch_prof = CharacterProfession::where('character_id', $character->id)
|
||||
->where('profession_id', $profession->id)
|
||||
->with(['character', 'recipes.craft', 'recipes.category'])
|
||||
->firstOrFail();
|
||||
|
||||
return view('character.profession.show', [
|
||||
'ch_prof' => $ch_prof,
|
||||
]);
|
||||
}
|
||||
|
||||
public function create(Character $character)
|
||||
{
|
||||
$this->authorize('import_profession', $character);
|
||||
|
||||
return view('character.profession.create', [
|
||||
'character' => $character
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Character $character, CharacterProfessionRequest $request)
|
||||
{
|
||||
$this->authorize('import_profession', $character);
|
||||
|
||||
$request->validated();
|
||||
|
||||
$data = json_decode($request->input('data'));
|
||||
|
||||
try {
|
||||
ImportProfession::dispatch($character, $data);
|
||||
} catch(\App\ProfessionImport\Exception $e) {
|
||||
return redirect()->back()->with('error', $e->getMessage());
|
||||
}
|
||||
return redirect()->back()->with('success', 'Profession imported!');
|
||||
}
|
||||
|
||||
public function destroy(Character $character, Profession $profession)
|
||||
{
|
||||
$ch_prof = CharacterProfession::where('character_id', $character->id)
|
||||
->where('profession_id', $profession->id)->firstOrFail();
|
||||
|
||||
$this->authorize('delete', $ch_prof);
|
||||
|
||||
$ch_prof->delete();
|
||||
|
||||
return redirect()->back()
|
||||
->with(['success' => "<strong>Profession</strong> was deleted!"]);
|
||||
}
|
||||
}
|
||||
13
app/Http/Controllers/Controller.php
Normal file
13
app/Http/Controllers/Controller.php
Normal 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;
|
||||
}
|
||||
38
app/Http/Controllers/RecipeController.php
Normal file
38
app/Http/Controllers/RecipeController.php
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Recipe;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class RecipeController extends Controller
|
||||
{
|
||||
/**
|
||||
* List all recipies
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('recipe.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a recipe
|
||||
*/
|
||||
public function show(Recipe $recipe)
|
||||
{
|
||||
$recipe->load([
|
||||
'reagents' => function($q) {
|
||||
$q->orderBy('name');
|
||||
},
|
||||
'crafters' => function($q) {
|
||||
$q->orderBy('name');
|
||||
}
|
||||
]);
|
||||
|
||||
return view('recipe.show', [
|
||||
'recipe' => $recipe
|
||||
]);
|
||||
}
|
||||
}
|
||||
37
app/Http/Controllers/UserController.php
Normal file
37
app/Http/Controllers/UserController.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\UserRequest;
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('user.index', [
|
||||
'user' => Auth::user(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(Request $request)
|
||||
{
|
||||
return view('user.edit', [
|
||||
'user' => Auth::user(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function update(UserRequest $request)
|
||||
{
|
||||
$data = $request->validated();
|
||||
|
||||
$user = $request->user();
|
||||
$user->password = Hash::make($data['password']);
|
||||
$user->save();
|
||||
|
||||
return redirect()->route('user.index')
|
||||
->with('success', 'Password was updated');
|
||||
}
|
||||
}
|
||||
66
app/Http/Kernel.php
Normal file
66
app/Http/Kernel.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\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
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::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,
|
||||
];
|
||||
}
|
||||
121
app/Http/Livewire/Form/CreateCharacterForm.php
Normal file
121
app/Http/Livewire/Form/CreateCharacterForm.php
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Form;
|
||||
|
||||
use App\Models\Character;
|
||||
use App\Warcraft\Classes;
|
||||
use App\Warcraft\Races;
|
||||
|
||||
use Livewire\Component;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
class CreateCharacterForm extends Component
|
||||
{
|
||||
use AuthorizesRequests;
|
||||
|
||||
/**
|
||||
* Character's name
|
||||
*/
|
||||
public string $name = '';
|
||||
|
||||
/**
|
||||
* Character's level
|
||||
*/
|
||||
public string $level = '70';
|
||||
|
||||
/**
|
||||
* All possible classes
|
||||
*/
|
||||
public $classes;
|
||||
|
||||
/**
|
||||
* Character's class
|
||||
*/
|
||||
public string $class = '';
|
||||
|
||||
/**
|
||||
* All possible races
|
||||
*/
|
||||
public $races;
|
||||
|
||||
/**
|
||||
* Character's race
|
||||
*/
|
||||
public string $race = '';
|
||||
|
||||
/**
|
||||
* All posible genders
|
||||
*/
|
||||
public $genders = [
|
||||
'M' => 'Male',
|
||||
'F' => 'Female'
|
||||
];
|
||||
|
||||
/**
|
||||
* Character gender
|
||||
*/
|
||||
public $gender = 'M';
|
||||
|
||||
/**
|
||||
* Validation rules
|
||||
*/
|
||||
protected $rules = [
|
||||
'name' => 'required|alpha|min:2|max:12|unique:characters,name',
|
||||
'level' => 'required|integer|min:1|max:70',
|
||||
'gender' => 'required|in:M,F',
|
||||
'race' => 'required',
|
||||
'class' => 'required'
|
||||
];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->races = (new Races)->alliance();
|
||||
$rules['race'] = 'required|in:' . $this->races->keys()->join(',');
|
||||
|
||||
$this->race = $this->races->keys()->first();
|
||||
$this->updatedRace($this->race);
|
||||
}
|
||||
|
||||
public function updated($propertyName)
|
||||
{
|
||||
$this->validateOnly($propertyName);
|
||||
}
|
||||
|
||||
public function updatedRace($race)
|
||||
{
|
||||
// Update classes list for this race.
|
||||
$this->classes = (new Classes)->race($this->race);
|
||||
|
||||
// Update validation rules
|
||||
$rules['class'] = 'required|in:' . $this->classes->keys()->join(',');
|
||||
|
||||
// if this race can not be the selected class.
|
||||
// select the first one.
|
||||
if (!$this->classes->has($this->class)) {
|
||||
$this->class = $this->classes->keys()->first();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the character
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$this->authorize('create', Character::class);
|
||||
|
||||
$data = $this->validate();
|
||||
|
||||
$user = auth()->user();
|
||||
$character = $user->characters()->create($data);
|
||||
|
||||
// Livewire redirect() does not have "with" method.
|
||||
// so we call session()->flash() directly instead.
|
||||
session()->flash('success', "<strong>{$character->name}</strong> was created!");
|
||||
return redirect()->route('user.index');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.form.character');
|
||||
}
|
||||
}
|
||||
84
app/Http/Livewire/Recipes.php
Normal file
84
app/Http/Livewire/Recipes.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Profession;
|
||||
use App\Models\Recipe;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Livewire\Component;
|
||||
|
||||
class Recipes extends Component
|
||||
{
|
||||
use Traits\WithPagination;
|
||||
|
||||
protected $queryString = [
|
||||
'name' => ['except' => ''],
|
||||
'crafter' => ['except' => ''],
|
||||
'profession' => ['except' => '']
|
||||
];
|
||||
|
||||
/**
|
||||
* Filter by name
|
||||
*/
|
||||
public string $name = '';
|
||||
|
||||
/**
|
||||
* Filter by profession
|
||||
*/
|
||||
public string $profession = '';
|
||||
|
||||
/**
|
||||
* Filter by crafter
|
||||
*/
|
||||
public string $crafter = '';
|
||||
|
||||
/**
|
||||
* List of all professions.
|
||||
*/
|
||||
public array $profession_options = [];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
// Build professions select list.
|
||||
$options = Profession::all()->mapWithKeys(function ($item) {
|
||||
return [Str::lower($item['name']) => $item['name']];
|
||||
});
|
||||
|
||||
$this->profession_options = collect(['' => '-- Profession --'])
|
||||
->merge($options)
|
||||
->toArray();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$query = Recipe::select('recipes.*')
|
||||
->join('items', 'items.id', '=', 'recipes.item_id')
|
||||
->orderBy('items.name');
|
||||
|
||||
// Filter by name
|
||||
if (strlen($this->name) >= 3) {
|
||||
$query->whereHas('craft', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . $this->name . '%');
|
||||
});
|
||||
}
|
||||
|
||||
// Filter by profession
|
||||
if (strlen($this->profession)) {
|
||||
$query->whereHas('profession', function ($q) {
|
||||
$q->where('name', Str::ucfirst($this->profession));
|
||||
});
|
||||
}
|
||||
|
||||
// Filter by crafter
|
||||
if (strlen($this->crafter) >= 3) {
|
||||
$query->whereHas('crafters', function ($q) {
|
||||
$q->where('name', 'LIKE', '%' . $this->crafter . '%');
|
||||
});
|
||||
}
|
||||
|
||||
return view('livewire.recipes', [
|
||||
'recipes' => $query->paginate($this->perPage)
|
||||
]);
|
||||
}
|
||||
}
|
||||
15
app/Http/Livewire/Traits/WithPagination.php
Normal file
15
app/Http/Livewire/Traits/WithPagination.php
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Livewire\Traits;
|
||||
|
||||
trait WithPagination
|
||||
{
|
||||
use \Livewire\WithPagination;
|
||||
|
||||
public $perPage = 15;
|
||||
|
||||
public function paginationView()
|
||||
{
|
||||
return 'pagination.default';
|
||||
}
|
||||
}
|
||||
21
app/Http/Middleware/Authenticate.php
Normal file
21
app/Http/Middleware/Authenticate.php
Normal 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('auth.login');
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal 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
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal 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
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
32
app/Http/Middleware/RedirectIfAuthenticated.php
Normal 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 $next
|
||||
* @param string|null ...$guards
|
||||
* @return mixed
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal 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
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal 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
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
app/Http/Middleware/TrustProxies.php
Normal file
23
app/Http/Middleware/TrustProxies.php
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array|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;
|
||||
}
|
||||
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal 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
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
95
app/Http/Requests/Auth/LoginRequest.php
Normal file
95
app/Http/Requests/Auth/LoginRequest.php
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Auth;
|
||||
|
||||
use Illuminate\Auth\Events\Lockout;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class LoginRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'username' => 'required|string',
|
||||
'password' => 'required|string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to authenticate the request's credentials.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function authenticate()
|
||||
{
|
||||
$this->ensureIsNotRateLimited();
|
||||
|
||||
$credentials = $this->only('username', 'password');
|
||||
$remember = $this->boolean('remember');
|
||||
|
||||
if (!Auth::attempt($credentials, $remember)) {
|
||||
RateLimiter::hit($this->throttleKey());
|
||||
throw ValidationException::withMessages([
|
||||
'username' => __('auth.failed'),
|
||||
]);
|
||||
}
|
||||
|
||||
RateLimiter::clear($this->throttleKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the login request is not rate limited.
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function ensureIsNotRateLimited()
|
||||
{
|
||||
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event(new Lockout($this));
|
||||
|
||||
$seconds = RateLimiter::availableIn($this->throttleKey());
|
||||
|
||||
throw ValidationException::withMessages([
|
||||
'email' => trans('auth.throttle', [
|
||||
'seconds' => $seconds,
|
||||
'minutes' => ceil($seconds / 60),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rate limiting throttle key for the request.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function throttleKey()
|
||||
{
|
||||
return Str::lower($this->input('email')).'|'.$this->ip();
|
||||
}
|
||||
}
|
||||
30
app/Http/Requests/CharacterProfessionRequest.php
Normal file
30
app/Http/Requests/CharacterProfessionRequest.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CharacterProfessionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'data' => 'required|json',
|
||||
];
|
||||
}
|
||||
}
|
||||
31
app/Http/Requests/UserRequest.php
Normal file
31
app/Http/Requests/UserRequest.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UserRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->user() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'current_password' => 'required|current_password',
|
||||
'password' => 'required|min:8|confirmed',
|
||||
];
|
||||
}
|
||||
}
|
||||
141
app/Jobs/ImportProfession.php
Normal file
141
app/Jobs/ImportProfession.php
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
|
||||
namespace App\Jobs;
|
||||
|
||||
use App\Models\Character;
|
||||
use App\Models\Profession;
|
||||
use App\Models\CharacterProfession;
|
||||
use App\Models\Recipe;
|
||||
use App\Models\RecipeCategory;
|
||||
use App\Models\Item;
|
||||
use App\ProfessionImport\Exception;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldBeUnique;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ImportProfession implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Character profession the operation should act upon,
|
||||
*/
|
||||
protected CharacterProfession $ch_prof;
|
||||
|
||||
/**
|
||||
* Array of recipe data to the imported.
|
||||
*/
|
||||
protected array $recipes;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Character $character, $data)
|
||||
{
|
||||
// Validate character name first.
|
||||
if ($character->name !== $data->player) {
|
||||
$message = sprintf('Wrong character: %s expected %s', $data->player, $character->name);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
// Validate profession
|
||||
$profession = Profession::slug($data->profession->name)->first();
|
||||
if (!$profession) {
|
||||
$message = sprintf('Invalid profession: %s', $data->profession->name);
|
||||
throw new Exception($message);
|
||||
}
|
||||
|
||||
// Create/update profession for player.
|
||||
$this->ch_prof = $character->professions()->updateOrCreate(['profession_id' => $profession->id], [
|
||||
'skill' => $data->profession->level,
|
||||
]);
|
||||
|
||||
$this->recipes = $data->profession->recipes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
DB::transaction(function () {
|
||||
|
||||
$this->processItems();
|
||||
|
||||
$profession = $this->ch_prof->profession;
|
||||
|
||||
$recipes = [];
|
||||
|
||||
// Create recipes for character
|
||||
foreach($this->recipes as $data) {
|
||||
|
||||
$item = Item::where('name', $data->name)->firstOrFail();
|
||||
|
||||
$recipes[] = $this->getRecipe($item, $profession, $data)->id;
|
||||
}
|
||||
|
||||
// Update attached recipes.
|
||||
$this->ch_prof->recipes()->sync($recipes);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
protected function processItems()
|
||||
{
|
||||
$items = collect($this->recipes);
|
||||
$nested = $items->pluck('items')->flatten()->unique('name');
|
||||
$items = $items->except('items')
|
||||
->merge($nested)
|
||||
->map(function ($item, $key) {
|
||||
return [
|
||||
'name' => $item->name,
|
||||
'slug' => Str::slug($item->name),
|
||||
'external_id' => $item->id,
|
||||
'texture' => isset($item->texture) ? $item->texture : null,
|
||||
'color' => isset($item->color) ? (string) Str::of($item->color)->replace('#', '')->limit(8) : null,
|
||||
];
|
||||
})
|
||||
->sort('name')
|
||||
->toArray();
|
||||
|
||||
Item::upsert($items, [ 'external_id', 'name', 'slug' ], [ 'external_id', 'texture', 'color' ]);
|
||||
}
|
||||
|
||||
protected function getRecipe(Item $item, Profession $profession, $data)
|
||||
{
|
||||
$recipe = $profession->recipes()
|
||||
->where('item_id', $item->id)
|
||||
->first();
|
||||
|
||||
// Create if not found.
|
||||
if ($recipe === null) {
|
||||
|
||||
$category = RecipeCategory::firstOrCreate([ 'name' => $data->categorie ]);
|
||||
|
||||
$recipe = $profession->recipes()->create([
|
||||
'item_id' => $item->id,
|
||||
'category_id' => $category->id
|
||||
]);
|
||||
|
||||
// Reagents
|
||||
foreach($data->items as $reagent) {
|
||||
$item = Item::where('name', $reagent->name)->firstOrFail();
|
||||
$recipe->reagents()->attach($item, [ 'quantity' => $reagent->num ]);
|
||||
}
|
||||
|
||||
$recipe->push();
|
||||
}
|
||||
|
||||
return $recipe;
|
||||
}
|
||||
}
|
||||
86
app/Models/Character.php
Normal file
86
app/Models/Character.php
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Character extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'level',
|
||||
'race',
|
||||
'gender',
|
||||
'class'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
{
|
||||
return $this->slug($value)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the character's name.
|
||||
*
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setNameAttribute($value)
|
||||
{
|
||||
$this->attributes['name'] = Str::ucfirst($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the user that owns this character.
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the character's professions.
|
||||
*/
|
||||
public function professions()
|
||||
{
|
||||
return $this->hasMany(CharacterProfession::class);
|
||||
}
|
||||
|
||||
public function scopeSlug($q, $name)
|
||||
{
|
||||
return $q->where('name', Str::ucfirst($name));
|
||||
}
|
||||
|
||||
public function getSlugAttribute()
|
||||
{
|
||||
return Str::lower($this->name);
|
||||
}
|
||||
}
|
||||
88
app/Models/CharacterProfession.php
Normal file
88
app/Models/CharacterProfession.php
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CharacterProfession extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'character_id',
|
||||
'profession_id',
|
||||
'skill',
|
||||
];
|
||||
|
||||
/**
|
||||
* The relationships that should always be loaded.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $with = [
|
||||
'profession'
|
||||
];
|
||||
|
||||
/**
|
||||
* The accessors to append to the model's array form.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $appends = [ 'name' ];
|
||||
|
||||
/**
|
||||
* Relation to the actual profession data.
|
||||
*/
|
||||
public function profession()
|
||||
{
|
||||
return $this->belongsTo(Profession::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the character that has this profession.
|
||||
*/
|
||||
public function character()
|
||||
{
|
||||
return $this->belongsTo(Character::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the character's recipes for this profession.
|
||||
*/
|
||||
public function recipes()
|
||||
{
|
||||
return $this->belongsToMany(Recipe::class,
|
||||
'character_profession_recipe', 'ch_prof_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Learn a recipe for this character and profession.
|
||||
*/
|
||||
public function learn(Recipe $recipe)
|
||||
{
|
||||
return $this->recipes()->save($recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get profession name.
|
||||
*/
|
||||
public function getNameAttribute() : string
|
||||
{
|
||||
return $this->profession->name;
|
||||
}
|
||||
|
||||
public function getSlugAttribute() : string
|
||||
{
|
||||
return $this->profession->slug;
|
||||
}
|
||||
}
|
||||
47
app/Models/Item.php
Normal file
47
app/Models/Item.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Item extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'external_id',
|
||||
'texture',
|
||||
'color'
|
||||
];
|
||||
|
||||
protected static function boot() {
|
||||
parent::boot();
|
||||
|
||||
static::creating(function ($item) {
|
||||
$item->slug = Str::slug($item->name);
|
||||
});
|
||||
}
|
||||
|
||||
public function recipe()
|
||||
{
|
||||
return $this->belongsTo(Recipe::class, 'id');
|
||||
}
|
||||
|
||||
public function getQuantityAttribute()
|
||||
{
|
||||
if ($this->pivot) {
|
||||
return $this->pivot->quantity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
62
app/Models/Profession.php
Normal file
62
app/Models/Profession.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Profession extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
{
|
||||
return $this->slug($value)->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all characters with this profession.
|
||||
*/
|
||||
public function characters()
|
||||
{
|
||||
return $this->belongsToMany(Character::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* What recipes this profession has
|
||||
*/
|
||||
public function recipes()
|
||||
{
|
||||
return $this->hasMany(Recipe::class);
|
||||
}
|
||||
|
||||
public function scopeSlug($q, $name)
|
||||
{
|
||||
return $q->where('name', Str::ucfirst($name));
|
||||
}
|
||||
|
||||
public function getSlugAttribute()
|
||||
{
|
||||
return Str::lower($this->name);
|
||||
}
|
||||
}
|
||||
131
app/Models/Recipe.php
Normal file
131
app/Models/Recipe.php
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Staudenmeir\EloquentHasManyDeep\HasRelationships as HasDeepRelation;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Recipe extends Model
|
||||
{
|
||||
use Traits\HasSlug;
|
||||
use HasDeepRelation;
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The relationships that should always be loaded.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $with = [
|
||||
'profession',
|
||||
'craft'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'profession_id',
|
||||
'category_id',
|
||||
'item_id'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the model for a bound value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param string|null $field
|
||||
* @return \Illuminate\Database\Eloquent\Model|null
|
||||
*/
|
||||
public function resolveRouteBinding($value, $field = null)
|
||||
{
|
||||
return $this->whereHas('craft', function ($q) use ($value) {
|
||||
$q->where('slug', $value);
|
||||
})->firstOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* What profession this item belongs to.
|
||||
*/
|
||||
public function profession()
|
||||
{
|
||||
return $this->belongsTo(Profession::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* What category this recipe belongs to.
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(RecipeCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* What item this recipe crafts.
|
||||
*/
|
||||
public function craft()
|
||||
{
|
||||
return $this->belongsTo(Item::class, 'item_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all character professions.
|
||||
*/
|
||||
public function character_profession()
|
||||
{
|
||||
return $this->belongsToMany(CharacterProfession::class,
|
||||
'character_profession_recipe', null, 'ch_prof_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all character that can craft this recipe.
|
||||
*/
|
||||
public function crafters()
|
||||
{
|
||||
return $this->hasManyDeep(Character::class,
|
||||
['character_profession_recipe', CharacterProfession::class],
|
||||
[ null, 'id', 'id'],
|
||||
[ null,'ch_prof_id', 'character_id']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* What reagents is needed to craft this recipe.
|
||||
*/
|
||||
public function reagents()
|
||||
{
|
||||
return $this->belongsToMany(Item::class, 'reagents')
|
||||
->withPivot('quantity');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recipe name from crafted item.
|
||||
*/
|
||||
public function getNameAttribute()
|
||||
{
|
||||
return $this->craft->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recipe slug from crafted item.
|
||||
*/
|
||||
public function getSlugAttribute()
|
||||
{
|
||||
return $this->craft->slug;
|
||||
}
|
||||
}
|
||||
27
app/Models/RecipeCategory.php
Normal file
27
app/Models/RecipeCategory.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class RecipeCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
];
|
||||
|
||||
public function recipes()
|
||||
{
|
||||
return $this->hasMany(Recipe::class, 'category_id');
|
||||
}
|
||||
}
|
||||
18
app/Models/Traits/HasSlug.php
Normal file
18
app/Models/Traits/HasSlug.php
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\Traits;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait HasSlug
|
||||
{
|
||||
public function setSlugAttribute($value)
|
||||
{
|
||||
$this->attributes['slug'] = Str::slug($value);
|
||||
}
|
||||
|
||||
public function scopeSlug($q, $value)
|
||||
{
|
||||
return $q->where('slug', Str::slug($value));
|
||||
}
|
||||
}
|
||||
48
app/Models/User.php
Normal file
48
app/Models/User.php
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'username',
|
||||
'password',
|
||||
'role'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function characters()
|
||||
{
|
||||
return $this->hasMany(Character::class);
|
||||
}
|
||||
}
|
||||
43
app/Policies/CharacterPolicy.php
Normal file
43
app/Policies/CharacterPolicy.php
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Character;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Illuminate\Auth\Access\Response;
|
||||
|
||||
class CharacterPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function create(User $user)
|
||||
{
|
||||
$limit = 8;
|
||||
|
||||
if ($user->characters->count() < $limit) {
|
||||
return Response::allow();
|
||||
}
|
||||
|
||||
$message = __('authorization.character.limit', [ 'limit' => $limit ]);
|
||||
return Response::deny($message);
|
||||
}
|
||||
|
||||
public function update(User $user, Character $character)
|
||||
{
|
||||
return $user->id === $character->user_id;
|
||||
}
|
||||
|
||||
public function delete(User $user, Character $character)
|
||||
{
|
||||
return $user->id === $character->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if use can import profession for this character.
|
||||
*/
|
||||
public function import_profession(User $user, Character $character)
|
||||
{
|
||||
return $user->id === $character->user_id;
|
||||
}
|
||||
}
|
||||
19
app/Policies/CharacterProfessionPolicy.php
Normal file
19
app/Policies/CharacterProfessionPolicy.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Character;
|
||||
use App\Models\CharacterProfession;
|
||||
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CharacterProfessionPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function delete(User $user, CharacterProfession $ch_prof)
|
||||
{
|
||||
return $user->id === $ch_prof->character->user_id;
|
||||
}
|
||||
}
|
||||
7
app/ProfessionImport/Exception.php
Normal file
7
app/ProfessionImport/Exception.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
namespace App\ProfessionImport;
|
||||
|
||||
class Exception extends \Exception
|
||||
{
|
||||
}
|
||||
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
29
app/Providers/AuthServiceProvider.php
Normal file
29
app/Providers/AuthServiceProvider.php
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The policy mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $policies = [
|
||||
'App\Models\Character' => \App\Policies\CharacterPolicy::class,
|
||||
'App\Models\CharacterProfession' => \App\Policies\CharacterProfessionPolicy::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
}
|
||||
}
|
||||
30
app/Providers/BladeServiceProvider.php
Normal file
30
app/Providers/BladeServiceProvider.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BladeServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected $components = [
|
||||
// Form
|
||||
'input' => \App\View\Components\Form\Input::class,
|
||||
'input-password' => \App\View\Components\Form\Password::class,
|
||||
'textarea' => \App\View\Components\Form\Textarea::class,
|
||||
'select' => \App\View\Components\Form\Select::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
// Register components
|
||||
foreach($this->components as $alias => $class) {
|
||||
Blade::component($alias, $class);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
app/Providers/EventServiceProvider.php
Normal file
32
app/Providers/EventServiceProvider.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event listener mappings for the application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
37
app/Providers/RouteServiceProvider.php
Normal file
37
app/Providers/RouteServiceProvider.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
use App\Models\Character;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* This is used by Laravel authentication to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
$this->routes(function () {
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
}
|
||||
10
app/View/Components/ClassIcon.php
Normal file
10
app/View/Components/ClassIcon.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class ClassIcon extends Icon
|
||||
{
|
||||
protected $prefix = 'classes';
|
||||
}
|
||||
32
app/View/Components/Form.php
Normal file
32
app/View/Components/Form.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Form extends Component
|
||||
{
|
||||
public string $method;
|
||||
|
||||
public $spoofMethod = false;
|
||||
|
||||
public function __construct($method = 'POST')
|
||||
{
|
||||
if (in_array($method, ['DELETE'])) {
|
||||
$this->spoofMethod = $method;
|
||||
$method = 'POST';
|
||||
}
|
||||
|
||||
$this->method = $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.form.form');
|
||||
}
|
||||
}
|
||||
37
app/View/Components/Form/Input.php
Normal file
37
app/View/Components/Form/Input.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Form;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Input extends Component
|
||||
{
|
||||
public string $type;
|
||||
|
||||
public ?string $id;
|
||||
|
||||
public string $name;
|
||||
|
||||
public ?string $value;
|
||||
|
||||
public string $disabled;
|
||||
|
||||
public function __construct($name, ?string $id = null, string $type = 'text', ?string $value = null, bool $disabled = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->name = $name;
|
||||
$this->value = old($name, $value);
|
||||
$this->disabled = $disabled ? 'disabled=disabled' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.form.inputs.input');
|
||||
}
|
||||
}
|
||||
11
app/View/Components/Form/Password.php
Normal file
11
app/View/Components/Form/Password.php
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Form;
|
||||
|
||||
class Password extends Input
|
||||
{
|
||||
public function __construct($name = 'password', ?string $id = null, ?string $value = null, bool $disabled = false)
|
||||
{
|
||||
parent::__construct($name, $id, 'password', $value, $disabled);
|
||||
}
|
||||
}
|
||||
37
app/View/Components/Form/Select.php
Normal file
37
app/View/Components/Form/Select.php
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Form;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Select extends Component
|
||||
{
|
||||
public ?string $id;
|
||||
|
||||
public string $name;
|
||||
|
||||
public ?string $value;
|
||||
|
||||
public string $disabled;
|
||||
|
||||
public $options;
|
||||
|
||||
public function __construct($name, $options, ?string $id = null, ?string $value = null, bool $disabled = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->value = old($name, $value);
|
||||
$this->disabled = $disabled ? 'disabled=disabled' : '';
|
||||
$this->options = $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.form.inputs.select');
|
||||
}
|
||||
}
|
||||
34
app/View/Components/Form/Textarea.php
Normal file
34
app/View/Components/Form/Textarea.php
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components\Form;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Textarea extends Component
|
||||
{
|
||||
public ?string $id;
|
||||
|
||||
public string $name;
|
||||
|
||||
public ?string $value;
|
||||
|
||||
public string $disabled;
|
||||
|
||||
public function __construct($name, ?string $id = null, ?string $value = null, bool $disabled = false)
|
||||
{
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->value = old($name, $value);
|
||||
$this->disabled = $disabled ? 'disabled=disabled' : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.form.inputs.textarea');
|
||||
}
|
||||
}
|
||||
35
app/View/Components/Icon.php
Normal file
35
app/View/Components/Icon.php
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
abstract class Icon extends Component
|
||||
{
|
||||
protected $prefix = '';
|
||||
|
||||
public $url;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$file = sprintf('%s/%s.jpg', $this->prefix, Str::lower($name));
|
||||
$this->url = Storage::disk('images')->url($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view('components.class-icon');
|
||||
}
|
||||
}
|
||||
33
app/View/Components/Layout.php
Normal file
33
app/View/Components/Layout.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Layout extends Component
|
||||
{
|
||||
/**
|
||||
* Layout script
|
||||
*/
|
||||
protected string $name;
|
||||
|
||||
/**
|
||||
* Create a new component instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($name = 'default')
|
||||
{
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|\Closure|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
return view("layouts.{$this->name}");
|
||||
}
|
||||
}
|
||||
53
app/View/Components/Notifications.php
Normal file
53
app/View/Components/Notifications.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\View\Component;
|
||||
|
||||
class Notifications extends Component
|
||||
{
|
||||
/**
|
||||
* Types of messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $types = [ 'info', 'success', 'warning', 'error' ];
|
||||
|
||||
/**
|
||||
* Position (left,center or right)
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public string $position = 'center';
|
||||
|
||||
/**
|
||||
* Type and css class mapping.
|
||||
*/
|
||||
protected $cssClasses = [
|
||||
'info' => 'info',
|
||||
'success' => 'success',
|
||||
'warning' => 'warning',
|
||||
'error' => 'danger'
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the view / contents that represent the component.
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View|string
|
||||
*/
|
||||
public function render()
|
||||
{
|
||||
$messages = [];
|
||||
|
||||
foreach($this->types as $type) {
|
||||
|
||||
if (Session::has($type)) {
|
||||
$class = $this->cssClasses[$type];
|
||||
$messages[$class] = Session::get($type);
|
||||
}
|
||||
}
|
||||
|
||||
return view('components.notifications', [ 'messages' => $messages ]);
|
||||
}
|
||||
}
|
||||
8
app/View/Components/ProfessionIcon.php
Normal file
8
app/View/Components/ProfessionIcon.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace App\View\Components;
|
||||
|
||||
class ProfessionIcon extends Icon
|
||||
{
|
||||
protected $prefix = 'professions';
|
||||
}
|
||||
81
app/Warcraft/Classes.php
Normal file
81
app/Warcraft/Classes.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace App\Warcraft;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Classes extends Collection
|
||||
{
|
||||
/**
|
||||
* Enum constants
|
||||
*/
|
||||
const WARRIOR = 'warrior';
|
||||
const PALADIN = 'paladin';
|
||||
const HUNTER = 'hunter';
|
||||
const ROGUE = 'rogue';
|
||||
const PRIEST = 'priest';
|
||||
const SHAMAN = 'shaman';
|
||||
const MAGE = 'mage';
|
||||
const WARLOCK = 'warlock';
|
||||
const DRUID = 'druid';
|
||||
|
||||
public function __construct($items = null)
|
||||
{
|
||||
if ($items === null) {
|
||||
$this->items = [
|
||||
self::WARRIOR => 'Warrior',
|
||||
self::PALADIN => 'Paladin',
|
||||
self::HUNTER => 'Hunter',
|
||||
self::ROGUE => 'Rogue',
|
||||
self::PRIEST => 'Priest',
|
||||
self::SHAMAN => 'Shaman',
|
||||
self::MAGE => 'Mage',
|
||||
self::WARLOCK => 'Warlock',
|
||||
self::DRUID => 'Druid'
|
||||
];
|
||||
} else {
|
||||
parent::__construct($items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter classes by race.
|
||||
*/
|
||||
public function race($race) : self
|
||||
{
|
||||
switch($race) {
|
||||
case Races::HUMAN :
|
||||
return $this->only(self::WARRIOR, self::PALADIN, self::ROGUE,
|
||||
self::PRIEST, self::MAGE, self::WARLOCK);
|
||||
case Races::DWARF :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::PALADIN,
|
||||
self::ROGUE, self::PRIEST);
|
||||
case Races::GNOME :
|
||||
return $this->only(self::WARRIOR, self::ROGUE, self::MAGE,
|
||||
self::WARLOCK);
|
||||
case Races::NIGHTELF :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::ROGUE,
|
||||
self::PRIEST, self::DRUID);
|
||||
case Races::DRAENEI :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::PALADIN,
|
||||
self::SHAMAN, self::PRIEST, self::MAGE);
|
||||
case Races::ORC :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::ROGUE,
|
||||
self::SHAMAN, self::WARLOCK);
|
||||
case Races::TROLL :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::ROGUE,
|
||||
self::PRIEST, self::SHAMAN, self::MAGE);
|
||||
case Races::TAUREN :
|
||||
return $this->only(self::WARRIOR, self::HUNTER, self::SHAMAN,
|
||||
self::DRUID);
|
||||
case Races::UNDEAD :
|
||||
return $this->only(self::WARRIOR, self::ROGUE, self::PRIEST,
|
||||
self::MAGE, self::WARLOCK);
|
||||
case Races::BLOODELF :
|
||||
return $this->only(self::PALADIN, self::HUNTER, self::ROGUE,
|
||||
self::PRIEST, self::MAGE, self::WARLOCK);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
90
app/Warcraft/Races.php
Normal file
90
app/Warcraft/Races.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
namespace App\Warcraft;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class Races extends Collection
|
||||
{
|
||||
/**
|
||||
* Enum constants
|
||||
*/
|
||||
const HUMAN = 'human';
|
||||
const DWARF = 'dwarf';
|
||||
const GNOME = 'gnome';
|
||||
const NIGHTELF = 'night elf';
|
||||
const DRAENEI = 'draenei';
|
||||
const ORC = 'orc';
|
||||
const TROLL = 'troll';
|
||||
const TAUREN = 'tauren';
|
||||
const UNDEAD = 'undead';
|
||||
const BLOODELF = 'blood elf';
|
||||
|
||||
public function __construct($items = null)
|
||||
{
|
||||
if ($items === null) {
|
||||
$this->items = [
|
||||
self::HUMAN => 'Human',
|
||||
self::DWARF => 'Dwarf',
|
||||
self::GNOME => 'Gnome',
|
||||
self::NIGHTELF => 'Night elf',
|
||||
self::DRAENEI => 'Draenei',
|
||||
self::ORC => 'Orc',
|
||||
self::TROLL => 'Troll',
|
||||
self::TAUREN => 'Tauren',
|
||||
self::UNDEAD => 'Undead',
|
||||
self::BLOODELF => 'Blood elf'
|
||||
];
|
||||
} else {
|
||||
parent::__construct($items);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter only alliance races
|
||||
*/
|
||||
public function alliance() : self
|
||||
{
|
||||
return $this->only(self::HUMAN, self::DWARF, self::GNOME, self::NIGHTELF, self::DRAENEI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter only alliance races
|
||||
*/
|
||||
public function horde() : self
|
||||
{
|
||||
return $this->only(self::ORC, self::TROLL, self::TAUREN, self::UNDEAD, self::BLOODELF);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter races by class.
|
||||
*/
|
||||
public function class($class) : self
|
||||
{
|
||||
switch($class) {
|
||||
case Classes::WARRIOR :
|
||||
return $this->except(self::BLOODELF);
|
||||
case Classes::PALADIN :
|
||||
return $this->only(self::HUMAN, self::DWARF, self::DRAENEI, self::BLOODELF);
|
||||
case Classes::HUNTER :
|
||||
return $this->only(self::HUMAN, self::DWARF, self::NIGHTELF, self::DRAENEI,
|
||||
self::ORC, self::TROLL, self::TAUREN, self::BLOODELF);
|
||||
case Classes::ROGUE :
|
||||
return $this->only(self::HUMAN, self::DWARF, self::NIGHTELF, self::GNOME,
|
||||
self::ORC, self::TROLL, self::UNDEAD, self::BLOODELF);
|
||||
case Classes::PRIEST :
|
||||
return $this->only(self::HUMAN, self::DWARF, self::NIGHTELF, self::DRAENEI,
|
||||
self::TROLL, self::UNDEAD, self::BLOODELF);
|
||||
case Classes::SHAMAN :
|
||||
return $this->only(self::DRAENEI, self::ORC, self::TROLL, self::TAUREN);
|
||||
case Classes::MAGE :
|
||||
return $this->only(self::HUMAN, self::GNOME, self::TROLL, self::UNDEAD, self::BLOODELF);
|
||||
case Classes::WARLOCK :
|
||||
return $this->only(self::HUMAN, self::GNOME, self::ORC, self::UNDEAD, self::BLOODELF);
|
||||
case Classes::DRUID :
|
||||
return $this->only(self::NIGHTELF, self::TAUREN);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Reference in a new issue