Compare commits
No commits in common. "main" and "old-api" have entirely different histories.
@ -1,18 +0,0 @@
|
||||
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
|
18
.env.example
18
.env.example
@ -1,16 +1,10 @@
|
||||
APP_NAME=KamilCraftAPI
|
||||
APP_ENV=local
|
||||
APP_KEY=
|
||||
APP_NAME="KamilCraft.com"
|
||||
APP_DEBUG=true
|
||||
APP_URL=http://localhost
|
||||
APP_URL=http://127.0.0.1
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=kamilcraft-api_db
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=kamilcraft-api
|
||||
DB_USERNAME=kamilcraft-api
|
||||
DB_PASSWORD=password
|
||||
|
||||
EXTERNAL_WEBSERVER_PORT=80
|
||||
CURRENT_UID=1000
|
||||
XDG_CONFIG_HOME=/tmp
|
||||
DB_DATABASE=test
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
|
5
.gitattributes
vendored
5
.gitattributes
vendored
@ -1,5 +0,0 @@
|
||||
* text=auto
|
||||
*.css linguist-vendored
|
||||
*.scss linguist-vendored
|
||||
*.js linguist-vendored
|
||||
CHANGELOG.md export-ignore
|
16
.gitignore
vendored
16
.gitignore
vendored
@ -1,15 +1,3 @@
|
||||
/.idea
|
||||
/.vscode
|
||||
/node_modules
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
/.composer
|
||||
.idea
|
||||
vendor
|
||||
.env
|
||||
.env.backup
|
||||
.phpunit.result.cache
|
||||
docker-compose.override.yml
|
||||
Homestead.json
|
||||
Homestead.yaml
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
|
14
.styleci.yml
14
.styleci.yml
@ -1,14 +0,0 @@
|
||||
php:
|
||||
preset: laravel
|
||||
version: 8
|
||||
disabled:
|
||||
- no_unused_imports
|
||||
finder:
|
||||
not-name:
|
||||
- index.php
|
||||
- server.php
|
||||
js:
|
||||
finder:
|
||||
not-name:
|
||||
- webpack.mix.js
|
||||
css: true
|
21
LICENCE
21
LICENCE
@ -1,21 +0,0 @@
|
||||
The MIT License
|
||||
|
||||
Copyright 2022 Kamil Niemczycki
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
55
README.md
55
README.md
@ -1,53 +1,22 @@
|
||||
# KamilCraftAPI
|
||||
# KamilCraftApi
|
||||
|
||||
API for kamilcraft.com projects
|
||||
|
||||
## Requirements
|
||||
## Installation
|
||||
|
||||
### Required
|
||||
|
||||
* Docker 20.10.x (Engine) or later
|
||||
* PHP 8.0 or later
|
||||
* Composer 2.3.x or later
|
||||
|
||||
### Optional
|
||||
### Installation of dependencies
|
||||
|
||||
* PHP 8.1.x or later
|
||||
* Composer 2.4.x or later
|
||||
* Nodejs 18.14.x or later
|
||||
```shell
|
||||
composer install
|
||||
```
|
||||
|
||||
## Preparation and installation
|
||||
## Launching
|
||||
|
||||
1) Copy the contents of the .env.example file into .env
|
||||
```shell
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
2) Build the image needed for Laravel and Node.js
|
||||
```shell
|
||||
docker-compose build --no-cache --pull
|
||||
```
|
||||
|
||||
3) Run the images prepared in ``docker-compose.yml``
|
||||
```shell
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
4) Install the dependencies needed for Laravel and Nodejs
|
||||
```shell
|
||||
docker-compose exec -u "$(id -u):$(id -g)" php composer install
|
||||
```
|
||||
```shell
|
||||
docker-compose run --rm -u "$(id -u):$(id -g)" npm install
|
||||
```
|
||||
|
||||
5) Key and data generation
|
||||
```shell
|
||||
docker-compose exec -u "$(id -u):$(id -g)" php php artisan key:generate
|
||||
```
|
||||
```shell
|
||||
docker-compose exec -u "$(id -u):$(id -g)" php php artisan migrate:fresh --seed
|
||||
```
|
||||
```shell
|
||||
docker-compose run --rm -u "$(id -u):$(id -g)" npm run dev
|
||||
```
|
||||
|
||||
6) Go to ``http://localhost/dashboard`` in your browser.
|
||||
```shell
|
||||
php -S localhost:80 public/index.php
|
||||
```
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
43
app/Controllers/CategoriesController.php
Normal file
43
app/Controllers/CategoriesController.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace KamilCraftApi\App\Controllers;
|
||||
|
||||
use KamilCraftApi\App\Models\Category;
|
||||
use KamilCraftApi\Request\Request;
|
||||
use KamilCraftApi\Response;
|
||||
|
||||
class CategoriesController extends Controller
|
||||
{
|
||||
private Category $category;
|
||||
|
||||
public function __construct(Request $request) {
|
||||
parent::__construct();
|
||||
$this->category = new Category($request);
|
||||
}
|
||||
|
||||
public function showWhereName(string $slug): Response
|
||||
{
|
||||
if ( ! ($category = $this->category->getCategoryWhereName($slug)) ) {
|
||||
return (new Response())->json([
|
||||
'message' => 'Not found category'
|
||||
], 404);
|
||||
}
|
||||
return (new Response())->json($category);
|
||||
}
|
||||
|
||||
public function show(int $id): Response
|
||||
{
|
||||
if ( ! ($category = $this->category->getCategory($id)) ) {
|
||||
return (new Response())->json([
|
||||
'message' => 'Not found category'
|
||||
], 404);
|
||||
}
|
||||
return (new Response())->json($category);
|
||||
}
|
||||
|
||||
public function __invoke(): Response
|
||||
{
|
||||
$categories = $this->category;
|
||||
return (new Response())->json($categories());
|
||||
}
|
||||
}
|
21
app/Controllers/Controller.php
Normal file
21
app/Controllers/Controller.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace KamilCraftApi\App\Controllers;
|
||||
|
||||
use KamilCraftApi\Interfaces\ControllerInterface;
|
||||
use KamilCraftApi\Response;
|
||||
|
||||
class Controller implements ControllerInterface
|
||||
{
|
||||
private Response $response;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->response = new Response();
|
||||
}
|
||||
|
||||
protected function response(): Response
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
}
|
17
app/Controllers/HomeController.php
Normal file
17
app/Controllers/HomeController.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace KamilCraftApi\App\Controllers;
|
||||
|
||||
use KamilCraftApi\Interfaces\ControllerInterface;
|
||||
use KamilCraftApi\Request\Request;
|
||||
use KamilCraftApi\Response;
|
||||
|
||||
class HomeController implements ControllerInterface
|
||||
{
|
||||
public function __invoke(Request $request): Response
|
||||
{
|
||||
return (new Response())->json((object)[
|
||||
'message' => 'Hello World'
|
||||
]);
|
||||
}
|
||||
}
|
39
app/Controllers/ProjectController.php
Normal file
39
app/Controllers/ProjectController.php
Normal file
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace KamilCraftApi\App\Controllers;
|
||||
|
||||
use KamilCraftApi\App\Models\Project;
|
||||
use KamilCraftApi\Response;
|
||||
|
||||
class ProjectController extends Controller
|
||||
{
|
||||
private Project $project;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->project = new Project();
|
||||
}
|
||||
|
||||
public function showWhereCategory(string $category): Response
|
||||
{
|
||||
$projects = $this->project->getProjectWhereCategory($category);
|
||||
return (new Response())->json($projects);
|
||||
}
|
||||
|
||||
public function show(int $id): Response
|
||||
{
|
||||
if ( ! ($project = $this->project->getProject($id)) ) {
|
||||
return (new Response())->json([
|
||||
'message' => 'Not found project'
|
||||
], 404);
|
||||
}
|
||||
return (new Response())->json($project);
|
||||
}
|
||||
|
||||
public function __invoke(): Response
|
||||
{
|
||||
$projects = $this->project;
|
||||
return (new Response())->json($projects());
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array<int, class-string<Throwable>>
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for 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) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Resources\CategoryResource;
|
||||
use App\Repository\Interfaces\CategoryRepository;
|
||||
use Illuminate\Support\Collection;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private CategoryRepository $categoryRepository
|
||||
) {}
|
||||
|
||||
public function index(): Collection
|
||||
{
|
||||
return $this->categoryRepository->all();
|
||||
}
|
||||
|
||||
public function showWhereSlug(string $category): CategoryResource
|
||||
{
|
||||
return $this->categoryRepository->get($category);
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Repository\Interfaces\ProjectRepository;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ProjectController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private ProjectRepository $projectRepository
|
||||
) {}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'category' => 'nullable|string|exists:categories,slug'
|
||||
]);
|
||||
$filters = [];
|
||||
if ($request->has('category') && ($category = $request->get('category')) !== '') {
|
||||
$filters['category'] = $category;
|
||||
}
|
||||
|
||||
return $this->projectRepository->all($filters);
|
||||
}
|
||||
|
||||
public function show(int $project)
|
||||
{
|
||||
return $this->projectRepository->get($project);
|
||||
}
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
|
||||
public function authenticate(Request $request)
|
||||
{
|
||||
if (Auth::check())
|
||||
return redirect()->route('admin.home');
|
||||
|
||||
$credentials = $request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required'],
|
||||
]);
|
||||
|
||||
if (Auth::attempt($credentials)) {
|
||||
$request->session()->regenerate();
|
||||
return redirect()->route('admin.home');
|
||||
}
|
||||
|
||||
return back()->withErrors([
|
||||
'email' => 'The provided credentials do not match our records.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function logout()
|
||||
{
|
||||
if (Auth::check()) {
|
||||
Auth::logout();
|
||||
}
|
||||
|
||||
return redirect()->route('admin.auth.login');
|
||||
}
|
||||
|
||||
public function login(): View|RedirectResponse
|
||||
{
|
||||
if (Auth::check())
|
||||
return redirect()->route('admin.home');
|
||||
|
||||
return view('auth.login');
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?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;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Repository\Interfaces\CategoryRepository;
|
||||
use App\Repository\Interfaces\ProjectRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AdminPanelController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private CategoryRepository $categoryRepository,
|
||||
private ProjectRepository $projectRepository
|
||||
) {
|
||||
$this->categoryRepository->auth = true;
|
||||
}
|
||||
|
||||
public function __invoke(Request $request): View
|
||||
{
|
||||
$categories = $this->categoryRepository->all();
|
||||
$projects = $this->projectRepository->all();
|
||||
|
||||
return view('dashboard.home', compact('categories', 'projects'));
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Requests\CategoryRequest;
|
||||
use App\Models\Category;
|
||||
use App\Repository\Interfaces\CategoryRepository;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class CategoryController
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private CategoryRepository $categoryRepository
|
||||
) {}
|
||||
|
||||
public function update(CategoryRequest $request, Category $category)
|
||||
{
|
||||
$validate = $request->validated();
|
||||
if ($this->categoryRepository->update($category, $validate)) {
|
||||
return back()->with('message', 'Zaktualizowano kategorię!');
|
||||
}
|
||||
|
||||
return back()->withError(['message_error', 'Wystąpił błąd podczas aktualizacji!']);
|
||||
}
|
||||
|
||||
public function store(CategoryRequest $request)
|
||||
{
|
||||
$validate = $request->validated();
|
||||
if ($category = $this->categoryRepository->create($validate)) {
|
||||
return redirect()->route('admin.category.update', ['category' => $category])->with('message', 'Utworzono kategorię!');
|
||||
}
|
||||
|
||||
return back()->withError(['message_error', 'Wystąpił błąd podczas tworzenia!']);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('dashboard.categories.create');
|
||||
}
|
||||
|
||||
public function edit(Category $category): View
|
||||
{
|
||||
return view('dashboard.categories.edit', compact('category'));
|
||||
}
|
||||
|
||||
public function delete(Category $category): View
|
||||
{
|
||||
return view('dashboard.categories.delete', compact('category'));
|
||||
}
|
||||
|
||||
public function destroy(Category $category): RedirectResponse
|
||||
{
|
||||
$name = $category->name;
|
||||
$category->delete();
|
||||
|
||||
return redirect()->route('admin.home')->with('message', 'Usunięto kategorię "'. $name .'"');
|
||||
}
|
||||
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Dashboard;
|
||||
|
||||
use App\Http\Requests\ProjectRequest;
|
||||
use App\Models\Project;
|
||||
use App\Repository\Interfaces\ProjectRepository;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class ProjectController
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private ProjectRepository $projectRepository
|
||||
) {
|
||||
$this->projectRepository->auth = true;
|
||||
}
|
||||
|
||||
public function edit(Project $project): View
|
||||
{
|
||||
return view('dashboard.projects.edit', compact('project'));
|
||||
}
|
||||
|
||||
public function update(ProjectRequest $request, Project $project): RedirectResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
if ($this->projectRepository->update($project, $validated)) {
|
||||
return back()->with('message', 'Zaktualizowano projekt!');
|
||||
}
|
||||
|
||||
return back()->withError(['message_error', 'Wystąpił błąd podczas aktualizacji!']);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('dashboard.projects.create');
|
||||
}
|
||||
|
||||
public function store(ProjectRequest $request): RedirectResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
if ($project = $this->projectRepository->create($validated)) {
|
||||
return redirect()
|
||||
->route('admin.project.update', compact('project'))
|
||||
->with('message', 'Utworzono projekt!');
|
||||
}
|
||||
|
||||
return back()->withError(['message_error', 'Wystąpił błąd podczas tworzenia!']);
|
||||
}
|
||||
|
||||
public function delete(Project $project): View
|
||||
{
|
||||
return view('dashboard.projects.delete', compact('project'));
|
||||
}
|
||||
|
||||
public function destroy(Project $project): RedirectResponse
|
||||
{
|
||||
$title = $project->title;
|
||||
$project->delete();
|
||||
return redirect()->route('admin.home')->with('message', 'Usunięto projekt "'. $title .'"');
|
||||
}
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
use App\Http\Middleware\Core;
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
|
||||
protected $middleware = [
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
Core::class
|
||||
];
|
||||
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\Illuminate\Cookie\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
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,
|
||||
];
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
|
||||
protected function redirectTo($request): ?string
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('admin.auth.login');
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Core
|
||||
{
|
||||
|
||||
public function handle(Request $request, Closure $next): mixed
|
||||
{
|
||||
return $next($request)
|
||||
->header('Access-Control-Allow-Origin', '*')
|
||||
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
|
||||
->header('Access-Control-Allow-Headers', 'Content-Type, Authorizations');
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
|
||||
public function handle(Request $request, Closure $next, ...$guards): mixed
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
|
||||
public function hosts(): array
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
|
||||
protected $proxies;
|
||||
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;
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class CategoryRequest 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 [
|
||||
'name' => 'required|string|min:3|max:25',
|
||||
'slug' => 'required|string|min:3|max:25',
|
||||
'priority' => 'required|numeric|min:0|max:10',
|
||||
'default' => 'nullable|in:yes,1,true,on',
|
||||
'visible' => 'nullable|in:yes,1,true,on'
|
||||
];
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ProjectRequest 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 [
|
||||
'title' => 'required|string|min:3|max:255',
|
||||
'author' => 'required|string|min:3|max:50',
|
||||
'categories' => 'nullable|string',
|
||||
'release_date' => 'required|date:Y-m-d',
|
||||
'update_date' => 'nullable|date:Y-m-d',
|
||||
|
||||
'image_small' => 'nullable|string',
|
||||
'image_medium' => 'nullable|string',
|
||||
'image_large' => 'nullable|string',
|
||||
|
||||
'project_url' => 'nullable|string',
|
||||
'project_version' => 'nullable|string',
|
||||
'description' => 'nullable|string',
|
||||
'visible' => 'nullable|in:yes,1,true,on'
|
||||
];
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class CategoryCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return CategoryResource::collection($this->collection);
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class CategoryResource extends JsonResource
|
||||
{
|
||||
|
||||
public static $wrap = null;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'slug' => $this->slug,
|
||||
'default' => $this->default,
|
||||
];
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\ResourceCollection;
|
||||
|
||||
class ProjectCollection extends ResourceCollection
|
||||
{
|
||||
/**
|
||||
* Transform the resource collection into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return ProjectResource::collection($this->collection);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class ProjectResource extends JsonResource
|
||||
{
|
||||
|
||||
public static $wrap = null;
|
||||
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'categories' => $this->categories,
|
||||
'author' => $this->author,
|
||||
'images' => $this->images,
|
||||
'release_date' => $this->release_date,
|
||||
'update_date' => $this->update_date,
|
||||
'project_url' => $this->project_url,
|
||||
'project_version' => $this->project_version,
|
||||
'description' => $this->description,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +1,78 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace KamilCraftApi\App\Models;
|
||||
|
||||
namespace App\Models;
|
||||
use KamilCraftApi\Request\Request;
|
||||
use KamilCraftApi\Response;
|
||||
use stdClass;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property bool $default
|
||||
* @property bool $visible
|
||||
*/
|
||||
class Category extends Model
|
||||
class Category
|
||||
{
|
||||
const JSON_PATH = ROOT_PATH . 'resources/json';
|
||||
private array $allCategory = [];
|
||||
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'name' => 'string',
|
||||
'slug' => 'string',
|
||||
'priority' => 'integer',
|
||||
'default' => 'boolean',
|
||||
'visible' => 'boolean'
|
||||
];
|
||||
|
||||
public function scopeVisibled(Builder $builder): Builder
|
||||
{
|
||||
return $builder->where(function (Builder $query) {
|
||||
$query->where('visible', true)
|
||||
->orWhere('default', true);
|
||||
});
|
||||
public function __construct(
|
||||
private Request $request
|
||||
) {
|
||||
$categories = file_get_contents(self::JSON_PATH . '/Categories.json');
|
||||
if ( $category = json_decode($categories) ) {
|
||||
$this->allCategory = $category;
|
||||
} else {
|
||||
$this->parseError();
|
||||
}
|
||||
}
|
||||
|
||||
public function getCategoryWhereName(string $slug): object|bool
|
||||
{
|
||||
if ( ( $key = array_search($slug, array_column($this->allCategory, 'slug') ) ) !== false ) {
|
||||
$category = $this->allCategory[$key];
|
||||
$category->default = $category->default ?? false;
|
||||
$category->visible = $category->visible ?? true;
|
||||
return $category;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getCategory(int $id): object|bool
|
||||
{
|
||||
if ( ( $key = array_search($id, array_column($this->allCategory, 'id') ) ) !== false ) {
|
||||
$category = $this->allCategory[$key];
|
||||
$category->default = $category->default ?? false;
|
||||
$category->visible = $category->visible ?? true;
|
||||
return $category;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private function parseError(): void
|
||||
{
|
||||
if ( $this->request->getContentType() === 'application/json' ) {
|
||||
(new Response())->json((object)[
|
||||
'message' => 'Server error'
|
||||
], 500)->render();
|
||||
} else {
|
||||
(new Response())(
|
||||
file_get_contents(ROOT_PATH . '/errors/error500.html'),
|
||||
500
|
||||
)->render();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
public function __invoke(): array
|
||||
{
|
||||
$tmp_categories = [];
|
||||
foreach ($this->allCategory as $category) {
|
||||
$tmp_category = new stdClass;
|
||||
$tmp_category->id = $category->id;
|
||||
$tmp_category->name = $category->name;
|
||||
$tmp_category->slug = $category->slug;
|
||||
$tmp_category->default = $category->default ?? false;
|
||||
$tmp_category->visible = $category->visible ?? true;
|
||||
|
||||
$tmp_categories[] = $tmp_category;
|
||||
}
|
||||
|
||||
return $tmp_categories;
|
||||
}
|
||||
}
|
||||
|
@ -1,70 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace KamilCraftApi\App\Models;
|
||||
|
||||
namespace App\Models;
|
||||
use stdClass;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
* @property string $title
|
||||
* @property array $categories
|
||||
* @property string $author
|
||||
* @property array $images
|
||||
* @property Carbon $release_date
|
||||
* @property Carbon $update_date
|
||||
* @property string $project_url
|
||||
* @property string $project_version
|
||||
* @property string $description
|
||||
*/
|
||||
class Project extends Model
|
||||
class Project
|
||||
{
|
||||
|
||||
protected $dateFormat = 'Y-m-d';
|
||||
protected $guarded = [];
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'title' => 'string',
|
||||
'categories' => 'array',
|
||||
'author' => 'string',
|
||||
'images' => 'array',
|
||||
'release_date' => 'datetime:Y-m-d',
|
||||
'update_date' => 'datetime:Y-m-d',
|
||||
'project_url' => 'string',
|
||||
'project_version' => 'string',
|
||||
'description' => 'string',
|
||||
'visible' => 'boolean'
|
||||
const JSON_PATH = ROOT_PATH . 'resources/json';
|
||||
const SHORT_PROJECT = [
|
||||
'id',
|
||||
'title',
|
||||
'image',
|
||||
'categories',
|
||||
'version'
|
||||
];
|
||||
private array $allProjects = [];
|
||||
|
||||
public function getReleaseDateAttribute($value): String
|
||||
public function __construct()
|
||||
{
|
||||
return Carbon::parse($value)->format('Y-m-d');
|
||||
$projects = file_get_contents(self::JSON_PATH . '/Projects.json');
|
||||
if ( $projects = json_decode($projects) ) {
|
||||
$this->allProjects = $projects;
|
||||
}
|
||||
}
|
||||
|
||||
public function setReleaseDateAttribute($value): void
|
||||
public function getProject(int $id): object|bool
|
||||
{
|
||||
$this->attributes['release_date'] = $value;
|
||||
if ( ( $key = array_search($id, array_column($this->allProjects, 'id')) ) !== false ) {
|
||||
return $this->allProjects[$key];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getUpdateDateAttribute($value): String|null
|
||||
public function getProjectWhereCategory(string $category): array
|
||||
{
|
||||
return Carbon::parse($value)->format('Y-m-d');
|
||||
$listWhereCategory = [];
|
||||
foreach ( array_column($this->allProjects, 'categories') as $key => $value ) {
|
||||
if ( in_array($category, $value) ) {
|
||||
$listWhereCategory[] = $this->shortProjectSchema($this->allProjects[$key]);
|
||||
}
|
||||
}
|
||||
return $listWhereCategory;
|
||||
}
|
||||
|
||||
public function setUpdateDateAttribute($value): void
|
||||
private function shortProjectSchema(object $project): object
|
||||
{
|
||||
if (!is_null($value))
|
||||
$this->attributes['update_date'] = $value;
|
||||
else
|
||||
$this->attributes['update_date'] = null;
|
||||
$tmp_project = new stdClass;
|
||||
foreach ($project as $key => $value) {
|
||||
if ( in_array($key, self::SHORT_PROJECT) ) {
|
||||
$tmp_project->{$key} = $value;
|
||||
}
|
||||
}
|
||||
$tmp_project->short_description = substr(
|
||||
explode("\n", $project->description)[0],
|
||||
0,
|
||||
255
|
||||
);
|
||||
|
||||
return $tmp_project;
|
||||
}
|
||||
|
||||
public function scopeVisibled(Builder $builder): Builder
|
||||
public function __invoke(): array
|
||||
{
|
||||
return $builder->where('visible', true);
|
||||
}
|
||||
$arr_map = [];
|
||||
foreach ($this->allProjects as $project) {
|
||||
$arr_map[] = $this->shortProjectSchema($project);
|
||||
}
|
||||
|
||||
return $arr_map;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'password',
|
||||
];
|
||||
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{}
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App\Repository\CategoryRepository;
|
||||
use App\Repository\Interfaces\CategoryRepository as CategoryRepositoryInterface;
|
||||
|
||||
class CategoryServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app
|
||||
->bind(CategoryRepositoryInterface::class, CategoryRepository::class);
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use App\Repository\Interfaces\ProjectRepository as ProjectRepositoryInterface;
|
||||
use App\Repository\ProjectRepository;
|
||||
|
||||
class ProjectServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(ProjectRepositoryInterface::class, ProjectRepository::class);
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
||||
public const HOME = '/';
|
||||
protected $namespace = 'App\\Http\\Controllers';
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
$this->configureRateLimiting();
|
||||
|
||||
$this->routes(function () {
|
||||
Route::prefix('v1')
|
||||
->middleware('api')
|
||||
->namespace($this->namespace . '\\Api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::prefix('dashboard')
|
||||
->middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Http\Resources\CategoryCollection;
|
||||
use App\Http\Resources\CategoryResource;
|
||||
use App\Models\Category;
|
||||
use App\Repository\Interfaces\CategoryRepository as CategoryRepositoryInterface;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class CategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
|
||||
public bool $auth = false;
|
||||
|
||||
public function __construct(
|
||||
private Category $category
|
||||
) {}
|
||||
|
||||
public function all(): Collection
|
||||
{
|
||||
$categories = $this->category
|
||||
->query()
|
||||
->orderby('priority', 'ASC')
|
||||
->orderby('name', 'ASC');
|
||||
|
||||
if (!$this->auth)
|
||||
$categories->visibled();
|
||||
|
||||
return (new CategoryCollection($categories->get()))->collection;
|
||||
}
|
||||
|
||||
public function get(string $slug): CategoryResource
|
||||
{
|
||||
$category = $this->category
|
||||
->query()
|
||||
->where('slug', $slug)
|
||||
->firstOrFail();
|
||||
|
||||
if (!$this->auth)
|
||||
$category->visibled();
|
||||
|
||||
return new CategoryResource($category);
|
||||
}
|
||||
|
||||
public function update(Category $category, array $data = []): bool
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
if (!$category->default && isset($data['default']) && $data['default'] === true)
|
||||
$this->unsetDefault();
|
||||
|
||||
return $category
|
||||
->update($data);
|
||||
}
|
||||
|
||||
public function create(array $data = []): Category
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
if (isset($data['default']) && $data['default'] === true)
|
||||
$this->unsetDefault();
|
||||
|
||||
return $this->category
|
||||
->query()
|
||||
->create($data);
|
||||
}
|
||||
|
||||
private function unsetDefault(): void
|
||||
{
|
||||
$this->category
|
||||
->query()
|
||||
->where('default', true)
|
||||
->first()?->update(['default' => false]);
|
||||
}
|
||||
|
||||
private function parseToArray(array $data = []): array
|
||||
{
|
||||
$toSave = [];
|
||||
|
||||
if (isset($data['name']) && !empty($data['name']))
|
||||
$toSave['name'] = $data['name'];
|
||||
if (isset($data['slug']) && !empty($data['slug']))
|
||||
$toSave['slug'] = $data['slug'];
|
||||
if (isset($data['priority']) && !is_integer($data['priority']))
|
||||
$toSave['priority'] = (int)$data['priority'];
|
||||
|
||||
if (
|
||||
isset($data['default']) &&
|
||||
in_array($data['default'], ['yes', 'on', 1, true])
|
||||
) $toSave['default'] = true;
|
||||
else $toSave['default'] = false;
|
||||
|
||||
if (
|
||||
(isset($toSave['default']) && $toSave['default'] === true) ||
|
||||
(isset($data['visible']) &&
|
||||
in_array($data['visible'], ['yes', 'on', 1, true]))
|
||||
) $toSave['visible'] = true;
|
||||
else $toSave['visible'] = false;
|
||||
|
||||
return $toSave;
|
||||
}
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository\Interfaces;
|
||||
|
||||
use App\Http\Resources\CategoryResource;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface CategoryRepository
|
||||
{
|
||||
|
||||
public function all(): Collection;
|
||||
public function get(string $slug): CategoryResource;
|
||||
public function update(Category $category, array $data = []): bool;
|
||||
public function create(array $data = []): Category;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository\Interfaces;
|
||||
|
||||
use App\Http\Resources\ProjectResource;
|
||||
use App\Models\Project;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
interface ProjectRepository
|
||||
{
|
||||
|
||||
public function all(array $filters = []): Collection;
|
||||
public function get(int $id): ProjectResource;
|
||||
public function update(Project $project, array $data = []): bool;
|
||||
public function create(array $data = []): Project;
|
||||
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Http\Resources\ProjectCollection;
|
||||
use App\Http\Resources\ProjectResource;
|
||||
use App\Models\Project;
|
||||
use App\Repository\Interfaces\ProjectRepository as ProjectRepositoryInterface;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class ProjectRepository implements ProjectRepositoryInterface
|
||||
{
|
||||
|
||||
public bool $auth = false;
|
||||
|
||||
public function __construct(
|
||||
private Project $project
|
||||
) {}
|
||||
|
||||
public function all(array $filters = []): Collection
|
||||
{
|
||||
$project = $this->project
|
||||
->query()
|
||||
->orderByDesc('release_date');
|
||||
|
||||
foreach ($filters as $filter_name => $filter_value) {
|
||||
if ($filter_name === 'category' && $filter_value !== 'all')
|
||||
$project->where('categories', 'like', '%"'. $filter_value .'"%');
|
||||
}
|
||||
|
||||
if (!$this->auth)
|
||||
$project->visibled();
|
||||
|
||||
return (new ProjectCollection($project->get()))->collection;
|
||||
}
|
||||
|
||||
public function get(int $id): ProjectResource
|
||||
{
|
||||
$project = $this->project
|
||||
->query();
|
||||
|
||||
if (!$this->auth)
|
||||
$project->visibled();
|
||||
|
||||
return new ProjectResource($project->findOrFail($id));
|
||||
}
|
||||
|
||||
public function update(Project $project, array $data = []): bool
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
|
||||
return $project
|
||||
->update($data);
|
||||
}
|
||||
|
||||
public function create(array $data = []): Project
|
||||
{
|
||||
$data = $this->parseToArray($data);
|
||||
|
||||
return $this->project
|
||||
->query()
|
||||
->create($data);
|
||||
}
|
||||
|
||||
private function parseToArray(array $data = []): array
|
||||
{
|
||||
$toSave = [];
|
||||
|
||||
if (isset($data['title']))
|
||||
$toSave['title'] = $data['title'];
|
||||
|
||||
if (isset($data['author']))
|
||||
$toSave['author'] = $data['author'];
|
||||
|
||||
$toSave['images']['small'] = $data['image_small'] ?? '';
|
||||
$toSave['images']['medium'] = $data['image_medium'] ?? '';
|
||||
$toSave['images']['large'] = $data['image_large'] ?? '';
|
||||
|
||||
if (isset($data['release_date']))
|
||||
$toSave['release_date'] = $data['release_date'];
|
||||
|
||||
if (isset($data['project_url']))
|
||||
$toSave['project_url'] = $data['project_url'];
|
||||
|
||||
if (isset($data['project_version']))
|
||||
$toSave['project_version'] = $data['project_version'];
|
||||
|
||||
if (isset($data['description']))
|
||||
$toSave['description'] = $data['description'];
|
||||
|
||||
if (isset($data['categories']) && is_array($data['categories']))
|
||||
$toSave['categories'] = $data['categories'];
|
||||
else if (isset($data['categories']) && !empty($data['categories']))
|
||||
$toSave['categories'] = explode(',', str_replace(', ', ',', $data['categories']));
|
||||
|
||||
if (isset($data['images']) && is_array($data['images']))
|
||||
$toSave['images'] = $data['images'];
|
||||
|
||||
if (isset($data['update_date']) && !empty($data['update_date']))
|
||||
$toSave['update_date'] = $data['update_date'];
|
||||
else
|
||||
$toSave['update_date'] = null;
|
||||
|
||||
if (
|
||||
isset($data['visible']) &&
|
||||
in_array($data['visible'], ['yes', 'on', 1, true])
|
||||
) $toSave['visible'] = true;
|
||||
else $toSave['visible'] = false;
|
||||
|
||||
return $toSave;
|
||||
}
|
||||
|
||||
}
|
53
artisan
53
artisan
@ -1,53 +0,0 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The Auto Loader
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Composer provides a convenient, automatically generated class loader
|
||||
| for our application. We just need to utilize it! We'll require it
|
||||
| into the script here so that we do not have to worry about the
|
||||
| loading of any of our classes manually. It's great to relax.
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/vendor/autoload.php';
|
||||
|
||||
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Artisan Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When we run the console application, the current CLI command will be
|
||||
| executed in this console and the response sent back to a terminal
|
||||
| or another output device for the developers. Here goes nothing!
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||
|
||||
$status = $kernel->handle(
|
||||
$input = new Symfony\Component\Console\Input\ArgvInput,
|
||||
new Symfony\Component\Console\Output\ConsoleOutput
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Shutdown The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Once Artisan has finished running, we will fire off the shutdown events
|
||||
| so that any final work may be done by the application before we shut
|
||||
| down the process. This is the last thing to happen to the request.
|
||||
|
|
||||
*/
|
||||
|
||||
$kernel->terminate($input, $status);
|
||||
|
||||
exit($status);
|
@ -1,55 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Create The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The first thing we will do is create a new Laravel application instance
|
||||
| which serves as the "glue" for all the components of Laravel, and is
|
||||
| the IoC container for the system binding all of the various parts.
|
||||
|
|
||||
*/
|
||||
|
||||
$app = new Illuminate\Foundation\Application(
|
||||
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Bind Important Interfaces
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Next, we need to bind some important interfaces into the container so
|
||||
| we will be able to resolve them when needed. The kernels serve the
|
||||
| incoming requests to this application from both the web and CLI.
|
||||
|
|
||||
*/
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Http\Kernel::class,
|
||||
App\Http\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Console\Kernel::class,
|
||||
App\Console\Kernel::class
|
||||
);
|
||||
|
||||
$app->singleton(
|
||||
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||
App\Exceptions\Handler::class
|
||||
);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Return The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This script returns the application instance. The instance is given to
|
||||
| the calling script so we can separate the building of the instances
|
||||
| from the actual running of the application and sending responses.
|
||||
|
|
||||
*/
|
||||
|
||||
return $app;
|
2
bootstrap/cache/.gitignore
vendored
2
bootstrap/cache/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
@ -1,64 +1,25 @@
|
||||
{
|
||||
"name": "kamilniemczycki/kamilcraft-api",
|
||||
"type": "project",
|
||||
"description": "The API portfolio of projects.",
|
||||
"description": "Api for kamilcraft.com",
|
||||
"keywords": ["kamilcraft", "api"],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^9.19",
|
||||
"laravel/tinker": "^2.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.6",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"laravel/pint": "^1.0",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^6.1",
|
||||
"phpunit/phpunit": "^9.5.10",
|
||||
"spatie/laravel-ignition": "^1.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"App\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
"type": "project",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kamil Niemczycki",
|
||||
"email": "contact@kamilcraft.com"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"dont-discover": []
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": "dist",
|
||||
"sort-packages": true,
|
||||
"allow-plugins": {
|
||||
"pestphp/pest-plugin": true
|
||||
}
|
||||
},
|
||||
],
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": "^8.0",
|
||||
"symfony/dotenv": "5.3.7"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"KamilCraftApi\\": "src/",
|
||||
"KamilCraftApi\\App\\": "app/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7792
composer.lock
generated
7792
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
return [
|
||||
'name' => env('APP_NAME', 'KamilCraft API'),
|
||||
'env' => env('APP_ENV', 'production'),
|
||||
'debug' => (bool) env('APP_DEBUG', false),
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
'asset_url' => env('ASSET_URL'),
|
||||
'timezone' => 'UTC',
|
||||
'locale' => 'pl',
|
||||
'fallback_locale' => 'en',
|
||||
'faker_locale' => 'en_US',
|
||||
'key' => env('APP_KEY'),
|
||||
'cipher' => 'AES-256-CBC',
|
||||
'maintenance' => [
|
||||
'driver' => 'file',
|
||||
],
|
||||
'providers' => [
|
||||
Illuminate\Auth\AuthServiceProvider::class,
|
||||
Illuminate\Bus\BusServiceProvider::class,
|
||||
Illuminate\Cache\CacheServiceProvider::class,
|
||||
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
|
||||
Illuminate\Cookie\CookieServiceProvider::class,
|
||||
Illuminate\Database\DatabaseServiceProvider::class,
|
||||
Illuminate\Encryption\EncryptionServiceProvider::class,
|
||||
Illuminate\Filesystem\FilesystemServiceProvider::class,
|
||||
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
|
||||
Illuminate\Hashing\HashServiceProvider::class,
|
||||
Illuminate\Notifications\NotificationServiceProvider::class,
|
||||
Illuminate\Pagination\PaginationServiceProvider::class,
|
||||
Illuminate\Pipeline\PipelineServiceProvider::class,
|
||||
Illuminate\Queue\QueueServiceProvider::class,
|
||||
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
|
||||
Illuminate\Session\SessionServiceProvider::class,
|
||||
Illuminate\Translation\TranslationServiceProvider::class,
|
||||
Illuminate\Validation\ValidationServiceProvider::class,
|
||||
Illuminate\View\ViewServiceProvider::class,
|
||||
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\AuthServiceProvider::class,
|
||||
App\Providers\RouteServiceProvider::class,
|
||||
|
||||
App\Providers\CategoryServiceProvider::class,
|
||||
App\Providers\ProjectServiceProvider::class,
|
||||
],
|
||||
'aliases' => Facade::defaultAliases()->merge([])->toArray()
|
||||
];
|
@ -1,31 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'defaults' => [
|
||||
'guard' => 'web',
|
||||
'passwords' => 'users',
|
||||
],
|
||||
'guards' => [
|
||||
'web' => [
|
||||
'driver' => 'session',
|
||||
'provider' => 'users',
|
||||
],
|
||||
],
|
||||
'providers' => [
|
||||
'users' => [
|
||||
'driver' => 'eloquent',
|
||||
'model' => App\Models\User::class,
|
||||
],
|
||||
],
|
||||
'passwords' => [
|
||||
'users' => [
|
||||
'provider' => 'users',
|
||||
'table' => 'password_resets',
|
||||
'expire' => 60,
|
||||
'throttle' => 60,
|
||||
],
|
||||
],
|
||||
'password_timeout' => 10800,
|
||||
];
|
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
'default' => env('CACHE_DRIVER', 'file'),
|
||||
'stores' => [
|
||||
'apc' => [
|
||||
'driver' => 'apc',
|
||||
],
|
||||
'array' => [
|
||||
'driver' => 'array',
|
||||
'serialize' => false,
|
||||
],
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'cache',
|
||||
'connection' => null,
|
||||
'lock_connection' => null,
|
||||
],
|
||||
'file' => [
|
||||
'driver' => 'file',
|
||||
'path' => storage_path('framework/cache/data'),
|
||||
],
|
||||
'memcached' => [
|
||||
'driver' => 'memcached',
|
||||
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
|
||||
'sasl' => [
|
||||
env('MEMCACHED_USERNAME'),
|
||||
env('MEMCACHED_PASSWORD'),
|
||||
],
|
||||
'options' => [
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||
],
|
||||
'servers' => [
|
||||
[
|
||||
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
|
||||
'port' => env('MEMCACHED_PORT', 11211),
|
||||
'weight' => 100,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'KamilCraftAPI'), '_').'_cache_'),
|
||||
];
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'paths' => ['api/*', 'sanctum/csrf-cookie'],
|
||||
'allowed_methods' => ['*'],
|
||||
'allowed_origins' => ['*'],
|
||||
'allowed_origins_patterns' => [],
|
||||
'allowed_headers' => ['*'],
|
||||
'exposed_headers' => [],
|
||||
'max_age' => 0,
|
||||
'supports_credentials' => false,
|
||||
];
|
@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => env('DB_CONNECTION', 'mysql'),
|
||||
'connections' => [
|
||||
'sqlite' => [
|
||||
'driver' => 'sqlite',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
||||
'prefix' => '',
|
||||
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
||||
],
|
||||
'mysql' => [
|
||||
'driver' => 'mysql',
|
||||
'url' => env('DATABASE_URL'),
|
||||
'host' => env('DB_HOST', '127.0.0.1'),
|
||||
'port' => env('DB_PORT', '3306'),
|
||||
'database' => env('DB_DATABASE', 'forge'),
|
||||
'username' => env('DB_USERNAME', 'forge'),
|
||||
'password' => env('DB_PASSWORD', ''),
|
||||
'unix_socket' => env('DB_SOCKET', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'search_path' => 'public',
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||
]) : [],
|
||||
],
|
||||
],
|
||||
'migrations' => 'migrations',
|
||||
];
|
@ -1,92 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'enabled' => env('DEBUGBAR_ENABLED', null),
|
||||
'except' => [
|
||||
'telescope*',
|
||||
'horizon*',
|
||||
],
|
||||
'storage' => [
|
||||
'enabled' => true,
|
||||
'driver' => 'file', // redis, file, pdo, socket, custom
|
||||
'path' => storage_path('debugbar'), // For file driver
|
||||
'connection' => null, // Leave null for default connection (Redis/PDO)
|
||||
'provider' => '', // Instance of StorageInterface for custom driver
|
||||
'hostname' => '127.0.0.1', // Hostname to use with the "socket" driver
|
||||
'port' => 2304, // Port to use with the "socket" driver
|
||||
],
|
||||
'editor' => env('DEBUGBAR_EDITOR', 'phpstorm'),
|
||||
'remote_sites_path' => env('DEBUGBAR_REMOTE_SITES_PATH', ''),
|
||||
'local_sites_path' => env('DEBUGBAR_LOCAL_SITES_PATH', ''),
|
||||
'include_vendors' => true,
|
||||
'capture_ajax' => true,
|
||||
'add_ajax_timing' => false,
|
||||
'error_handler' => false,
|
||||
'clockwork' => false,
|
||||
'collectors' => [
|
||||
'phpinfo' => true, // Php version
|
||||
'messages' => true, // Messages
|
||||
'time' => true, // Time Datalogger
|
||||
'memory' => true, // Memory usage
|
||||
'exceptions' => true, // Exception displayer
|
||||
'log' => true, // Logs from Monolog (merged in messages if enabled)
|
||||
'db' => true, // Show database (PDO) queries and bindings
|
||||
'views' => true, // Views with their data
|
||||
'route' => true, // Current route information
|
||||
'auth' => false, // Display Laravel authentication status
|
||||
'gate' => true, // Display Laravel Gate checks
|
||||
'session' => true, // Display session data
|
||||
'symfony_request' => true, // Only one can be enabled..
|
||||
'mail' => true, // Catch mail messages
|
||||
'laravel' => false, // Laravel version and environment
|
||||
'events' => false, // All events fired
|
||||
'default_request' => false, // Regular or special Symfony request logger
|
||||
'logs' => false, // Add the latest log messages
|
||||
'files' => false, // Show the included files
|
||||
'config' => false, // Display config settings
|
||||
'cache' => false, // Display cache events
|
||||
'models' => true, // Display models
|
||||
'livewire' => true, // Display Livewire (when available)
|
||||
],
|
||||
'options' => [
|
||||
'auth' => [
|
||||
'show_name' => true, // Also show the users name/email in the debugbar
|
||||
],
|
||||
'db' => [
|
||||
'with_params' => true, // Render SQL with the parameters substituted
|
||||
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
|
||||
'backtrace_exclude_paths' => [], // Paths to exclude from backtrace. (in addition to defaults)
|
||||
'timeline' => false, // Add the queries to the timeline
|
||||
'duration_background' => true, // Show shaded background on each query relative to how long it took to execute.
|
||||
'explain' => [ // Show EXPLAIN output on queries
|
||||
'enabled' => false,
|
||||
'types' => ['SELECT'], // Deprecated setting, is always only SELECT
|
||||
],
|
||||
'hints' => false, // Show hints for common mistakes
|
||||
'show_copy' => false, // Show copy button next to the query
|
||||
],
|
||||
'mail' => [
|
||||
'full_log' => false,
|
||||
],
|
||||
'views' => [
|
||||
'timeline' => false, // Add the views to the timeline (Experimental)
|
||||
'data' => false, //Note: Can slow down the application, because the data can be quite large..
|
||||
],
|
||||
'route' => [
|
||||
'label' => true, // show complete route on bar
|
||||
],
|
||||
'logs' => [
|
||||
'file' => null,
|
||||
],
|
||||
'cache' => [
|
||||
'values' => true, // collect cache values
|
||||
],
|
||||
],
|
||||
'inject' => true,
|
||||
'route_prefix' => '_debugbar',
|
||||
'route_domain' => null,
|
||||
'theme' => env('DEBUGBAR_THEME', 'auto'),
|
||||
'debug_backtrace_limit' => 50,
|
||||
];
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
||||
'disks' => [
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app'),
|
||||
'throw' => false,
|
||||
],
|
||||
'public' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('app/public'),
|
||||
'url' => env('APP_URL').'/storage',
|
||||
'visibility' => 'public',
|
||||
'throw' => false,
|
||||
],
|
||||
],
|
||||
|
||||
'links' => [
|
||||
public_path('storage') => storage_path('app/public'),
|
||||
],
|
||||
|
||||
];
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'driver' => 'bcrypt',
|
||||
'bcrypt' => [
|
||||
'rounds' => env('BCRYPT_ROUNDS', 10),
|
||||
],
|
||||
'argon' => [
|
||||
'memory' => 1024,
|
||||
'threads' => 2,
|
||||
'time' => 2,
|
||||
],
|
||||
];
|
@ -1,74 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Monolog\Handler\NullHandler;
|
||||
use Monolog\Handler\StreamHandler;
|
||||
use Monolog\Handler\SyslogUdpHandler;
|
||||
|
||||
return [
|
||||
'default' => env('LOG_CHANNEL', 'stack'),
|
||||
'deprecations' => [
|
||||
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
|
||||
'trace' => false,
|
||||
],
|
||||
'channels' => [
|
||||
'stack' => [
|
||||
'driver' => 'stack',
|
||||
'channels' => ['single'],
|
||||
'ignore_exceptions' => false,
|
||||
],
|
||||
'single' => [
|
||||
'driver' => 'single',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
],
|
||||
'daily' => [
|
||||
'driver' => 'daily',
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'days' => 14,
|
||||
],
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
'username' => 'Laravel Log',
|
||||
'emoji' => ':boom:',
|
||||
'level' => env('LOG_LEVEL', 'critical'),
|
||||
],
|
||||
'papertrail' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
|
||||
'handler_with' => [
|
||||
'host' => env('PAPERTRAIL_URL'),
|
||||
'port' => env('PAPERTRAIL_PORT'),
|
||||
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
|
||||
],
|
||||
],
|
||||
'stderr' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
'handler' => StreamHandler::class,
|
||||
'formatter' => env('LOG_STDERR_FORMATTER'),
|
||||
'with' => [
|
||||
'stream' => 'php://stderr',
|
||||
],
|
||||
],
|
||||
'syslog' => [
|
||||
'driver' => 'syslog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
],
|
||||
'errorlog' => [
|
||||
'driver' => 'errorlog',
|
||||
'level' => env('LOG_LEVEL', 'debug'),
|
||||
],
|
||||
'null' => [
|
||||
'driver' => 'monolog',
|
||||
'handler' => NullHandler::class,
|
||||
],
|
||||
'emergency' => [
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
],
|
||||
],
|
||||
];
|
@ -1,42 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'default' => env('QUEUE_CONNECTION', 'sync'),
|
||||
'connections' => [
|
||||
'sync' => [
|
||||
'driver' => 'sync',
|
||||
],
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'jobs',
|
||||
'queue' => 'default',
|
||||
'retry_after' => 90,
|
||||
'after_commit' => false,
|
||||
],
|
||||
'beanstalkd' => [
|
||||
'driver' => 'beanstalkd',
|
||||
'host' => 'localhost',
|
||||
'queue' => 'default',
|
||||
'retry_after' => 90,
|
||||
'block_for' => 0,
|
||||
'after_commit' => false,
|
||||
],
|
||||
'sqs' => [
|
||||
'driver' => 'sqs',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
|
||||
'queue' => env('SQS_QUEUE', 'default'),
|
||||
'suffix' => env('SQS_SUFFIX'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'after_commit' => false,
|
||||
],
|
||||
],
|
||||
'failed' => [
|
||||
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
|
||||
'database' => env('DB_CONNECTION', 'mysql'),
|
||||
'table' => 'failed_jobs',
|
||||
],
|
||||
];
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'mailgun' => [
|
||||
'domain' => env('MAILGUN_DOMAIN'),
|
||||
'secret' => env('MAILGUN_SECRET'),
|
||||
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
|
||||
],
|
||||
'postmark' => [
|
||||
'token' => env('POSTMARK_TOKEN'),
|
||||
],
|
||||
'ses' => [
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
],
|
||||
];
|
@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
'driver' => env('SESSION_DRIVER', 'file'),
|
||||
'lifetime' => env('SESSION_LIFETIME', 120),
|
||||
'expire_on_close' => false,
|
||||
'encrypt' => false,
|
||||
'files' => storage_path('framework/sessions'),
|
||||
'connection' => env('SESSION_CONNECTION'),
|
||||
'table' => 'sessions',
|
||||
'store' => env('SESSION_STORE'),
|
||||
'lottery' => [2, 100],
|
||||
'cookie' => env(
|
||||
'SESSION_COOKIE',
|
||||
Str::slug(env('APP_NAME', 'KamilCraftAPI'), '_').'_session'
|
||||
),
|
||||
'path' => '/',
|
||||
'domain' => env('SESSION_DOMAIN'),
|
||||
'secure' => env('SESSION_SECURE_COOKIE'),
|
||||
'http_only' => true,
|
||||
'same_site' => 'lax',
|
||||
];
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
'paths' => [
|
||||
resource_path('views'),
|
||||
],
|
||||
'compiled' => env(
|
||||
'VIEW_COMPILED_PATH',
|
||||
realpath(storage_path('framework/views'))
|
||||
),
|
||||
];
|
1
database/.gitignore
vendored
1
database/.gitignore
vendored
@ -1 +0,0 @@
|
||||
*.sqlite*
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->name(),
|
||||
'email' => $this->faker->unique()->safeEmail(),
|
||||
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
|
||||
'remember_token' => Str::random(10),
|
||||
];
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('users');
|
||||
}
|
||||
};
|
@ -1,24 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('password_resets', function (Blueprint $table) {
|
||||
$table->string('email')->index();
|
||||
$table->string('token');
|
||||
$table->timestamp('created_at')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('password_resets');
|
||||
}
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('failed_jobs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('uuid')->unique();
|
||||
$table->text('connection');
|
||||
$table->text('queue');
|
||||
$table->longText('payload');
|
||||
$table->longText('exception');
|
||||
$table->timestamp('failed_at')->useCurrent();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('failed_jobs');
|
||||
}
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->string('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
@ -1,28 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('categories', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->char('name', 20)->nullable();
|
||||
$table->char('slug', 20)->unique();
|
||||
$table->integer('priority')->nullable()->default(0);
|
||||
$table->boolean('default')->nullable()->default(false);
|
||||
$table->boolean('visible')->nullable()->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('categories');
|
||||
}
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('projects', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title', 255);
|
||||
$table->json('categories')->nullable()->default(null);
|
||||
$table->string('author', 30);
|
||||
$table->json('images')->nullable()->default(null);
|
||||
$table->dateTimeTz('release_date')->nullable()->useCurrent();
|
||||
$table->dateTimeTz('update_date')->nullable()->default(null);
|
||||
$table->string('project_url', 255)->nullable()->default(null);
|
||||
$table->string('project_version', 20)->nullable()->default(null);
|
||||
$table->text('description')->nullable()->default(null);
|
||||
$table->boolean('visible')->nullable()->default(false);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('projects');
|
||||
}
|
||||
};
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class CategorySeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$categories = [
|
||||
['name' => 'Wszystkie', 'slug' => 'all', 'default' => true, 'visible' => true],
|
||||
['name' => 'Prywatne', 'slug' => 'private', 'priority' => 1, 'visible' => true],
|
||||
['name' => 'Zlecenie', 'slug' => 'custom', 'priority' => 1, 'visible' => true],
|
||||
['name' => 'Wybrane', 'slug' => 'selected', 'priority' => 1, 'visible' => true],
|
||||
];
|
||||
|
||||
foreach ($categories as $category)
|
||||
Category::query()->create($category);
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$this->call(CategorySeeder::class);
|
||||
$this->call(UserSeeder::class);
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class UserSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
User::factory(['email' => 'admin@example.com'])->create();
|
||||
}
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:latest
|
||||
container_name: kamilcraft-api_www
|
||||
working_dir: /application
|
||||
ports:
|
||||
- ${EXTERNAL_WEBSERVER_PORT:-80}:80
|
||||
volumes:
|
||||
- ./environment/dev/nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||
- .:/application
|
||||
networks:
|
||||
- kamilcraft
|
||||
depends_on:
|
||||
- php
|
||||
- db
|
||||
|
||||
php:
|
||||
build:
|
||||
context: environment/dev/php
|
||||
container_name: kamilcraft-api_php
|
||||
working_dir: /application
|
||||
user: ${CURRENT_UID:-1000}
|
||||
volumes:
|
||||
- .:/application
|
||||
- ./environment/dev/php/php.ini:/usr/local/etc/php/conf.d/php.ini
|
||||
networks:
|
||||
- kamilcraft
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
restart: unless-stopped
|
||||
|
||||
npm:
|
||||
build:
|
||||
context: environment/dev/npm
|
||||
container_name: kamilcraft-api_node
|
||||
working_dir: /application
|
||||
entrypoint: [ 'npm' ]
|
||||
ports:
|
||||
- '3000:3000'
|
||||
- '3001:3001'
|
||||
volumes:
|
||||
- .:/application
|
||||
networks:
|
||||
- kamilcraft
|
||||
|
||||
db:
|
||||
image: mysql:8.0
|
||||
container_name: kamilcraft-api_db
|
||||
ports:
|
||||
- '${DB_PORT}:3306'
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
|
||||
MYSQL_DATABASE: '${DB_DATABASE}'
|
||||
MYSQL_USER: '${DB_USERNAME}'
|
||||
MYSQL_PASSWORD: '${DB_PASSWORD}'
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
|
||||
volumes:
|
||||
- 'mysql-db-data:/var/lib/mysql'
|
||||
networks:
|
||||
- kamilcraft
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
kamilcraft:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
mysql-db-data:
|
||||
name: ib-mysql-data
|
||||
driver: local
|
@ -1,21 +0,0 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
index index.php index.html;
|
||||
root /application/public;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php?$query_string;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass php:9000;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location ~ /.ht {
|
||||
deny all;
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
RUN npm install -g npm@latest
|
@ -1,34 +0,0 @@
|
||||
FROM php:8.1-fpm-alpine
|
||||
|
||||
ARG XDEBUG_VERSION=3.1.6
|
||||
ARG INSTALL_XDEBUG=false
|
||||
|
||||
ARG COMPOSER_VERSION=2.4.4
|
||||
ENV COMPOSER_HOME=/application/.composer
|
||||
ENV COMPOSER_MEMORY_LIMIT=-1
|
||||
|
||||
RUN if [ ${INSTALL_XDEBUG} = true ]; then \
|
||||
apk --no-cache add $PHPIZE_DEPS \
|
||||
&& pecl install xdebug-${XDEBUG_VERSION} \
|
||||
&& docker-php-ext-enable xdebug \
|
||||
;fi
|
||||
|
||||
RUN apk update && apk upgrade \
|
||||
&& apk add --no-cache pcre-dev $PHPIZE_DEPS \
|
||||
icu-dev \
|
||||
zip \
|
||||
libzip-dev \
|
||||
libpng-dev \
|
||||
&& curl -sS https://getcomposer.org/installer | php -- --version="${COMPOSER_VERSION}" --install-dir=/usr/local/bin --filename=composer \
|
||||
&& pecl install redis \
|
||||
&& docker-php-ext-install \
|
||||
mysqli \
|
||||
pdo \
|
||||
pdo_mysql \
|
||||
zip \
|
||||
gd \
|
||||
bcmath \
|
||||
&& docker-php-ext-configure \
|
||||
zip \
|
||||
&& docker-php-ext-enable \
|
||||
redis
|
@ -1,9 +0,0 @@
|
||||
[PHP]
|
||||
memory_limit = 1G
|
||||
|
||||
[xdebug]
|
||||
xdebug.client_host=host.docker.internal
|
||||
xdebug.client_port=9003
|
||||
xdebug.mode=debug
|
||||
xdebug.start_with_request=yes
|
||||
xdebug.log_level=0
|
14
errors/error400.html
Normal file
14
errors/error400.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Błąd 400</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Błąd 400</h1>
|
||||
<p>Niepoprawne zapytanie!</p>
|
||||
</body>
|
||||
</html>
|
14
errors/error404.html
Normal file
14
errors/error404.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Błąd 404</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Błąd 404</h1>
|
||||
<p>Nie znaleziono szukanej strony!</p>
|
||||
</body>
|
||||
</html>
|
14
errors/error500.html
Normal file
14
errors/error500.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="pl">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Błąd 500</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Błąd 500</h1>
|
||||
<p>Wystąpił wewnętrzny błąd serwera!</p>
|
||||
</body>
|
||||
</html>
|
15909
package-lock.json
generated
15909
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
21
package.json
21
package.json
@ -1,21 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"prod": "npm run production",
|
||||
"production": "mix --production"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.21",
|
||||
"laravel-mix": "^6.0.6",
|
||||
"lodash": "^4.17.19",
|
||||
"postcss": "^8.1.14",
|
||||
"resolve-url-loader": "^5.0.0",
|
||||
"sass": "^1.49.7",
|
||||
"sass-loader": "^12.4.0"
|
||||
}
|
||||
}
|
31
phpunit.xml
31
phpunit.xml
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./app</directory>
|
||||
</include>
|
||||
</coverage>
|
||||
<php>
|
||||
<server name="APP_ENV" value="testing"/>
|
||||
<server name="BCRYPT_ROUNDS" value="4"/>
|
||||
<server name="CACHE_DRIVER" value="array"/>
|
||||
<!-- <server name="DB_CONNECTION" value="sqlite"/> -->
|
||||
<!-- <server name="DB_DATABASE" value=":memory:"/> -->
|
||||
<server name="MAIL_MAILER" value="array"/>
|
||||
<server name="QUEUE_CONNECTION" value="sync"/>
|
||||
<server name="SESSION_DRIVER" value="array"/>
|
||||
<server name="TELESCOPE_ENABLED" value="false"/>
|
||||
</php>
|
||||
</phpunit>
|
@ -1,21 +0,0 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
<IfModule mod_negotiation.c>
|
||||
Options -MultiViews -Indexes
|
||||
</IfModule>
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
# Handle Authorization Header
|
||||
RewriteCond %{HTTP:Authorization} .
|
||||
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
||||
|
||||
# Redirect Trailing Slashes If Not A Folder...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_URI} (.+)/$
|
||||
RewriteRule ^ %1 [L,R=301]
|
||||
|
||||
# Send Requests To Front Controller...
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [L]
|
||||
</IfModule>
|
2
public/css/.gitignore
vendored
2
public/css/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
@ -1,55 +1,10 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Contracts\Http\Kernel;
|
||||
use Illuminate\Http\Request;
|
||||
const ROOT_PATH = __DIR__ . '/../';
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
use KamilCraftApi\Application;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Check If The Application Is Under Maintenance
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If the application is in maintenance / demo mode via the "down" command
|
||||
| we will load this file so that any pre-rendered content can be shown
|
||||
| instead of starting the framework, which could cause an exception.
|
||||
|
|
||||
*/
|
||||
require ROOT_PATH . 'vendor/autoload.php';
|
||||
|
||||
if (file_exists($maintenance = __DIR__.'/../storage/framework/maintenance.php')) {
|
||||
require $maintenance;
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The Auto Loader
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Composer provides a convenient, automatically generated class loader for
|
||||
| this application. We just need to utilize it! We'll simply require it
|
||||
| into the script here so we don't need to manually load our classes.
|
||||
|
|
||||
*/
|
||||
|
||||
require __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Once we have the application, we can handle the incoming request using
|
||||
| the application's HTTP kernel. Then, we will send the response back
|
||||
| to this client's browser, allowing them to enjoy our application.
|
||||
|
|
||||
*/
|
||||
|
||||
$app = require_once __DIR__.'/../bootstrap/app.php';
|
||||
|
||||
$kernel = $app->make(Kernel::class);
|
||||
|
||||
$response = $kernel->handle(
|
||||
$request = Request::capture()
|
||||
)->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
||||
$app = new Application(ROOT_PATH . '.env');
|
||||
$app->run();
|
||||
|
2
public/js/.gitignore
vendored
2
public/js/.gitignore
vendored
@ -1,2 +0,0 @@
|
||||
*
|
||||
!.gitignore
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"/js/app.js": "/js/app.js",
|
||||
"/css/dashboard.css": "/css/dashboard.css",
|
||||
"/css/app.css": "/css/app.css"
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
User-agent: *
|
||||
Disallow:
|
@ -1 +0,0 @@
|
||||
require('./bootstrap');
|
28
resources/js/bootstrap.js
vendored
28
resources/js/bootstrap.js
vendored
@ -1,28 +0,0 @@
|
||||
window._ = require('lodash');
|
||||
|
||||
/**
|
||||
* We'll load the axios HTTP library which allows us to easily issue requests
|
||||
* to our Laravel back-end. This library automatically handles sending the
|
||||
* CSRF token as a header based on the value of the "XSRF" token cookie.
|
||||
*/
|
||||
|
||||
window.axios = require('axios');
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
|
||||
/**
|
||||
* Echo exposes an expressive API for subscribing to channels and listening
|
||||
* for events that are broadcast by Laravel. Echo and event broadcasting
|
||||
* allows your team to easily build robust real-time web applications.
|
||||
*/
|
||||
|
||||
// import Echo from 'laravel-echo';
|
||||
|
||||
// window.Pusher = require('pusher-js');
|
||||
|
||||
// window.Echo = new Echo({
|
||||
// broadcaster: 'pusher',
|
||||
// key: process.env.MIX_PUSHER_APP_KEY,
|
||||
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
|
||||
// forceTLS: true
|
||||
// });
|
24
resources/json/Categories.json
Normal file
24
resources/json/Categories.json
Normal file
@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Wszystkie",
|
||||
"slug": "all",
|
||||
"default": true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Prywatne",
|
||||
"slug": "private"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Zlecenie",
|
||||
"slug": "custom"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Wybrane",
|
||||
"slug": "selected",
|
||||
"visible": false
|
||||
}
|
||||
]
|
24
resources/json/Projects.json
Normal file
24
resources/json/Projects.json
Normal file
@ -0,0 +1,24 @@
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Memstacja.pl",
|
||||
"categories": ["selected", "private"],
|
||||
"author": "Kamil Niemczycki",
|
||||
"image": "assets/img/projects/kamilcraft.jpg",
|
||||
"release_data": "28 sierpnia 2021",
|
||||
"project_url": "https://memstacja.pl",
|
||||
"version": "v1.4.9",
|
||||
"description": "Memstacja.pl jest to strona z memami. Umożliwia dodanie własnego mema przez panel administracyjny, nadanie tagów i opisu. Użytkownicy mogą głosować przy użyciu serduszek, mając wpływ na pozycję danego mema na liście polecanych i TOP 10."
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"title": "edwardgoff-art.co.uk",
|
||||
"categories": ["selected", "custom"],
|
||||
"author": "Kamil Niemczycki",
|
||||
"image": "assets/img/projects/edward.jpg",
|
||||
"release_data": "25 sierpnia 2021",
|
||||
"project_url": "https://edwardgoff-art.co.uk",
|
||||
"version": "v1.1.4",
|
||||
"description": "Strona jest wizytówką autora i galerią jego prac. Strona umożliwa tworzenie, a także dodawanie zdjęć i opisów dla utworzonych galerii."
|
||||
}
|
||||
]
|
@ -1,20 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
|
||||
'failed' => 'These credentials do not match our records.',
|
||||
'password' => 'The provided password is incorrect.',
|
||||
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
|
||||
|
||||
];
|
@ -1,19 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Previous',
|
||||
'next' => 'Next »',
|
||||
|
||||
];
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reset Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'reset' => 'Your password has been reset!',
|
||||
'sent' => 'We have emailed your password reset link!',
|
||||
'throttled' => 'Please wait before retrying.',
|
||||
'token' => 'This password reset token is invalid.',
|
||||
'user' => "We can't find a user with that email address.",
|
||||
|
||||
];
|
@ -1,162 +0,0 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'The :attribute must be accepted.',
|
||||
'accepted_if' => 'The :attribute must be accepted when :other is :value.',
|
||||
'active_url' => 'The :attribute is not a valid URL.',
|
||||
'after' => 'The :attribute must be a date after :date.',
|
||||
'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
|
||||
'alpha' => 'The :attribute must only contain letters.',
|
||||
'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.',
|
||||
'alpha_num' => 'The :attribute must only contain letters and numbers.',
|
||||
'array' => 'The :attribute must be an array.',
|
||||
'before' => 'The :attribute must be a date before :date.',
|
||||
'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
|
||||
'between' => [
|
||||
'numeric' => 'The :attribute must be between :min and :max.',
|
||||
'file' => 'The :attribute must be between :min and :max kilobytes.',
|
||||
'string' => 'The :attribute must be between :min and :max characters.',
|
||||
'array' => 'The :attribute must have between :min and :max items.',
|
||||
],
|
||||
'boolean' => 'The :attribute field must be true or false.',
|
||||
'confirmed' => 'The :attribute confirmation does not match.',
|
||||
'current_password' => 'The password is incorrect.',
|
||||
'date' => 'The :attribute is not a valid date.',
|
||||
'date_equals' => 'The :attribute must be a date equal to :date.',
|
||||
'date_format' => 'The :attribute does not match the format :format.',
|
||||
'declined' => 'The :attribute must be declined.',
|
||||
'declined_if' => 'The :attribute must be declined when :other is :value.',
|
||||
'different' => 'The :attribute and :other must be different.',
|
||||
'digits' => 'The :attribute must be :digits digits.',
|
||||
'digits_between' => 'The :attribute must be between :min and :max digits.',
|
||||
'dimensions' => 'The :attribute has invalid image dimensions.',
|
||||
'distinct' => 'The :attribute field has a duplicate value.',
|
||||
'email' => 'The :attribute must be a valid email address.',
|
||||
'ends_with' => 'The :attribute must end with one of the following: :values.',
|
||||
'enum' => 'The selected :attribute is invalid.',
|
||||
'exists' => 'The selected :attribute is invalid.',
|
||||
'file' => 'The :attribute must be a file.',
|
||||
'filled' => 'The :attribute field must have a value.',
|
||||
'gt' => [
|
||||
'numeric' => 'The :attribute must be greater than :value.',
|
||||
'file' => 'The :attribute must be greater than :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than :value characters.',
|
||||
'array' => 'The :attribute must have more than :value items.',
|
||||
],
|
||||
'gte' => [
|
||||
'numeric' => 'The :attribute must be greater than or equal to :value.',
|
||||
'file' => 'The :attribute must be greater than or equal to :value kilobytes.',
|
||||
'string' => 'The :attribute must be greater than or equal to :value characters.',
|
||||
'array' => 'The :attribute must have :value items or more.',
|
||||
],
|
||||
'image' => 'The :attribute must be an image.',
|
||||
'in' => 'The selected :attribute is invalid.',
|
||||
'in_array' => 'The :attribute field does not exist in :other.',
|
||||
'integer' => 'The :attribute must be an integer.',
|
||||
'ip' => 'The :attribute must be a valid IP address.',
|
||||
'ipv4' => 'The :attribute must be a valid IPv4 address.',
|
||||
'ipv6' => 'The :attribute must be a valid IPv6 address.',
|
||||
'mac_address' => 'The :attribute must be a valid MAC address.',
|
||||
'json' => 'The :attribute must be a valid JSON string.',
|
||||
'lt' => [
|
||||
'numeric' => 'The :attribute must be less than :value.',
|
||||
'file' => 'The :attribute must be less than :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than :value characters.',
|
||||
'array' => 'The :attribute must have less than :value items.',
|
||||
],
|
||||
'lte' => [
|
||||
'numeric' => 'The :attribute must be less than or equal to :value.',
|
||||
'file' => 'The :attribute must be less than or equal to :value kilobytes.',
|
||||
'string' => 'The :attribute must be less than or equal to :value characters.',
|
||||
'array' => 'The :attribute must not have more than :value items.',
|
||||
],
|
||||
'max' => [
|
||||
'numeric' => 'The :attribute must not be greater than :max.',
|
||||
'file' => 'The :attribute must not be greater than :max kilobytes.',
|
||||
'string' => 'The :attribute must not be greater than :max characters.',
|
||||
'array' => 'The :attribute must not have more than :max items.',
|
||||
],
|
||||
'mimes' => 'The :attribute must be a file of type: :values.',
|
||||
'mimetypes' => 'The :attribute must be a file of type: :values.',
|
||||
'min' => [
|
||||
'numeric' => 'The :attribute must be at least :min.',
|
||||
'file' => 'The :attribute must be at least :min kilobytes.',
|
||||
'string' => 'The :attribute must be at least :min characters.',
|
||||
'array' => 'The :attribute must have at least :min items.',
|
||||
],
|
||||
'multiple_of' => 'The :attribute must be a multiple of :value.',
|
||||
'not_in' => 'The selected :attribute is invalid.',
|
||||
'not_regex' => 'The :attribute format is invalid.',
|
||||
'numeric' => 'The :attribute must be a number.',
|
||||
'password' => 'The password is incorrect.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'prohibited' => 'The :attribute field is prohibited.',
|
||||
'prohibited_if' => 'The :attribute field is prohibited when :other is :value.',
|
||||
'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.',
|
||||
'prohibits' => 'The :attribute field prohibits :other from being present.',
|
||||
'regex' => 'The :attribute format is invalid.',
|
||||
'required' => 'The :attribute field is required.',
|
||||
'required_if' => 'The :attribute field is required when :other is :value.',
|
||||
'required_unless' => 'The :attribute field is required unless :other is in :values.',
|
||||
'required_with' => 'The :attribute field is required when :values is present.',
|
||||
'required_with_all' => 'The :attribute field is required when :values are present.',
|
||||
'required_without' => 'The :attribute field is required when :values is not present.',
|
||||
'required_without_all' => 'The :attribute field is required when none of :values are present.',
|
||||
'same' => 'The :attribute and :other must match.',
|
||||
'size' => [
|
||||
'numeric' => 'The :attribute must be :size.',
|
||||
'file' => 'The :attribute must be :size kilobytes.',
|
||||
'string' => 'The :attribute must be :size characters.',
|
||||
'array' => 'The :attribute must contain :size items.',
|
||||
],
|
||||
'starts_with' => 'The :attribute must start with one of the following: :values.',
|
||||
'string' => 'The :attribute must be a string.',
|
||||
'timezone' => 'The :attribute must be a valid timezone.',
|
||||
'unique' => 'The :attribute has already been taken.',
|
||||
'uploaded' => 'The :attribute failed to upload.',
|
||||
'url' => 'The :attribute must be a valid URL.',
|
||||
'uuid' => 'The :attribute must be a valid UUID.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'attribute-name' => [
|
||||
'rule-name' => 'custom-message',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap our attribute placeholder
|
||||
| with something more reader friendly such as "E-Mail Address" instead
|
||||
| of "email". This simply helps us make our message more expressive.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user