76 Commits

Author SHA1 Message Date
caa6ecc2bf Merge pull request 'Версия 0.4.0' (#7) from develop into main
Reviewed-on: #7
2025-02-15 00:07:47 +05:00
c112b225dc Update byTag method to specify void return type
Added an explicit void return type to the byTag method for clarity and strict type enforcement.
2025-02-14 23:33:39 +05:00
e3194cef48 Update MDHub image version to 0.4.0 in production setup 2025-02-14 21:52:17 +05:00
41a7343338 Added the ability to automatically translate simple text. 2025-02-13 22:43:39 +05:00
90aa909b7f Fix incorrect property access in CompletionChecker
Corrected the property access from array syntax to object syntax for `$hash->field` in the `CompletionChecker.php` file. This ensures proper handling of fields and prevents potential runtime errors.
2025-02-13 22:42:40 +05:00
8b35a5691f Refactor language filter to use conditional query builder
Removed redundant `whereIn` clause to simplify the query logic.
2025-02-12 21:38:52 +05:00
844264fb62 Added automatic translation about the project. 2025-02-09 21:39:18 +05:00
d8d17064d0 Mark DocumentationCategoryContentService as readonly. 2025-02-09 20:55:40 +05:00
4dc6060fb3 Added support for automatic translation of documentation categories. 2025-02-09 20:00:34 +05:00
58a256e1e4 Added the ability to automatically translate documentation content. 2025-02-09 18:58:51 +05:00
25faa3d62b Added settings for translation into other languages ​​in the project. 2025-02-09 18:53:08 +05:00
c4817a675a Standardize Dockerfile stage naming convention
Updated all Dockerfile stage names to adhere to a consistent lowercase naming convention with underscores. This improves readability and aligns with best practices for naming Docker build stages.
2025-02-09 18:26:05 +05:00
cb2161356e Remove commented-out alternate image references in configs
Cleaned up unused image lines referencing MDHub in multiple docker-compose files.
2025-02-09 18:25:09 +05:00
b729d057a9 Add writable .composer directory for Composer cache.
This commit ensures a writable .composer directory is created with appropriate permissions. This change resolves potential permission issues when using Composer inside the container.
2024-12-10 22:22:50 +05:00
c2266f2a67 Merge pull request 'Changed the version of my-projects-website:0.3.0 to my-projects-website:0.3.1.' (#6) from develop into main
Reviewed-on: #6
2024-08-04 13:50:34 +05:00
d36507b180 Changed the version of my-projects-website:0.3.0 to my-projects-website:0.3.1. 2024-08-04 13:49:56 +05:00
0e98d67c49 Merge pull request 'Версия 0.3.1' (#5) from develop into main
Reviewed-on: #5
2024-08-04 13:44:20 +05:00
8159145e07 Added prism 'Bash', 'Sh', 'Shell', 'TOML', 'Json'. 2024-08-04 12:38:38 +05:00
17e84ae0a3 Merge pull request 'Fixed. Docker Production CMD ["/usr/local/bin/start"].' (#4) from develop into main
Reviewed-on: #4
2024-07-27 03:07:41 +05:00
4e414a952e Fixed. Docker Production CMD ["/usr/local/bin/start"]. 2024-07-27 02:57:17 +05:00
907a41e057 Merge pull request 'Версия 0.3.0' (#3) from develop into main
Reviewed-on: #3
2024-07-27 02:09:13 +05:00
3902f5d36f my-projects-website:0.3.0. 2024-07-27 01:40:45 +05:00
46da639055 Added the ability to send notifications by email when a new review is added. 2024-07-27 00:29:28 +05:00
c84ed9f12b Configured the removal of old files that were not attached to the model or were marked as deleted. 2024-07-26 22:18:01 +05:00
dde792b97a Made it possible to disable captcha. 2024-07-26 22:16:34 +05:00
618c925dfa Fixed an issue with displaying the translation of site.Menu if the project language did not match the system language. 2024-07-26 22:15:33 +05:00
8bc4c0d8d0 Made it possible to disable captcha. 2024-07-26 22:13:14 +05:00
a5e3c5ed25 Fixed category display error from documentation. Previously, I showed all categories of documentation. 2024-07-26 22:11:54 +05:00
22bb840705 Added prism-yaml. 2024-07-26 22:06:38 +05:00
707762d29b Site. Fixed an error in javascript when the page does not have a tag with the .documentation-version__button class. 2024-07-26 22:06:21 +05:00
b33362a235 Added the ability to upload pictures in the editor. 2024-07-26 22:04:39 +05:00
4d36821ecc Fixed UNIT_SOURCE. 2024-06-12 00:43:36 +05:00
417ce35fc8 Merge pull request 'Версия 0.2.1' (#2) from develop into main
Reviewed-on: #2
2024-06-12 00:03:10 +05:00
da5201dd9a Updated to korelf/my-projects-website:0.2.1. 2024-06-12 00:01:01 +05:00
2910509218 Added environment UNIT_SOURCE and redis volumes. 2024-06-11 23:44:51 +05:00
74f7b88bce Improved docker-entrypoint_*.sh scripts. 2024-06-11 23:43:37 +05:00
6998424b78 Added ignore .env.testing. 2024-06-11 23:42:54 +05:00
05f566c115 Added RoleSyncPermissionsCommandHandlerException. 2024-06-11 23:40:45 +05:00
c5fc106761 Added autocomplete="off" attribute to input password. 2024-06-11 22:39:39 +05:00
d7dc80cca4 Deleted sweetalert2. 2024-06-11 22:35:04 +05:00
6d3891979c Removed extra code. 2024-06-11 22:34:44 +05:00
f986e0396d Merge branch 'develop' 2024-05-19 21:02:48 +05:00
9f6924935d Fixed .dockerignore. 2024-05-19 21:01:04 +05:00
e74456ee2f A documentation section has been added to the site. 2024-05-19 19:47:02 +05:00
42701a24db Fixed an error when saving a project when there is no language data. 2024-05-18 22:58:05 +05:00
78e6a1e396 Added a check for accessibility permission to the project. 2024-05-18 20:18:41 +05:00
b6e1c50486 I fixed this so that prismjs doesn't overlap the menu in the mobile version. 2024-05-17 23:39:26 +05:00
3bc508b8b0 I fixed it so that prismjs would not overlap when selecting another language. 2024-05-17 23:27:18 +05:00
21026cdf52 Added prismjs support. 2024-05-17 21:06:12 +05:00
45504791c0 A documentation section has been added to the admin panel. 2024-05-17 21:05:13 +05:00
156d8a9f68 Added middleware IsWebsiteTranslations and IsProject.
This fixes errors where Project or WebsiteTranslations are not found.
2024-05-03 00:06:59 +05:00
478cbe4762 Refactoring. 2024-05-03 00:03:35 +05:00
35c2368ae2 In the admin panel in the feedback section I added a date. 2024-05-03 00:01:39 +05:00
303af6f203 Fixed menu width. 2024-05-03 00:00:18 +05:00
1485180e20 Updated the captcha service to 0.8.1. 2024-05-02 23:59:38 +05:00
4b6cf902ff Merge pull request 'Версия 0.1.0' (#1) from develop into main
Reviewed-on: #1
2024-04-24 21:56:46 +05:00
d6cb058830 Added a link to the project website. 2024-04-24 21:06:23 +05:00
0c5f2317fd Links are provided on the project page. 2024-04-24 21:00:27 +05:00
6a2991eb5e Docker-compose for production. 2024-04-24 20:54:49 +05:00
481dcac2cc Fixed an error when the APP_FORCE_HTTPS=true parameter is set, and nginx sends the http scheme. 2024-04-24 20:53:59 +05:00
e8b79ca457 Changed the project descriptions. 2024-04-23 19:43:17 +05:00
371395ddd5 Changed the project descriptions. 2024-04-23 19:36:24 +05:00
8c353a49b7 Added Feedback section. 2024-04-23 19:30:56 +05:00
491249c8d8 Added the ability to dynamically translate on the project website. 2024-04-22 23:52:04 +05:00
a648ba3db9 Correcting the link to the project with your domain. 2024-04-18 21:47:47 +05:00
435e793eb2 Added target="_blank". 2024-04-18 21:46:58 +05:00
05fabd7650 Refactoring.
Removed unnecessary methods.
2024-04-18 21:46:22 +05:00
24e0cf0eea The page about the project has been revived. 2024-04-18 19:41:31 +05:00
63ea5dac92 Added the ability to add links to the project. 2024-04-15 22:53:34 +05:00
4583908230 Added package barryvdh/laravel-debugbar. 2024-04-14 15:29:00 +05:00
2769585de0 Added the ability to add project information. 2024-04-14 15:27:51 +05:00
b7d0a2453e Moved from "app/src" to "app/application".
Otherwise phpstorm doesn't understand the paths correctly. He thinks that this is not a complete application, but a package. And when creating a class, the namespace indicates “app” with a small letter, but should be “App”.
2024-04-11 19:52:37 +05:00
e41f63f94f Made it possible to create projects. 2024-04-11 19:43:01 +05:00
c96dabbd09 Added a captcha for login. 2024-04-02 23:21:23 +05:00
e8e9e50162 Installing Laravel.
A simple application skeleton.
2024-04-02 22:16:29 +05:00
bb2b68507b Added my name to the license. 2024-02-24 22:12:59 +06:00
596 changed files with 46758 additions and 3 deletions

10
.env.example Normal file
View File

@@ -0,0 +1,10 @@
DOCKER_APP_PORT=8080
DOCKER_CAPTCHA_PORT=8081
DOCKER_CAPTCHA_WEBSOCKET_PORT=8082
DOCKER_DB_PORT=3306
MYSQL_ROOT_PASSWORD=root_pass
DB_DATABASE=my-projetcs
DB_USERNAME=my-projetcs
DB_PASSWORD=my-projetcs_pass
UID=1000
GID=1000

View File

@@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2024 kor-elf Copyright (c) 2024 Leonid Nikitin (kor-elf)
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: 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:

View File

@@ -1,3 +1,19 @@
# my-projects-website ## О проекте
Сайт для моих проектов. Свой сервис, что бы быстро создавать сайты для своих проектов.
[Сайт проекта](https://my-projects-website.projects.kor-elf.net/)
## Зависимости
php 8.3 (модули: redis, gd)
redis
mysql 8
[Service Captcha](https://git.kor-elf.net/kor-elf/service-captcha)
## Лицензия
[MIT license](https://opensource.org/licenses/MIT).

15
app/.dockerignore Normal file
View File

@@ -0,0 +1,15 @@
**/.env
**/*.env
**/.env.example
**/storage/app/*
**/storage/debugbar
**/storage/framework/cache/*
**/storage/framework/sessions/*
**/storage/framework/views/*
**/storage/framework/testing/*
**/storage/translation_service/*
**/storage/logs/*
**/vendor/
**/node_modules/
**/public/build/
**/public/storage

View File

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

View File

@@ -0,0 +1,94 @@
APP_NAME="My Projects Website"
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_TIMEZONE=UTC
APP_URL=http://localhost
APP_CAPTCHA=false
CAPTCHA_API_DOMAIN=http://your-domain-captcha-or-IP:8081
CAPTCHA_PRIVATE_TOKEN=
CAPTCHA_STATIC_PATH=http://your-domain-captcha-or-IP:8081/captcha
CAPTCHA_PUBLIC_TOKEN=
# Don't forget to configure MAIL_MAILER to send mail.
FEEDBACK_MAIL_NOTIFICATIONS=false
FEEDBACK_MAIL_TO=
TRANSLATION_SERVICE_ENABLE=false
# yandex or log
TRANSLATE_SERVICE=log
TRANSLATE_YANDEX_FOLDER_ID=
TRANSLATE_YANDEX_AUTHORIZED_KEY_PATH=/storage/translation_service/authorized_key.json
TRANSLATE_YANDEX_LIMIT_MAX_REQUEST=20
TRANSLATE_YANDEX_LIMIT_RATE_SECONDS=1
TRANSLATE_YANDEX_LIMIT_MAX_SYMBOLS=9000
TRANSLATE_LOG_LIMIT_MAX_REQUEST=20
TRANSLATE_LOG_LIMIT_RATE_SECONDS=1
TRANSLATE_LOG_LIMIT_MAX_SYMBOLS=9000
APP_FORCE_HTTPS=false
APP_DEFAULT_LOCALE=ru
APP_FAKER_LOCALE=ru_RU
APP_DEFAULT_USER_TIMEZONE=UTC
APP_MAINTENANCE_DRIVER=file
APP_MAINTENANCE_STORE=database
#LOGIN_MAX_REQUEST=50
#LOGIN_MAX_EMAIL_REQUEST=10
TINYMCE_LICENSE_KEY="gpl"
BCRYPT_ROUNDS=12
LOG_CHANNEL=stack
LOG_STACK=single
LOG_DEPRECATIONS_CHANNEL=null
LOG_LEVEL=debug
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
SESSION_DRIVER=redis
SESSION_LIFETIME=120
SESSION_ENCRYPT=true
SESSION_PATH=/
SESSION_DOMAIN=null
BROADCAST_CONNECTION=log
FILESYSTEM_DISK=local
QUEUE_CONNECTION=redis
CACHE_STORE=redis
CACHE_PREFIX=
MEMCACHED_HOST=127.0.0.1
REDIS_CLIENT=phpredis
REDIS_HOST=app-redis
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=127.0.0.1
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="hello@example.com"
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"

11
app/application/.gitattributes vendored Normal file
View File

@@ -0,0 +1,11 @@
* text=auto eol=lf
*.blade.php diff=html
*.css diff=css
*.html diff=html
*.md diff=markdown
*.php diff=php
/.github export-ignore
CHANGELOG.md export-ignore
.styleci.yml export-ignore

20
app/application/.gitignore vendored Normal file
View File

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

66
app/application/README.md Normal file
View File

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

View File

@@ -0,0 +1,94 @@
<?php declare(strict_types=1);
namespace App\Console\Commands;
use App\Dto\User\ManyRoleDto;
use App\Enums\SystemRole;
use App\Repositories\RoleRepository;
use App\Services\User\UserCommandHandler;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator as ValidatorFacade;
use Illuminate\Validation\Rules\Password;
use Illuminate\Validation\Validator;
final class CreateUserAdmin extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:create-user-admin {email} {password}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Create admin user.';
/**
* Execute the console command.
*/
public function handle(UserCommandHandler $userCommandHandler, RoleRepository $roleRepository): void
{
$validator = $this->getData();
if ($validator->fails()) {
$this->errorMessageAndStop($validator->errors()->all());
}
$data = $validator->valid();
try {
$role = $roleRepository->getRoleByCode(SystemRole::Admin->value);
if (is_null($role)) {
$this->errorMessageAndStop('Administrator role not found.');
}
$user = DB::transaction(function () use($data, $userCommandHandler, $role) {
$data['name'] = 'Administrator';
$user = $userCommandHandler->handleStore($data, $data['password']);
$userCommandHandler->handleConfirmationByEmail($user);
$roles = new ManyRoleDto([$role->id]);
$userCommandHandler->handleSyncRoles($user, $roles);
return $user;
});
} catch (\Throwable $e) {
$this->errorMessageAndStop($e->getMessage());
}
$this->info('The command was successful!');
}
private function getData(): Validator
{
return ValidatorFacade::make([
'email' => $this->argument('email'),
'password' => $this->argument('password'),
], [
'email' => ['required', 'email', 'unique:users,email'],
'password' => ['required', Password::default()],
]);
}
private function stop(): never
{
exit;
}
private function errorMessageAndStop(string | array $error): never
{
$this->info('User not created. See error messages below:');
if (is_array($error)) {
foreach ($error as $err) {
$this->error($err);
}
} else {
$this->error($error);
}
$this->stop();
}
}

View File

@@ -0,0 +1,50 @@
<?php declare(strict_types=1);
namespace App\Console\Commands\Files;
use App\Services\Commands\DeleteOldFilesService;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
final class DeleteOldFilesFromStorage extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'files:delete-old-files-from-storage';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Remove temporary files or files that have been deleted from the storage table';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle(DeleteOldFilesService $deleteOldFilesService): void
{
$temporaryBeforeDate = Carbon::now()->subDays(3);
$deletedBeforeDate = Carbon::now()->subDays(7);
$result = $deleteOldFilesService->fromStorage($temporaryBeforeDate, $deletedBeforeDate);
if ($result->isError()) {
$this->error($result->getMessage());
return;
}
$this->info($result->getMessage());
}
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Contracts;
use App\Dto\Service\Dto;
interface FormRequestDto
{
public function getDto(): Dto;
}

View File

@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
namespace App\Contracts\Models;
use App\Enums\StorageType;
use App\Models\Storage as StorageModel;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Collection;
interface Storage
{
public function storage(): MorphMany;
public function getStorageOne(StorageType $type): ?StorageModel;
public function getStorageMany(StorageType $type): Collection;
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Contracts;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Pagination\CursorPaginator;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
interface Search
{
public function __construct(Relation | Builder $query);
public function all(): Collection;
public function get(int $limit): Collection;
public function pagination(int $limit, int $page = 1): LengthAwarePaginator;
public function cursorPaginate(int $limit): CursorPaginator;
}

View File

@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);
namespace App\Contracts;
interface ServiceResult
{
public function isSuccess(): bool;
public function isError(): bool;
}

View File

@@ -0,0 +1,12 @@
<?php declare(strict_types=1);
namespace App\Contracts;
interface ServiceResultError
{
public function getCode(): ?int;
public function getMessage(): string;
public function getErrors(): array;
public function getErrorsOrMessage(): array|string;
public function getData(): array;
}

View File

@@ -0,0 +1,11 @@
<?php declare(strict_types=1);
namespace App\Contracts;
interface StorageType
{
public function getTitle(): string;
public function getAcceptMimes(): array;
public function getFolderName(): string;
public static function cases(): array;
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Contracts\StorageType;
use App\Contracts\StorageType as StorageTypeContract;
interface Audio extends StorageTypeContract
{
public function isAudio(): bool;
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Contracts\StorageType;
use App\Contracts\StorageType as StorageTypeContract;
interface Image extends StorageTypeContract
{
public function isImage(): bool;
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Contracts\StorageType;
use App\Contracts\StorageType as StorageTypeContract;
interface Video extends StorageTypeContract
{
public function isVideo(): bool;
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
use App\Dto\Builder\DocumentationCategory\Category;
final readonly class Documentation
{
public function __construct(
private ?bool $isPublic = null,
private ?Category $categoryId = null,
) { }
public function isPublic(): ?bool
{
return $this->isPublic;
}
public function getCategoryId(): ?Category
{
return $this->categoryId;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
use App\Dto\Builder\DocumentationCategory\Category;
final readonly class DocumentationCategory
{
public function __construct(
private ?bool $isPublic = null,
private ?Category $parentId = null,
) { }
public function isPublic(): ?bool
{
return $this->isPublic;
}
public function getParentId(): ?Category
{
return $this->parentId;
}
}

View File

@@ -0,0 +1,20 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder\DocumentationCategory;
final readonly class Category
{
public function __construct(
private ?int $categoryId,
) { }
public function getCategoryId(): ?int
{
return $this->categoryId;
}
public function isCategoryNull(): bool
{
return $this->getCategoryId() === null;
}
}

View File

@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
final readonly class DocumentationVersion
{
public function __construct(
private ?bool $isPublic = null,
) { }
public function isPublic(): ?bool
{
return $this->isPublic;
}
}

View File

@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
use App\Models\User;
final readonly class Project
{
public function __construct(
private ?bool $isPublic = null,
) { }
public function isPublic(): ?bool
{
return $this->isPublic;
}
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
final readonly class ProjectFeedback
{
public function __construct(
) { }
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
final readonly class ProjectLink
{
public function __construct(
) { }
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
final readonly class Role
{
public function __construct(
) { }
}

View File

@@ -0,0 +1,10 @@
<?php declare(strict_types=1);
namespace App\Dto\Builder;
final readonly class User
{
public function __construct(
) { }
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto;
final readonly class HttpUserData
{
public function __construct(
private ?string $clientIp = null,
private ?string $userAgent = null,
) { }
public function getClientIp(): ?string
{
return $this->clientIp;
}
public function getUserAgent(): ?string
{
return $this->userAgent;
}
}

View File

@@ -0,0 +1,27 @@
<?php declare(strict_types=1);
namespace App\Dto;
final readonly class QuerySettingsDto
{
public function __construct(
private int $limit,
private int $page = 1,
private array $queryWith = []
) { }
public function getLimit(): int
{
return $this->limit;
}
public function getPage(): int
{
return $this->page;
}
public function getQueryWith(): array
{
return $this->queryWith;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Language;
use App\Dto\Service\Dto;
final readonly class NewLanguage extends Dto
{
public function __construct(
private string $name,
private int $index,
) { }
public function getName(): string
{
return $this->name;
}
public function getIndex(): int
{
return $this->index;
}
}

View File

@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\About;
use App\Dto\Service\Dto;
use App\Dto\Service\Storage\Storages;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $title,
private string $description,
private Storages $storages,
private bool $isTranslateAutomatically = false,
) { }
public function getTitle(): string
{
return $this->title;
}
public function getDescription(): string
{
return $this->description;
}
public function getStorages(): Storages
{
return $this->storages;
}
public function isTranslateAutomatically(): bool
{
return $this->isTranslateAutomatically;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Documentation;
use App\Dto\Builder\Documentation;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private Documentation $documentation,
int $page
) {
parent::__construct($page);
}
public function getDocumentation(): Documentation
{
return $this->documentation;
}
}

View File

@@ -0,0 +1,42 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Documentation;
use App\Dto\Service\Admin\Project\DocumentationContent\Contents;
use App\Dto\Service\Dto;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $slug,
private bool $isPublic,
private int $sort,
private Contents $contents,
private ?int $categoryId,
) { }
public function getSlug(): string
{
return $this->slug;
}
public function isPublic(): bool
{
return $this->isPublic;
}
public function getCategoryId(): ?int
{
return $this->categoryId;
}
public function getSort(): int
{
return $this->sort;
}
public function getContents(): Contents
{
return $this->contents;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationCategory;
use App\Dto\Builder\DocumentationCategory;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private DocumentationCategory $documentationCategory,
int $page
) {
parent::__construct($page);
}
public function getDocumentationCategory(): DocumentationCategory
{
return $this->documentationCategory;
}
}

View File

@@ -0,0 +1,42 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationCategory;
use App\Dto\Service\Admin\Project\DocumentationCategoryContent\Contents;
use App\Dto\Service\Dto;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $slug,
private bool $isPublic,
private int $sort,
private Contents $contents,
private ?int $parentId,
) { }
public function getSlug(): string
{
return $this->slug;
}
public function isPublic(): bool
{
return $this->isPublic;
}
public function getSort(): int
{
return $this->sort;
}
public function getParentId(): ?int
{
return $this->parentId;
}
public function getContents(): Contents
{
return $this->contents;
}
}

View File

@@ -0,0 +1,27 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationCategoryContent;
final readonly class Content
{
public function __construct(
private int $languageId,
private string $title,
private bool $isTranslateAutomatically = false,
) { }
public function getLanguageId(): int
{
return $this->languageId;
}
public function getTitle(): string
{
return $this->title;
}
public function isTranslateAutomatically(): bool
{
return $this->isTranslateAutomatically;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationCategoryContent;
final class Contents
{
private array $contents = [];
public function addContent(Content $content): void
{
$this->contents[$content->getLanguageId()] = $content;
}
public function getContent(int $languageId): ?Content
{
return $this->contents[$languageId] ?? null;
}
public function getContents(): array
{
return $this->contents;
}
}

View File

@@ -0,0 +1,41 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationContent;
use App\Dto\Service\Storage\Storages;
final readonly class Content
{
public function __construct(
private int $languageId,
private string $title,
private string $content,
private Storages $storages,
private bool $isTranslateAutomatically = false,
) { }
public function getLanguageId(): int
{
return $this->languageId;
}
public function getTitle(): string
{
return $this->title;
}
public function getContent(): string
{
return $this->content;
}
public function getStorages(): Storages
{
return $this->storages;
}
public function isTranslateAutomatically(): bool
{
return $this->isTranslateAutomatically;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationContent;
final class Contents
{
private array $contents = [];
public function addContent(Content $content): void
{
$this->contents[$content->getLanguageId()] = $content;
}
public function getContent(int $languageId): ?Content
{
return $this->contents[$languageId] ?? null;
}
public function getContents(): array
{
return $this->contents;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationVersion;
use App\Dto\Builder\DocumentationVersion;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private DocumentationVersion $documentationVersionBuildDto,
int $page
) {
parent::__construct($page);
}
public function getDocumentationVersionBuildDto(): DocumentationVersion
{
return $this->documentationVersionBuildDto;
}
}

View File

@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\DocumentationVersion;
use App\Dto\Service\Dto;
use App\Enums\DocumentationVersionStatus;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $title,
private string $slug,
private bool $isPublic,
private DocumentationVersionStatus $status,
) { }
public function getTitle(): string
{
return $this->title;
}
public function getSlug(): string
{
return $this->slug;
}
public function isPublic(): bool
{
return $this->isPublic;
}
public function getStatus(): DocumentationVersionStatus
{
return $this->status;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Feedback;
use App\Dto\Builder\ProjectFeedback;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private ProjectFeedback $projectFeedbackBuilderDto,
int $page
) {
parent::__construct($page);
}
public function getProjectFeedbackBuilderDto(): ProjectFeedback
{
return $this->projectFeedbackBuilderDto;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project;
use App\Dto\Builder\Project;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private Project $projectBuilderDto,
int $page
) {
parent::__construct($page);
}
public function getProjectBuilderDto(): Project
{
return $this->projectBuilderDto;
}
}

View File

@@ -0,0 +1,54 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project;
use App\Dto\Service\Dto;
use App\Enums\Lang;
final readonly class Language extends Dto
{
public function __construct(
private string $title,
private string $code,
private int $sort,
private bool $isDefault,
private ?string $isoCode = null,
private ?Lang $systemLang = null,
private ?int $id = null,
) { }
public function getTitle(): string
{
return $this->title;
}
public function getCode(): string
{
return $this->code;
}
public function getSort(): int
{
return $this->sort;
}
public function isDefault(): bool
{
return $this->isDefault;
}
public function getId(): ?int
{
return $this->id;
}
public function getIsoCode(): ?string
{
return $this->isoCode;
}
public function getSystemLang(): ?Lang
{
return $this->systemLang;
}
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project;
final class Languages
{
private $languages = [];
public function addLanguage(Language $language): void
{
$this->languages[] = $language;
}
public function getLanguages(): array
{
return $this->languages;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Link;
use App\Dto\Builder\ProjectLink;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private ProjectLink $linkBuilderDto,
int $page,
) {
parent::__construct($page);
}
public function getLinkBuilderDto(): ProjectLink
{
return $this->linkBuilderDto;
}
}

View File

@@ -0,0 +1,35 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Link;
use App\Dto\Service\Dto;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $title,
private string $link,
private int $sort,
private ?int $languageId,
) { }
public function getTitle(): string
{
return $this->title;
}
public function getLink(): string
{
return $this->link;
}
public function getSort(): int
{
return $this->sort;
}
public function getLanguageId(): ?int
{
return $this->languageId;
}
}

View File

@@ -0,0 +1,29 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\ServiceTranslate;
use App\Dto\Service\Dto;
final readonly class Translation extends Dto
{
public function __construct(
private int $languageId,
private ?int $sourceLanguageId,
private ?string $code,
) { }
public function getLanguageId(): int
{
return $this->languageId;
}
public function getSourceLanguageId(): ?int
{
return $this->sourceLanguageId;
}
public function getCode(): ?string
{
return $this->code;
}
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\ServiceTranslate;
final class Translations
{
private array $translations;
public function add(Translation $translation): void
{
$this->translations[] = $translation;
}
public function getTranslations(): array
{
return $this->translations;
}
}

View File

@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\ServiceTranslate;
use App\Dto\Service\Dto;
final readonly class Update extends Dto
{
public function __construct(
private Translations $translations,
) { }
public function getTranslations(): Translations
{
return $this->translations;
}
}

View File

@@ -0,0 +1,48 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project;
use App\Dto\Service\Dto;
use App\Dto\Service\Storage\Storages;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $name,
private string $code,
private bool $isPublic,
private Languages $languages,
private Storages $storages,
private ?string $httpHost,
) { }
public function getName(): string
{
return $this->name;
}
public function getCode(): string
{
return $this->code;
}
public function isPublic(): bool
{
return $this->isPublic;
}
public function getLanguages(): Languages
{
return $this->languages;
}
public function getHttpHost(): ?string
{
return $this->httpHost;
}
public function getStorages(): Storages
{
return $this->storages;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Translation;
use App\Dto\Service\Dto;
final readonly class Translation extends Dto
{
public function __construct(
private string $code,
private ?string $text
) { }
public function getCode(): string
{
return $this->code;
}
public function getText(): ?string
{
return $this->text;
}
}

View File

@@ -0,0 +1,55 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Translation;
use App\Enums\DocumentationVersionStatus;
use App\Exceptions\Dto\Admin\Project\Transaction\TranslationsException;
final class Translations
{
private array $translations = [];
public function addTranslation(string $code, ?string $text): void
{
if (!in_array($code, self::getTranslationCodes())) {
throw new TranslationsException('Translation code "' . $code . '" not available');
}
$this->translations[] = new Translation($code, $text);
}
public function getTranslations(): array
{
return $this->translations;
}
public static function getTranslationCodes(): array
{
$translations = [
'site.Menu',
'site.Powered by service',
'site.About project',
'site.Choose language',
'site.Page without translation',
'site.Project',
'site.Feedback',
'site.Feedback-send',
'site.required field',
'site.attributes.name',
'site.attributes.email',
'site.attributes.message',
'site.Message sent successfully',
'Server Error',
'site.Documentation',
'site.Documentation not created',
'site.Choose version',
'site.alert-status-not-supported',
'site.alert-status-future',
];
foreach (DocumentationVersionStatus::cases() as $status) {
$translations[] = $status->getCodeForTranslation();
}
return $translations;
}
}

View File

@@ -0,0 +1,23 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Project\Translation;
use App\Dto\Service\Dto;
final readonly class Update extends Dto
{
public function __construct(
private Translations $translations,
private bool $isTranslateAutomatically = false,
) { }
public function getTranslations(): Translations
{
return $this->translations;
}
public function isTranslateAutomatically(): bool
{
return $this->isTranslateAutomatically;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Role;
use App\Dto\Builder\Role;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private Role $roleBuilderDto,
int $page
) {
parent::__construct($page);
}
public function getRoleBuilderDto(): Role
{
return $this->roleBuilderDto;
}
}

View File

@@ -0,0 +1,29 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\Role;
use App\Dto\Service\Dto;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $name,
private ?string $code,
private array $permissions,
) { }
public function getName(): string
{
return $this->name;
}
public function getCode(): ?string
{
return $this->code;
}
public function getPermissions(): array
{
return $this->permissions;
}
}

View File

@@ -0,0 +1,21 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\User;
use App\Dto\Builder\User;
use App\Dto\Service\Pages;
final readonly class Index extends Pages
{
public function __construct(
private User $userBuilderDto,
int $page
) {
parent::__construct($page);
}
public function getUserBuilderDto(): User
{
return $this->userBuilderDto;
}
}

View File

@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Admin\User;
use App\Dto\Service\Dto;
use App\Dto\User\ManyRoleDto;
final readonly class StoreUpdate extends Dto
{
public function __construct(
private string $name,
private string $email,
private ManyRoleDto $roles,
private ?string $password = null
) { }
public function getName(): string
{
return $this->name;
}
public function getEmail(): string
{
return $this->email;
}
public function getPassword(): ?string
{
return $this->password;
}
public function getRoles(): ManyRoleDto
{
return $this->roles;
}
}

View File

@@ -0,0 +1,27 @@
<?php declare(strict_types=1);
namespace App\Dto\Service;
final readonly class Authorization extends Dto
{
public function __construct(
private string $email,
private string $password,
private bool $remember = false
) { }
public function getEmail(): string
{
return $this->email;
}
public function getPassword(): string
{
return $this->password;
}
public function getRemember(): bool
{
return $this->remember;
}
}

View File

@@ -0,0 +1,30 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\DocumentationContent;
use App\Dto\Service\Storage\Storages;
use App\Models\DocumentationContent;
final class StorageDto
{
/**
* @var array [][DocumentationContent documentationContent, Storages storages]
*/
private array $storages = [];
public function add(DocumentationContent $documentationContent, Storages $storages): void
{
$this->storages[] = [
'documentationContent' => $documentationContent,
'storages' => $storages
];
}
/**
* @return array [][DocumentationContent documentationContent, Storages storages]
*/
public function getStorages(): array
{
return $this->storages;
}
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Dto\Service;
abstract readonly class Dto
{
}

View File

@@ -0,0 +1,15 @@
<?php declare(strict_types=1);
namespace App\Dto\Service;
abstract readonly class Pages extends Dto
{
public function __construct(
private int $page
) { }
public function getPage(): int
{
return $this->page;
}
}

View File

@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Private\Profile;
use App\Dto\Service\Dto;
final readonly class Update extends Dto
{
public function __construct(
private string $name
) { }
public function getName(): string
{
return $this->name;
}
}

View File

@@ -0,0 +1,24 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Private\Profile;
use App\Dto\Service\Dto;
use App\Enums\Lang;
final readonly class UpdateSettings extends Dto
{
public function __construct(
private ?Lang $lang,
private ?string $timezone
) { }
public function getLang(): ?Lang
{
return $this->lang;
}
public function getTimezone(): ?string
{
return $this->timezone;
}
}

View File

@@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceHash;
final class Fields
{
private array $fields = [];
public function add(string $name, string $value): self
{
$this->fields[$name] = $value;
return $this;
}
public function getFields(): array
{
return $this->fields;
}
public function getNames(): array
{
return \array_keys($this->fields);
}
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceHash;
final class HashStatusWaiting
{
private array $hash = [];
public function add(string $fieldName, bool $isWaiting): void
{
$this->hash[$fieldName] = $isWaiting;
}
public function isStatusWaiting(string $fieldName): bool
{
return $this->hash[$fieldName] ?? false;
}
}

View File

@@ -0,0 +1,28 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceHash;
final class Hashes
{
private array $hashes = [];
private array $ids = [];
public function add(int $hashId, string $fieldName, string $hash): void
{
$this->hashes[$hashId] = [
'field' => $fieldName,
'hash' => $hash,
];
$this->ids[] = $hashId;
}
public function getHash(int $hashId): ?array
{
return $this->hashes[$hashId] ?? null;
}
public function getIds(): array
{
return $this->ids;
}
}

View File

@@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceHash;
final class TranslateFields
{
private array $fields = [];
private array $hashes = [];
public function add(int $languageId, string $fieldName, string $hash, int $hashId): self
{
if (!isset($this->fields[$languageId])) {
$this->fields[$languageId] = [];
}
$this->fields[$languageId][] = $fieldName;
if (!isset($this->hashes[$languageId])) {
$this->hashes[$languageId] = [];
}
$this->hashes[$languageId][$fieldName] = [
'hash' => $hash,
'hashId' => $hashId,
];
return $this;
}
public function getFields(): array
{
return $this->fields;
}
public function getHashesByLanguage(int $languageId): array
{
return $this->hashes[$languageId] ?? [];
}
}

View File

@@ -0,0 +1,25 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceTextHash;
final class Codes
{
private array $codes = [];
public function add(string $code, string $value): self
{
$this->codes[$code] = $value;
return $this;
}
public function getCodes(): array
{
return $this->codes;
}
public function getCodeNames(): array
{
return \array_keys($this->codes);
}
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceTextHash;
final class HashStatusWaiting
{
private array $hash = [];
public function add(string $code, bool $isWaiting): void
{
$this->hash[$code] = $isWaiting;
}
public function isStatusWaiting(string $code): bool
{
return $this->hash[$code] ?? false;
}
}

View File

@@ -0,0 +1,28 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceTextHash;
final class Hashes
{
private array $hashes = [];
private array $ids = [];
public function add(int $hashId, string $code, string $hash): void
{
$this->hashes[$hashId] = [
'code' => $code,
'hash' => $hash,
];
$this->ids[] = $hashId;
}
public function getHash(int $hashId): ?array
{
return $this->hashes[$hashId] ?? null;
}
public function getIds(): array
{
return $this->ids;
}
}

View File

@@ -0,0 +1,37 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\ProjectTranslationServiceTextHash;
final class TranslateCodes
{
private array $codes = [];
private array $hashes = [];
public function add(int $languageId, string $code, string $hash, int $hashId): self
{
if (!isset($this->codes[$languageId])) {
$this->codes[$languageId] = [];
}
$this->codes[$languageId][] = $code;
if (!isset($this->hashes[$languageId])) {
$this->hashes[$languageId] = [];
}
$this->hashes[$languageId][$code] = [
'hash' => $hash,
'hashId' => $hashId,
];
return $this;
}
public function getCodes(): array
{
return $this->codes;
}
public function getHashesByLanguage(int $languageId): array
{
return $this->hashes[$languageId] ?? [];
}
}

View File

@@ -0,0 +1,47 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Site;
use App\Models\DocumentationVersion;
use App\Models\Project;
use App\Models\User;
use App\Services\WebsiteTranslations;
final readonly class Documentation
{
public function __construct(
private Project $project,
private DocumentationVersion $version,
private WebsiteTranslations $websiteTranslations,
private ?User $user = null,
) { }
public function getProject(): Project
{
return $this->project;
}
public function getVersion(): DocumentationVersion
{
return $this->version;
}
public function getWebsiteTranslations(): WebsiteTranslations
{
return $this->websiteTranslations;
}
public function getUser(): ?User
{
return $this->user;
}
public function toArray(): array
{
return [
'project' => $this->getProject(),
'version' => $this->getVersion(),
'websiteTranslations' => $this->getWebsiteTranslations(),
];
}
}

View File

@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Site\Feedback;
use App\Dto\HttpUserData;
use App\Dto\Service\Dto;
final readonly class Send extends Dto
{
public function __construct(
private string $message,
private HttpUserData $httpUserData,
private ?string $name,
private ?string $email,
) { }
public function getName(): ?string
{
return $this->name;
}
public function getEmail(): ?string
{
return $this->email;
}
public function getMessage(): string
{
return $this->message;
}
public function getHttpUserData(): HttpUserData
{
return $this->httpUserData;
}
}

View File

@@ -0,0 +1,29 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Storage;
use App\Contracts\StorageType;
use App\Dto\Service\Dto;
use App\Exceptions\Dto\Storage\FileException;
final readonly class File extends Dto
{
public function __construct(
private int $id,
private StorageType $storageType,
) {
if ($this->id < 1) {
throw new FileException('ID cannot be equal to or less than zero: ' . $this->id);
}
}
public function getId(): int
{
return $this->id;
}
public function getStorageType(): StorageType
{
return $this->storageType;
}
}

View File

@@ -0,0 +1,57 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Storage;
use App\Dto\Service\Dto;
use App\Enums\StorageType;
use app\Exceptions\Dto\Storage\StorageException;
final readonly class Storage extends Dto
{
private ?File $file;
private bool $isDelete;
public function __construct(
array $data,
private StorageType $storageType,
private bool $isMany,
) {
$file = null;
if (isset($data['file'])) {
if ((int) $data['file'] <= 0) {
throw new StorageException('ID cannot be equal to or less than zero: ' . $data['file']);
}
$file = new File(
id: (int) $data['file'],
storageType: $this->storageType,
);
}
$this->file = $file;
$this->isDelete = !empty($data['delete']);
}
public function getFile(): ?File
{
return $this->file;
}
public function isDelete(): bool
{
return $this->isDelete;
}
public function isFile(): bool
{
return \is_null($this->file) === false;
}
public function getStorageType(): StorageType
{
return $this->storageType;
}
public function isMany(): bool
{
return $this->isMany;
}
}

View File

@@ -0,0 +1,73 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Storage;
use App\Enums\StorageType;
use app\Exceptions\Dto\Storage\StoragesException;
final class Storages
{
private array $storages = [];
public function add(array $data, StorageType $type): void
{
if (isset($this->storages[$type->value])) {
throw new StoragesException('You cannot attach two files of the same type!');
}
$this->storages[$type->value] = new Storage(data: $data, storageType: $type, isMany: false);
}
public function addMany(array $data, StorageType $type): void
{
if (!isset($this->storages[$type->value])) {
$this->storages[$type->value] = [];
}
foreach ($data as $storageData) {
$this->storages[$type->value][] = new Storage(data: $storageData, storageType: $type, isMany: true);
}
}
public function toArray(): array
{
return $this->storages;
}
public function getAllStorageIds(): array
{
$ids = [];
foreach ($this->storages as $storage) {
/** @var Storage $storage */
if (!is_array($storage)) {
if ($storage->isFile() && !$storage->isDelete()) {
$ids[] = $storage->getFile()->getId();
}
continue;
}
foreach ($storage as $storageOne) {
/** @var Storage $storageOne */
if ($storageOne->isFile() && !$storageOne->isDelete()) {
$ids[] = $storageOne->getFile()->getId();
}
}
}
return $ids;
}
public function getAllStorages(): array
{
$storages = [];
foreach ($this->storages as $storage) {
if (!is_array($storage)) {
$storages[] = $storage;
continue;
}
foreach ($storage as $storageOne) {
$storages[] = $storageOne;
}
}
return $storages;
}
}

View File

@@ -0,0 +1,32 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\Storage;
use App\Dto\Service\Dto;
use App\Enums\Morph;
use App\Enums\StorageType;
use Illuminate\Http\UploadedFile;
final readonly class Upload extends Dto
{
public function __construct(
private UploadedFile $file,
private StorageType $storageType,
private Morph $morph,
) { }
public function getFile(): UploadedFile
{
return $this->file;
}
public function getStorageType(): StorageType
{
return $this->storageType;
}
public function getMorph(): Morph
{
return $this->morph;
}
}

View File

@@ -0,0 +1,17 @@
<?php declare(strict_types=1);
namespace App\Dto\Service\User;
use App\Dto\Service\Dto;
final readonly class UpdatePassword extends Dto
{
public function __construct(
private string $password
) { }
public function getPassword(): string
{
return $this->password;
}
}

View File

@@ -0,0 +1,32 @@
<?php declare(strict_types=1);
namespace App\Dto\User;
use App\Exceptions\Dto\User\ManyRoleDtoException;
final class ManyRoleDto
{
private array $roles = [];
public function __construct(array $roles = []) {
foreach ($roles as $role) {
if (!is_numeric($role) || is_float($role)) {
throw new ManyRoleDtoException('Not an integer: ' . $role . '.');
}
$this->add((int) $role);
}
}
public function add(int $id): void
{
if ($id < 1) {
throw new ManyRoleDtoException('Only Integer > 0.');
}
$this->roles[] = $id;
}
public function toArray(): array
{
return $this->roles;
}
}

View File

@@ -0,0 +1,29 @@
<?php declare(strict_types=1);
namespace App\Dto\View\Volt\Form;
use App\Enums\Morph;
use App\Helpers\Helpers;
final readonly class WysiwygStorageUpload
{
public function __construct(
private string $inputName,
private Morph $morph,
) { }
public function getInputName(): string
{
return $this->inputName;
}
public function getRequestInputName(): string
{
return Helpers::formatAttributeNameToRequestName($this->getInputName());
}
public function getMorph(): Morph
{
return $this->morph;
}
}

View File

@@ -0,0 +1,18 @@
<?php declare(strict_types=1);
namespace App\Enums;
use Illuminate\Cache\TaggedCache;
use Illuminate\Support\Facades\Cache;
enum CacheTag: string
{
case Project = 'project';
case ProjectTranslation = 'project_translation';
case DocumantationVersion = 'documantation_version';
public function getCache(): TaggedCache
{
return Cache::tags($this->value);
}
}

View File

@@ -0,0 +1,46 @@
<?php declare(strict_types=1);
namespace App\Enums;
use App\Services\WebsiteTranslations;
use Illuminate\Support\Collection;
enum DocumentationVersionStatus: int
{
case NotSupported = 0;
case Supported = 50;
case CurrentVersion = 100;
case FutureVersion = 150;
public function getTitle(?WebsiteTranslations $websiteTranslations = null): string
{
if (\is_null($websiteTranslations)) {
return __($this->getCodeForTranslation());
}
return $websiteTranslations->translate($this->getCodeForTranslation());
}
public function getCodeForTranslation(): string
{
return 'version-status.' . $this->name;
}
public static function toArray(): array
{
$items = [];
foreach (self::cases() as $item) {
$items[] = [
'name' => $item->name,
'value' => $item->value,
'title' => $item->getTitle(),
];
}
return $items;
}
public static function toCollection(): Collection
{
return collect(self::toArray());
}
}

View File

@@ -0,0 +1,46 @@
<?php declare(strict_types=1);
namespace App\Enums;
use Illuminate\Support\Collection;
enum Lang: int
{
case Ru = 1;
case En = 2;
public function getTitle(): string
{
return match ($this) {
self::Ru => 'Русский',
self::En => 'English'
};
}
public function getLocale(): string
{
return match ($this) {
self::Ru => 'ru',
self::En => 'en'
};
}
public static function toArray(): array
{
$choices = [];
foreach (self::cases() as $lang) {
$choices[] = [
'name' => $lang->name,
'value' => $lang->value,
'title' => $lang->getTitle(),
'locale' => $lang->getLocale()
];
}
return $choices;
}
public static function toCollection(): Collection
{
return collect(self::toArray());
}
}

View File

@@ -0,0 +1,40 @@
<?php declare(strict_types=1);
namespace App\Enums;
use App\Models\DocumentationCategoryContent;
use App\Models\DocumentationContent;
use App\Models\Project;
use App\Models\ProjectContent;
enum Morph: int
{
case Project = 1;
case DocumentationContent = 2;
case ProjectContent = 3;
case DocumentationCategoryContent = 4;
public function getPathModel(): string
{
return match ($this) {
self::Project => Project::class,
self::DocumentationContent => DocumentationContent::class,
self::ProjectContent => ProjectContent::class,
self::DocumentationCategoryContent => DocumentationCategoryContent::class,
};
}
public function getFolderName(): string
{
return $this->name;
}
public static function map(): array
{
$map = [];
foreach (self::cases() as $item) {
$map[$item->value] = $item->getPathModel();
}
return $map;
}
}

View File

@@ -0,0 +1,83 @@
<?php declare(strict_types=1);
namespace App\Enums;
enum Permission: string
{
case AdminPanel = 'allow-admin-panel';
case Role = 'role';
case User = 'user';
case Project = 'project';
case ProjectContent = 'project-content';
case ProjectLink = 'project-link';
case ProjectTranslation = 'project-translation';
case ProjectFeedback = 'project-feedback';
case Documentation = 'documentation';
case DocumentationCategory = 'documentation-category';
public function getPermissions(): array
{
$permissions = match ($this) {
self::AdminPanel => [
'view' => __('permissions.Administrative panel allowed'),
],
self::Project => array_merge($this->getBasePermissions(), [
'Setting up automatic translation' => __('permissions.Setting up automatic translation'),
]),
self::ProjectContent => [
'view' => __('permissions.Allowed to watch'),
'create' => __('permissions.Allowed to create'),
'update' => __('permissions.Allowed to edit'),
],
self::ProjectTranslation => [
'view' => __('permissions.Allowed to watch'),
'update' => __('permissions.Allowed to edit'),
],
self::ProjectFeedback => [
'view' => __('permissions.Allowed to watch'),
],
default => $this->getBasePermissions()
};
return $permissions;
}
public function getTitle(): string
{
return __('permissions.' . $this->name);
}
public function formatValue(string $permission): string
{
return $this->value . '.' . $permission;
}
public static function toArrayList(): array
{
$permissions = [];
foreach (self::cases() as $permissionEnum) {
foreach ($permissionEnum->getPermissions() as $permissionName => $permissionTitle) {
$name = $permissionEnum->formatValue($permissionName);
$title = $permissionEnum->getTitle() . ' - ' . $permissionTitle;
$permissions[$name] = $title;
}
}
return $permissions;
}
public static function toArrayListCodes(): array
{
return \array_keys(self::toArrayList());
}
private function getBasePermissions(): array
{
return [
'view' => __('permissions.Allowed to watch'),
'create' => __('permissions.Allowed to create'),
'update' => __('permissions.Allowed to edit'),
'delete' => __('permissions.Allowed to delete'),
];
}
}

View File

@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace App\Enums\ProjectTranslationServiceHashes;
enum Status: int
{
case Waiting = 0;
case Success = 10;
}

View File

@@ -0,0 +1,36 @@
<?php declare(strict_types=1);
namespace App\Enums\Site;
use App\Models\Project;
use App\Models\ProjectLanguage;
enum ProjectSection: string
{
case Home = 'home';
case Feedback = 'feedback';
case FeedbackSend = 'feedback.send';
case Documentation = 'documentation';
case DocumentationVersion = 'documentation.version';
case DocumentationCategory = 'documentation.category';
case DocumentationView = 'documentation.view';
public function url(Project $project, ?ProjectLanguage $language = null, array $parameters = []): string
{
$prefixProject = '';
if ($project->http_host === null) {
$prefixProject = 'project.';
$parameters['project'] = $project->code;
}
$prefixLanguage = '';
if ($language?->is_default === false) {
$parameters['language'] = $language->code;
$prefixLanguage = '-language';
}
$route = \route($prefixProject . $this->value . $prefixLanguage, $parameters, false);
return $project->http_host . $route;
}
}

View File

@@ -0,0 +1,57 @@
<?php declare(strict_types=1);
namespace App\Enums;
use App\Contracts\StorageType\Audio;
use App\Contracts\StorageType\Image;
use App\Contracts\StorageType\Video;
enum StorageType: int implements Image, Video, Audio
{
case Logo = 1;
case ContentImages = 2;
public function getTitle(): string
{
return match ($this) {
self::Logo => __('validation.attributes.logo'),
self::ContentImages => __('validation.attributes.content_images'),
};
}
public function getAcceptMimes(): array
{
return match ($this) {
self::Logo => ['jpeg', 'jpg', 'png'],
self::ContentImages => ['jpeg', 'jpg', 'png'],
};
}
public function isImage(): bool
{
return match ($this) {
self::Logo => true,
self::ContentImages => true,
default => false
};
}
public function isVideo(): bool
{
return match ($this) {
default => false
};
}
public function isAudio(): bool
{
return match ($this) {
default => false
};
}
public function getFolderName(): string
{
return $this->name;
}
}

View File

@@ -0,0 +1,9 @@
<?php declare(strict_types=1);
namespace App\Enums;
enum SystemRole: string
{
case Admin = 'admin';
case AdminProject = 'admin-project';
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Dto\Admin\Project\Transaction;
final class TranslationsException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Dto\Storage;
final class FileException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace app\Exceptions\Dto\Storage;
final class StorageException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace app\Exceptions\Dto\Storage;
final class StoragesException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Dto\User;
final class ManyRoleDtoException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Services\DocumentationCategory;
final class ParentException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Services\DocumentationCategoryContent;
final class ContentSaveException extends \Exception
{
}

View File

@@ -0,0 +1,8 @@
<?php declare(strict_types=1);
namespace App\Exceptions\Services\DocumentationContent;
final class ContentSaveException extends \Exception
{
}

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