Compare commits

...

No commits in common. "main" and "old-api" have entirely different histories.

148 changed files with 1007 additions and 27444 deletions

View File

@ -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

View File

@ -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
View File

@ -1,5 +0,0 @@
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore

16
.gitignore vendored
View File

@ -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

View File

@ -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
View File

@ -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.

View File

@ -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
```

View File

@ -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');
}
}

View 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());
}
}

View 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;
}
}

View 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'
]);
}
}

View 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());
}
}

View File

@ -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) {
//
});
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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');
}
}

View File

@ -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;
}

View File

@ -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'));
}
}

View File

@ -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 .'"');
}
}

View File

@ -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 .'"');
}
}

View File

@ -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,
];
}

View File

@ -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;
}
}

View File

@ -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');
}
}

View File

@ -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);
}
}

View File

@ -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',
];
}

View File

@ -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(),
];
}
}

View File

@ -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;
}

View File

@ -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'
];
}
}

View File

@ -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'
];
}
}

View File

@ -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);
}
}

View File

@ -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,
];
}
}

View File

@ -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);
}
}

View File

@ -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,
];
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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',
];
}

View File

@ -1,10 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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());
});
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View File

@ -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);

View File

@ -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;

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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()
];

View File

@ -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,
];

View File

@ -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_'),
];

View File

@ -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,
];

View File

@ -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',
];

View File

@ -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,
];

View File

@ -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'),
],
];

View File

@ -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,
],
];

View File

@ -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'),
],
],
];

View File

@ -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',
],
];

View File

@ -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'),
],
];

View File

@ -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',
];

View File

@ -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
View File

@ -1 +0,0 @@
*.sqlite*

View File

@ -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),
];
}
}

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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');
}
};

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -1,3 +0,0 @@
FROM node:18-alpine
RUN npm install -g npm@latest

View File

@ -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

View File

@ -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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

View File

@ -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"
}
}

View File

@ -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>

View File

@ -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>

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

View File

@ -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();

View File

@ -1,2 +0,0 @@
*
!.gitignore

View File

@ -1,5 +0,0 @@
{
"/js/app.js": "/js/app.js",
"/css/dashboard.css": "/css/dashboard.css",
"/css/app.css": "/css/app.css"
}

View File

@ -1,2 +0,0 @@
User-agent: *
Disallow:

View File

@ -1 +0,0 @@
require('./bootstrap');

View File

@ -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
// });

View 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
}
]

View 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."
}
]

View File

@ -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.',
];

View File

@ -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' => '&laquo; Previous',
'next' => 'Next &raquo;',
];

View File

@ -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.",
];

View File

@ -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