From 8e2cd6ca683f2e18f0067b6fea7f150dfc176185 Mon Sep 17 00:00:00 2001 From: Ondrej Vlach Date: Wed, 22 Jan 2025 22:52:26 +0100 Subject: [PATCH] taktik-nette --- .gitignore | 6 + .htaccess | 1 + Dockerfile.fpm | 11 + Dockerfile.nginx | 3 + Dockerfile.static | 0 README.md | 64 + app/Bootstrap.php | 51 + app/Core/RouterFactory.php | 23 + app/Repository/SurveyRepository.php | 83 + app/UI/@layout.latte | 19 + app/UI/Accessory/LatteExtension.php | 45 + app/UI/DTO/FilterDTO.php | 31 + app/UI/DTO/OrderDTO.php | 34 + app/UI/DTO/OrderDirection.php | 11 + app/UI/Error/Error4xx/Error4xxPresenter.php | 20 + app/UI/Error/Error5xx/500.phtml | 27 + app/UI/Error/Error5xx/503.phtml | 24 + app/UI/Error/Error5xx/Error5xxPresenter.php | 38 + app/UI/Form/ResultFilteringFactory.php | 35 + app/UI/Form/SurveyFormFactory.php | 47 + app/UI/Results/ResultsPresenter.php | 137 + app/UI/Results/default.latte | 63 + app/UI/Survey/SurveyPresenter.php | 69 + app/UI/Survey/default.latte | 4 + app/lang/messages.cs.neon | 0 app/lang/pagination.cs.neon | 4 + app/lang/survey.cs.neon | 18 + composer.json | 42 + composer.lock | 4090 +++++++++++++++++++ config/common.neon | 44 + config/local.neon | 5 + config/services.neon | 10 + develop.sh | 23 + docker-compose.yml | 59 + docker/nginx/default.conf | 20 + migrations/001_init.sql | 21 + phpcs.xml.dist | 30 + phpstan.neon.dist | 5 + phpunit.xml | 19 + tests/Unit/UI/DTO/FilterDTOTest.php | 64 + tests/Unit/UI/DTO/OrderDTOTest.php | 58 + www/.htaccess | 41 + www/favicon.ico | Bin 0 -> 2550 bytes www/index.php | 11 + www/robots.txt | 0 45 files changed, 5410 insertions(+) create mode 100644 .gitignore create mode 100644 .htaccess create mode 100644 Dockerfile.fpm create mode 100644 Dockerfile.nginx create mode 100644 Dockerfile.static create mode 100644 README.md create mode 100644 app/Bootstrap.php create mode 100644 app/Core/RouterFactory.php create mode 100644 app/Repository/SurveyRepository.php create mode 100644 app/UI/@layout.latte create mode 100644 app/UI/Accessory/LatteExtension.php create mode 100644 app/UI/DTO/FilterDTO.php create mode 100644 app/UI/DTO/OrderDTO.php create mode 100644 app/UI/DTO/OrderDirection.php create mode 100644 app/UI/Error/Error4xx/Error4xxPresenter.php create mode 100644 app/UI/Error/Error5xx/500.phtml create mode 100644 app/UI/Error/Error5xx/503.phtml create mode 100644 app/UI/Error/Error5xx/Error5xxPresenter.php create mode 100644 app/UI/Form/ResultFilteringFactory.php create mode 100644 app/UI/Form/SurveyFormFactory.php create mode 100644 app/UI/Results/ResultsPresenter.php create mode 100644 app/UI/Results/default.latte create mode 100644 app/UI/Survey/SurveyPresenter.php create mode 100644 app/UI/Survey/default.latte create mode 100644 app/lang/messages.cs.neon create mode 100644 app/lang/pagination.cs.neon create mode 100644 app/lang/survey.cs.neon create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/common.neon create mode 100644 config/local.neon create mode 100644 config/services.neon create mode 100755 develop.sh create mode 100644 docker-compose.yml create mode 100644 docker/nginx/default.conf create mode 100644 migrations/001_init.sql create mode 100644 phpcs.xml.dist create mode 100644 phpstan.neon.dist create mode 100644 phpunit.xml create mode 100644 tests/Unit/UI/DTO/FilterDTOTest.php create mode 100644 tests/Unit/UI/DTO/OrderDTOTest.php create mode 100644 www/.htaccess create mode 100644 www/favicon.ico create mode 100644 www/index.php create mode 100644 www/robots.txt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c530cf --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +vendor +log +.phpunit.result.cache +temp +.phpcs-cache + diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..b66e808 --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ +Require all denied diff --git a/Dockerfile.fpm b/Dockerfile.fpm new file mode 100644 index 0000000..9465df8 --- /dev/null +++ b/Dockerfile.fpm @@ -0,0 +1,11 @@ +FROM php:8.3-fpm + +RUN apt-get update && apt-get install -y nodejs npm unzip libzip-dev && rm -rf /var/cache/apt/* +RUN curl -sSL https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions -o - | sh -s \ + opentelemetry-php/ext-opentelemetry@main opcache zip grpc intl calendar pdo_mysql mysqli redis +RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer +RUN composer self-update +RUN usermod -a -G www-data root +RUN mkdir -p /var/www/html +RUN chown -R www-data:www-data /var/www/html +WORKDIR /var/www/html/ diff --git a/Dockerfile.nginx b/Dockerfile.nginx new file mode 100644 index 0000000..8110690 --- /dev/null +++ b/Dockerfile.nginx @@ -0,0 +1,3 @@ +FROM nginx:1.25.3-alpine +COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 diff --git a/Dockerfile.static b/Dockerfile.static new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..dc5f791 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +How to start with development +=== + +* **Requirements:** + * bash + * Docker with Docker Compose (v2) command + +* **Run:** + ```bash + develop.sh + ``` + * Enjoy your coffee ;-) + * Nette will serve the web at [http://localhost:8000]. + +--- + +Tests +--- +Run the following command to execute the tests: + +```bash +docker compose exec php-fpm vendor/bin/phpunit +``` + +--- + +PHPStan & CS +--- + +* Run PHP CodeSniffer: + ```bash + docker compose exec php-fpm vendor/bin/phpcs + ``` +* Run PHPStan with increased memory limit: + ```bash + docker compose exec php-fpm vendor/bin/phpstan --memory-limit=2G + ``` + +--- + +Containers +--- + +* `php-fpm` - FPM and additional tooling +* `nginx` - Serves static content, proxies requests to FPM +* `mariadb` - Database + +--- + +TODO +--- + +* [ ] The current tests are just two unit tests. It definitely needs testing of individual pages, but I haven't had time to set up Codeception (which I would like to use), and the framework itself doesn't offer much. +* [ ] Add a monitoring stack (Prometheus, Otel, Loki, Grafana, etc.). +* [ ] Integrate Sentry. +* [ ] Establish deployment pipelines for dev/test and production environments. Configure production settings and Docker + images. +* [ ] Integrate CI/CD. + +--- + +Notes +--- +* Saving filters into session makes this app very unusable (back button etc.) diff --git a/app/Bootstrap.php b/app/Bootstrap.php new file mode 100644 index 0000000..4b3b627 --- /dev/null +++ b/app/Bootstrap.php @@ -0,0 +1,51 @@ +rootDir = dirname(__DIR__); + $this->configurator = new Configurator(); + $this->configurator->setTempDirectory($this->rootDir . '/temp'); + } + + + public function bootWebApplication(): Nette\DI\Container + { + $this->initializeEnvironment(); + $this->setupContainer(); + + return $this->configurator->createContainer(); + } + + public function initializeEnvironment(): void + { + //$this->configurator->setDebugMode('secret@23.75.345.200'); // enable for your remote IP + //$this->configurator->enableTracy($this->rootDir . '/log'); + + $this->configurator->createRobotLoader() + ->addDirectory(__DIR__) + ->register(); + } + + + private function setupContainer(): void + { + $configDir = $this->rootDir . '/config'; + $this->configurator->addConfig($configDir . '/common.neon'); + $this->configurator->addConfig($configDir . '/services.neon'); + $this->configurator->addConfig($configDir . '/local.neon'); + } +} diff --git a/app/Core/RouterFactory.php b/app/Core/RouterFactory.php new file mode 100644 index 0000000..ca35398 --- /dev/null +++ b/app/Core/RouterFactory.php @@ -0,0 +1,23 @@ +addRoute('/[/]', [ + 'presenter' => 'Survey', + 'action' => 'default', + ]); + return $router; + } +} diff --git a/app/Repository/SurveyRepository.php b/app/Repository/SurveyRepository.php new file mode 100644 index 0000000..c305fd3 --- /dev/null +++ b/app/Repository/SurveyRepository.php @@ -0,0 +1,83 @@ + + */ + public function findSurveys(int $limit, int $offset, ?OrderDTO $order, FilterDTO $filter): array + { + if ($order === null) { + $order = new OrderDTO( + 'survey_id', + OrderDirection::DESC + ); + } + + $data = $this->explorer->query( + "SELECT + survey.id AS survey_id, + survey.name AS survey_name, + survey.comments, + survey.agreement, + ( + SELECT + GROUP_CONCAT(i2.interest SEPARATOR ',') + FROM interests i2 + WHERE survey.id = i2.survey_id + GROUP BY i2.survey_id + ) AS interests + FROM + survey + LEFT JOIN + interests + ON + survey.id = interests.survey_id + WHERE ? + GROUP BY + survey.id + ORDER BY ? ? + LIMIT ? + OFFSET ?", + $filter->filters, + new SqlLiteral($order->column), + new SqlLiteral($order->direction->value), + $limit, + $offset + ); + + return $data->fetchAll(); + } + + public function getSuveysCount(FilterDTO $filter): int + { + $countQuery = $this->explorer->query( + "SELECT + COUNT(DISTINCT survey.id) AS cnt + FROM survey + LEFT JOIN + interests + ON + survey.id = interests.survey_id + WHERE ?", + $filter->filters + ); + return $countQuery->fetchField(); + } +} diff --git a/app/UI/@layout.latte b/app/UI/@layout.latte new file mode 100644 index 0000000..2933a16 --- /dev/null +++ b/app/UI/@layout.latte @@ -0,0 +1,19 @@ + + + + + + + {ifset title}{include title|stripHtml} | {/ifset}Nette Web + + + +
{$flash->message}
+ + {include content} + + {block scripts} + + {/block} + + diff --git a/app/UI/Accessory/LatteExtension.php b/app/UI/Accessory/LatteExtension.php new file mode 100644 index 0000000..b73388e --- /dev/null +++ b/app/UI/Accessory/LatteExtension.php @@ -0,0 +1,45 @@ + [$this, 'renderInterests'], + ]; + } + + public function renderInterests(?string $interests): string + { + if ($interests === null) { + return ''; + } + + $explodedInterests = explode(',', $interests); + $rtVal = []; + + foreach ($explodedInterests as $interest) { + $rtVal[] = $this->translator->translate('survey.interests.' . $interest); + } + + return implode(',', $rtVal); + } +} diff --git a/app/UI/DTO/FilterDTO.php b/app/UI/DTO/FilterDTO.php new file mode 100644 index 0000000..ab4d2dd --- /dev/null +++ b/app/UI/DTO/FilterDTO.php @@ -0,0 +1,31 @@ + $filters + */ + public function __construct(public readonly array $filters = []) + { + } + + /** + * @param array|null $data + * @param array $acceptFilters + * @return FilterDTO + */ + public static function createFromData(?array $data, array $acceptFilters = []): FilterDTO + { + if ($data === null) { + return new self([]); + } + + $result = array_intersect_key($data, array_flip($acceptFilters)); + + return new self($result); + } +} diff --git a/app/UI/DTO/OrderDTO.php b/app/UI/DTO/OrderDTO.php new file mode 100644 index 0000000..6ee507d --- /dev/null +++ b/app/UI/DTO/OrderDTO.php @@ -0,0 +1,34 @@ + $acceptColumns + */ + public static function createOrReturnNullFromData(?string $order, ?string $direction, array $acceptColumns = []): ?OrderDTO + { + if ($order === null || $direction === null) { + return null; + } + + if (!in_array($order, $acceptColumns, true)) { + return null; + } + + $direction = OrderDirection::tryFrom($direction); + + if ($direction === null) { + return null; + } + + return new self($order, $direction); + } +} diff --git a/app/UI/DTO/OrderDirection.php b/app/UI/DTO/OrderDirection.php new file mode 100644 index 0000000..ab7c2ad --- /dev/null +++ b/app/UI/DTO/OrderDirection.php @@ -0,0 +1,11 @@ +redirect(':Survey:default'); + } +} diff --git a/app/UI/Error/Error5xx/500.phtml b/app/UI/Error/Error5xx/500.phtml new file mode 100644 index 0000000..a2b900c --- /dev/null +++ b/app/UI/Error/Error5xx/500.phtml @@ -0,0 +1,27 @@ + + + +Server Error + + + +
+
+

Server Error

+ +

We're sorry! The server encountered an internal error and + was unable to complete your request. Please try again later.

+ +

error 500

+
+
+ + diff --git a/app/UI/Error/Error5xx/503.phtml b/app/UI/Error/Error5xx/503.phtml new file mode 100644 index 0000000..f123919 --- /dev/null +++ b/app/UI/Error/Error5xx/503.phtml @@ -0,0 +1,24 @@ + + + + + + + + +Site is temporarily down for maintenance + +

We're Sorry

+ +

The site is temporarily down for maintenance. Please try again in a few minutes.

diff --git a/app/UI/Error/Error5xx/Error5xxPresenter.php b/app/UI/Error/Error5xx/Error5xxPresenter.php new file mode 100644 index 0000000..06e72fb --- /dev/null +++ b/app/UI/Error/Error5xx/Error5xxPresenter.php @@ -0,0 +1,38 @@ +getParameter('exception'); + $this->logger->log($exception, ILogger::EXCEPTION); + + // Display a generic error message to the user + return new Responses\CallbackResponse(function (Http\IRequest $httpRequest, Http\IResponse $httpResponse): void { + if (preg_match('#^text/html(?:;|$)#', (string) $httpResponse->getHeader('Content-Type'))) { + require __DIR__ . '/500.phtml'; + } + }); + } +} diff --git a/app/UI/Form/ResultFilteringFactory.php b/app/UI/Form/ResultFilteringFactory.php new file mode 100644 index 0000000..26d9e10 --- /dev/null +++ b/app/UI/Form/ResultFilteringFactory.php @@ -0,0 +1,35 @@ +setTranslator($this->translator); + + $form->addText('name', 'survey.name'); + + $form->addTextArea('comments', 'survey.comments'); + + $form->addMultiSelect('interest', 'survey.interests', [ + 'sport' => 'survey.interests.sport', + 'music' => 'survey.interests.music', + 'travel' => 'survey.interests.travel', + ]); + + $form->addSubmit('send', 'survey.search'); + return $form; + } +} diff --git a/app/UI/Form/SurveyFormFactory.php b/app/UI/Form/SurveyFormFactory.php new file mode 100644 index 0000000..db60f24 --- /dev/null +++ b/app/UI/Form/SurveyFormFactory.php @@ -0,0 +1,47 @@ +setTranslator($this->translator); + + $form->addText('name', 'survey.name') + ->setRequired('survey.name_required') + ->addRule(NetteForm::MaxLength, $this->translator->translate('survey.name_is_too_long'), 255); + + + $form->addTextArea('comments', 'survey.comments'); + + $form->addCheckbox('agreement', 'survey.agreement') + ->setRequired('survey.agreement_required'); + + $form->addMultiSelect('interests', 'survey.interests', [ + 'sport' => 'survey.interests.sport', + 'music' => 'survey.interests.music', + 'travel' => 'survey.interests.travel', + ])->setRequired('survey.interests_required') + ->addRule(NetteForm::MaxLength, $this->translator->translate('survey.interest_is_too_long'), 255); + + + $form->addSubmit('send', 'survey.send'); + + $form->addProtection('survey.protection'); + + return $form; + } +} diff --git a/app/UI/Results/ResultsPresenter.php b/app/UI/Results/ResultsPresenter.php new file mode 100644 index 0000000..26dbcc9 --- /dev/null +++ b/app/UI/Results/ResultsPresenter.php @@ -0,0 +1,137 @@ +|null + */ + #[Persistent] + public ?array $filter = null; + + protected const SESSION_STORE_KEY = 'survey_results_v1'; + + public function __construct( + protected readonly SurveyRepository $surveyRepository, + protected readonly ResultFilteringFactory $resultFilteringFactory, + protected readonly Session $session, + ) { + parent::__construct(); + $this->restoreStateFromSession(); + if ($this->order === null) { + $this->order = 'survey_id'; + } + if ($this->direction === null) { + $this->direction = 'desc'; + } + if ($this->filter === null) { + $this->filter = null; + } + } + + public function renderDefault(int $page = 1): void + { + $order = OrderDTO::createOrReturnNullFromData($this->order, $this->direction, ['survey_name', 'comments', 'survey_id']); + $filter = FilterDTO::createFromData($this->filter, ['name', 'comments', 'agreement', 'interest']); + + $itemsCount = $this->surveyRepository->getSuveysCount($filter); + $paginator = new Paginator(); + $paginator->setItemCount($itemsCount); + $paginator->setItemsPerPage(10); + $paginator->setPage($page); + + $articles = $this->surveyRepository->findSurveys($paginator->getLength(), $paginator->getOffset(), $order, $filter); + + $this->template->surveys = $articles; // @phpstan-ignore property.notFound + $this->template->paginator = $paginator; // @phpstan-ignore property.notFound + $this->template->order = $this->order; // @phpstan-ignore property.notFound + $this->template->direction = $this->direction; // @phpstan-ignore property.notFound + } + + + protected function createComponentFilteringForm(): Form + { + $form = $this->resultFilteringFactory->create(); + + $form->setDefaults($this->filter ?? []); + + // @phpstan-ignore-next-line assign.propertyType + $form->onSuccess[] = function (\Nette\Forms\Form $form, array $values): void { + if ($form->isValid()) { + $filter = []; + if (!empty($values['name'])) { + $filter['name'] = $values['name']; + } + if (!empty($values['agreement'])) { + $filter['agreement'] = $values['agreement']; + } + if (!empty($values['comments'])) { + $filter['comments'] = $values['comments']; + } + + if (!empty($values['interest'])) { + $filter['interest'] = $values['interest']; + } + + $this->filter = $filter; + $this->storeStateIntoSession(); + + $this->redirect('default', [ + 'page' => 1, + 'filter' => $filter, + ]); + } + }; + + return $form; + } + + + protected function restoreStateFromSession(): void + { + $session = $this->session->getSection(self::SESSION_STORE_KEY); + if ($session->get('order') !== null) { + $this->order = $session->get('order'); + } + if ($session->get('direction') !== null) { + $this->direction = $session->get('direction'); + } + if ($session->get('filter') !== null) { + $this->filter = $session->get('filter'); + } + } + + protected function storeStateIntoSession(): void + { + $session = $this->session->getSection(self::SESSION_STORE_KEY); + $session->set('order', $this->order); + $session->set('direction', $this->direction); + $session->set('filter', $this->filter); + } + + public function terminate(): void + { + $this->storeStateIntoSession(); + parent::terminate(); + } +} diff --git a/app/UI/Results/default.latte b/app/UI/Results/default.latte new file mode 100644 index 0000000..904143e --- /dev/null +++ b/app/UI/Results/default.latte @@ -0,0 +1,63 @@ +{block content} +

Ankety

+ +
+ {control filteringForm} + {if count($surveys) == 0} +
{_('survey.data_not_found')}
+ {else} + + + + + + + + + + + {foreach $surveys as $survey} + + + + + + + {/foreach} + +
+ + {_('survey.id')} {$order === 'survey_id' ? ($direction === 'ASC' ? '▲' : '▼') : ''} + + + + {_('survey.name')} {$order === 'survey_name' ? ($direction === 'ASC' ? '▲' : '▼') : ''} + + + + {_('survey.comments')} {$order === 'comments' ? ($direction === 'ASC' ? '▲' : '▼') : ''} + + {_('survey.interests')}
{$survey->survey_id}{$survey->survey_name}{$survey->comments}{interests($survey->interests)}
+ {/if} +
+ +{if count($surveys) > 0} + +{/if} +{/block} diff --git a/app/UI/Survey/SurveyPresenter.php b/app/UI/Survey/SurveyPresenter.php new file mode 100644 index 0000000..eaeade7 --- /dev/null +++ b/app/UI/Survey/SurveyPresenter.php @@ -0,0 +1,69 @@ + $values + */ + public function processSurveyForm(Nette\Forms\Form $form, array $values): void + { + if ($form->isValid()) { + $this->database->beginTransaction(); + + try { + $recordId = $this->database->table('survey')->insert( + [ + 'name' => $values['name'], + 'comments' => $values['comments'], + 'agreement' => $values['agreement'], + ] + ); + + foreach ($values['interests'] as $value) { + $this->database->table('interests')->insert( + [ + 'survey_id' => $recordId, + 'interest' => $value, + ] + ); + } + + $this->database->commit(); + + $this->flashMessage($this->translator->translate('survey.successfullyFilled'), 'success'); + $this->redirect('this'); + } catch (\PDOException $e) { + $this->database->rollback(); // TODO: Tady bych dal log do sentry a rekl uziteli at to zkusi pozdeji ;-) + throw $e; + } + } + } + + protected function createComponentSurveyForm(): Nette\Application\UI\Form + { + $form = $this->surveyFormFactor->create(); + $form->onSuccess[] = [$this, 'processSurveyForm']; // @phpstan-ignore assign.propertyType + return $form; + } +} diff --git a/app/UI/Survey/default.latte b/app/UI/Survey/default.latte new file mode 100644 index 0000000..dfb367c --- /dev/null +++ b/app/UI/Survey/default.latte @@ -0,0 +1,4 @@ +{block content} +

{_('survey.header')}

+ {control surveyForm} +{/block} diff --git a/app/lang/messages.cs.neon b/app/lang/messages.cs.neon new file mode 100644 index 0000000..e69de29 diff --git a/app/lang/pagination.cs.neon b/app/lang/pagination.cs.neon new file mode 100644 index 0000000..e775cc0 --- /dev/null +++ b/app/lang/pagination.cs.neon @@ -0,0 +1,4 @@ +last: Poslední +next: Následující +prev: Předcházející +first: První diff --git a/app/lang/survey.cs.neon b/app/lang/survey.cs.neon new file mode 100644 index 0000000..5ae6799 --- /dev/null +++ b/app/lang/survey.cs.neon @@ -0,0 +1,18 @@ +name: Jméno +comments: Komentáře +agreement: Souhlasím s podmínkami +interests: Zájmy +header: Dotazník +interests.sport: Sport +interests.music: Hudba +interests.travel: Cestování +send: Odeslat +name_required: Vyplňte prosím jméno +interests_required: Vypňte prosím zájmy +agreement_required: Musíte souhlasit s podmínkami +successfullyFilled: "Anketa byla úspěšně vyplňena, děkujeme!" +search: Hledat +id: ID +name_is_too_long: "Jméno je na naši anketu příliš dlouhé. Bohužel :-(" +interest_is_too_long: "Váš zájem náš systém neschroupe. Pokud si myslíte že to je chyba, prosím obraťte se na naši podporu" +data_not_found: "Data nebyly nalezeny" diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..a0fb600 --- /dev/null +++ b/composer.json @@ -0,0 +1,42 @@ +{ + "name": "nette/web-project", + "description": "Nette: Standard Web Project", + "keywords": ["nette"], + "type": "project", + "license": ["MIT", "BSD-3-Clause", "GPL-2.0-only", "GPL-3.0-only"], + "require": { + "php": ">= 8.1", + "nette/application": "^3.2.3", + "nette/bootstrap": "^3.2", + "nette/caching": "^3.3", + "nette/database": "^3.2", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/http": "^3.3", + "nette/mail": "^4.0", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/utils": "^4.0", + "latte/latte": "^3.0", + "tracy/tracy": "^2.10", + "contributte/translation": "^2.0", + "nubium/this-should-never-happen-exception": "^1.0" + }, + "autoload": { + "psr-4": { + "App\\": "app" + } + }, + "minimum-stability": "stable", + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, + "require-dev": { + "phpunit/phpunit": "^11.5", + "slevomat/coding-standard": "^8.15", + "squizlabs/php_codesniffer": "^3.11", + "phpstan/phpstan": "^2.1" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..2e1f2be --- /dev/null +++ b/composer.lock @@ -0,0 +1,4090 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "d9804a2b512fa1ba20b90908718fe68e", + "packages": [ + { + "name": "contributte/translation", + "version": "v2.0.5", + "source": { + "type": "git", + "url": "https://github.com/contributte/translation.git", + "reference": "8dedfb0746ee32da06d38d23e1f8e46fe5cabdf5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/contributte/translation/zipball/8dedfb0746ee32da06d38d23e1f8e46fe5cabdf5", + "reference": "8dedfb0746ee32da06d38d23e1f8e46fe5cabdf5", + "shasum": "" + }, + "require": { + "latte/latte": "^2.6|^3.0.12", + "nette/di": "^3.0.6", + "nette/finder": "^2.5.2|~3.0.0", + "nette/http": "^3.0.7", + "nette/neon": "^3.3.1", + "nette/routing": "^3.0", + "nette/schema": "^1.0", + "nette/utils": "^3.2.1|~4.0.0", + "php": "^8.0.2", + "symfony/config": "^6.0|^7.0", + "symfony/translation": "^6.0|^7.0" + }, + "require-dev": { + "doctrine/orm": "^2.8", + "mockery/mockery": "^1.4", + "nette/application": "^3.1.0", + "nette/bootstrap": "^3.2.1", + "nette/database": "^3.1.1", + "nette/robot-loader": "^3.4.0|~4.0.0", + "nette/tester": "^2.3.1", + "ninjify/nunjuck": "^0.4.0", + "ninjify/qa": "^0.13", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-nette": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "psr/log": "^1.1|^2.0|^3.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Contributte\\Translation\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ales Wita" + } + ], + "description": "Symfony/Translation integration for Nette Framework.", + "homepage": "https://github.com/contributte/translation", + "keywords": [ + "nette", + "symfony", + "translation" + ], + "support": { + "issues": "https://github.com/contributte/translation/issues", + "source": "https://github.com/contributte/translation/tree/v2.0.5" + }, + "funding": [ + { + "url": "https://contributte.org/partners.html", + "type": "custom" + }, + { + "url": "https://github.com/f3l1x", + "type": "github" + } + ], + "time": "2024-03-20T10:14:53+00:00" + }, + { + "name": "latte/latte", + "version": "v3.0.20", + "source": { + "type": "git", + "url": "https://github.com/nette/latte.git", + "reference": "4db7a5502f8cef02fffa84fc9c34a635d9c79d4d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/latte/zipball/4db7a5502f8cef02fffa84fc9c34a635d9c79d4d", + "reference": "4db7a5502f8cef02fffa84fc9c34a635d9c79d4d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "php": "8.0 - 8.4" + }, + "conflict": { + "nette/application": "<3.1.7", + "nette/caching": "<3.1.4" + }, + "require-dev": { + "nette/php-generator": "^4.0", + "nette/tester": "^2.5", + "nette/utils": "^4.0", + "phpstan/phpstan": "^1", + "tracy/tracy": "^2.10" + }, + "suggest": { + "ext-fileinfo": "to use filter |datastream", + "ext-iconv": "to use filters |reverse, |substring", + "ext-intl": "to use Latte\\Engine::setLocale()", + "ext-mbstring": "to use filters like lower, upper, capitalize, ...", + "nette/php-generator": "to use tag {templatePrint}", + "nette/utils": "to use filter |webalize" + }, + "bin": [ + "bin/latte-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "☕ Latte: the intuitive and fast template engine for those who want the most secure PHP sites. Introduces context-sensitive escaping.", + "homepage": "https://latte.nette.org", + "keywords": [ + "context-sensitive", + "engine", + "escaping", + "html", + "nette", + "security", + "template", + "twig" + ], + "support": { + "issues": "https://github.com/nette/latte/issues", + "source": "https://github.com/nette/latte/tree/v3.0.20" + }, + "time": "2024-10-08T00:58:27+00:00" + }, + { + "name": "nette/application", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/nette/application.git", + "reference": "9c288cc45df467dc012504f4ad64791279720af8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/application/zipball/9c288cc45df467dc012504f4ad64791279720af8", + "reference": "9c288cc45df467dc012504f4ad64791279720af8", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3", + "nette/routing": "^3.1", + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "conflict": { + "latte/latte": "<2.7.1 || >=3.0.0 <3.0.18 || >=3.1", + "nette/caching": "<3.2", + "nette/di": "<3.2", + "nette/forms": "<3.2", + "nette/schema": "<1.3", + "tracy/tracy": "<2.9" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "latte/latte": "^2.10.2 || ^3.0.18", + "mockery/mockery": "^2.0", + "nette/di": "^3.2", + "nette/forms": "^3.2", + "nette/robot-loader": "^4.0", + "nette/security": "^3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "latte/latte": "Allows using Latte in templates", + "nette/forms": "Allows to use Nette\\Application\\UI\\Form" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🏆 Nette Application: a full-stack component-based MVC kernel for PHP that helps you write powerful and modern web applications. Write less, have cleaner code and your work will bring you joy.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "component-based", + "control", + "framework", + "mvc", + "mvp", + "nette", + "presenter", + "routing", + "seo" + ], + "support": { + "issues": "https://github.com/nette/application/issues", + "source": "https://github.com/nette/application/tree/v3.2.6" + }, + "time": "2024-09-10T10:08:04+00:00" + }, + { + "name": "nette/bootstrap", + "version": "v3.2.5", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "91d08432cb33d6c08d58b215c769d04f20580624" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/91d08432cb33d6c08d58b215c769d04f20580624", + "reference": "91d08432cb33d6c08d58b215c769d04f20580624", + "shasum": "" + }, + "require": { + "nette/di": "^3.1", + "nette/utils": "^3.2.1 || ^4.0", + "php": "8.0 - 8.4" + }, + "conflict": { + "tracy/tracy": "<2.6" + }, + "require-dev": { + "latte/latte": "^2.8 || ^3.0", + "nette/application": "^3.1", + "nette/caching": "^3.0", + "nette/database": "^3.0", + "nette/forms": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/robot-loader": "^3.0 || ^4.0", + "nette/safe-stream": "^2.2", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🅱 Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/bootstrap/issues", + "source": "https://github.com/nette/bootstrap/tree/v3.2.5" + }, + "time": "2024-11-14T00:49:46+00:00" + }, + { + "name": "nette/caching", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/nette/caching.git", + "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/caching/zipball/b37d2c9647b41a9d04f099f10300dc5496c4eb77", + "reference": "b37d2c9647b41a9d04f099f10300dc5496c4eb77", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.0 - 8.4" + }, + "conflict": { + "latte/latte": ">=3.0.0 <3.0.12" + }, + "require-dev": { + "latte/latte": "^2.11 || ^3.0.12", + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "psr/simple-cache": "^2.0 || ^3.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-pdo_sqlite": "to use SQLiteStorage or SQLiteJournal" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⏱ Nette Caching: library with easy-to-use API and many cache backends.", + "homepage": "https://nette.org", + "keywords": [ + "cache", + "journal", + "memcached", + "nette", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/caching/issues", + "source": "https://github.com/nette/caching/tree/v3.3.1" + }, + "time": "2024-08-07T00:01:58+00:00" + }, + { + "name": "nette/component-model", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/nette/component-model.git", + "reference": "fb7608fd5f1c378ef9ef8ddc459c6ef0b63e9d77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/component-model/zipball/fb7608fd5f1c378ef9ef8ddc459c6ef0b63e9d77", + "reference": "fb7608fd5f1c378ef9ef8ddc459c6ef0b63e9d77", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "⚛ Nette Component Model", + "homepage": "https://nette.org", + "keywords": [ + "components", + "nette" + ], + "support": { + "issues": "https://github.com/nette/component-model/issues", + "source": "https://github.com/nette/component-model/tree/v3.1.1" + }, + "time": "2024-08-07T00:35:59+00:00" + }, + { + "name": "nette/database", + "version": "v3.2.6", + "source": { + "type": "git", + "url": "https://github.com/nette/database.git", + "reference": "cb825ac1cffe1ede98388a9c4e6c4445c26b961d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/database/zipball/cb825ac1cffe1ede98388a9c4e6c4445c26b961d", + "reference": "cb825ac1cffe1ede98388a9c4e6c4445c26b961d", + "shasum": "" + }, + "require": { + "ext-pdo": "*", + "nette/caching": "^3.2", + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "^1.0", + "mockery/mockery": "^1.6", + "nette/di": "^3.1", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💾 Nette Database: layer with a familiar PDO-like API but much more powerful. Building queries, advanced joins, drivers for MySQL, PostgreSQL, SQLite, MS SQL Server and Oracle.", + "homepage": "https://nette.org", + "keywords": [ + "database", + "mssql", + "mysql", + "nette", + "notorm", + "oracle", + "pdo", + "postgresql", + "queries", + "sqlite" + ], + "support": { + "issues": "https://github.com/nette/database/issues", + "source": "https://github.com/nette/database/tree/v3.2.6" + }, + "time": "2025-01-12T15:33:57+00:00" + }, + { + "name": "nette/di", + "version": "v3.2.4", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "57f923a7af32435b6e4921c0adbc70c619625a17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/57f923a7af32435b6e4921c0adbc70c619625a17", + "reference": "57f923a7af32435b6e4921c0adbc70c619625a17", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-tokenizer": "*", + "nette/neon": "^3.3 || ^4.0", + "nette/php-generator": "^4.1.6", + "nette/robot-loader": "^4.0", + "nette/schema": "^1.2.5", + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "💎 Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "support": { + "issues": "https://github.com/nette/di/issues", + "source": "https://github.com/nette/di/tree/v3.2.4" + }, + "time": "2025-01-10T04:57:37+00:00" + }, + { + "name": "nette/finder", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/nette/finder.git", + "reference": "027395c638637de95c8e9fad49a7c51249404ed2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/finder/zipball/027395c638637de95c8e9fad49a7c51249404ed2", + "reference": "027395c638637de95c8e9fad49a7c51249404ed2", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔍 Nette Finder: find files and directories with an intuitive API.", + "homepage": "https://nette.org", + "keywords": [ + "filesystem", + "glob", + "iterator", + "nette" + ], + "support": { + "issues": "https://github.com/nette/finder/issues", + "source": "https://github.com/nette/finder/tree/v3.0.0" + }, + "time": "2022-12-14T17:05:54+00:00" + }, + { + "name": "nette/forms", + "version": "v3.2.5", + "source": { + "type": "git", + "url": "https://github.com/nette/forms.git", + "reference": "7e59cee3a16e0382f83680c94babb85a0a167dd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/forms/zipball/7e59cee3a16e0382f83680c94babb85a0a167dd0", + "reference": "7e59cee3a16e0382f83680c94babb85a0a167dd0", + "shasum": "" + }, + "require": { + "nette/component-model": "^3.1", + "nette/http": "^3.3", + "nette/utils": "^4.0.4", + "php": "8.1 - 8.4" + }, + "conflict": { + "latte/latte": ">=3.0.0 <3.0.12 || >=3.1" + }, + "require-dev": { + "latte/latte": "^2.10.2 || ^3.0.12", + "nette/application": "^3.0", + "nette/di": "^3.0", + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^1", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-intl": "to use date/time controls" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📝 Nette Forms: generating, validating and processing secure forms in PHP. Handy API, fully customizable, server & client side validation and mature design.", + "homepage": "https://nette.org", + "keywords": [ + "Forms", + "bootstrap", + "csrf", + "javascript", + "nette", + "validation" + ], + "support": { + "issues": "https://github.com/nette/forms/issues", + "source": "https://github.com/nette/forms/tree/v3.2.5" + }, + "time": "2024-10-22T18:42:14+00:00" + }, + { + "name": "nette/http", + "version": "v3.3.2", + "source": { + "type": "git", + "url": "https://github.com/nette/http.git", + "reference": "3e2587b34beb66f238f119b12fbb4f0b9ab2d6d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/http/zipball/3e2587b34beb66f238f119b12fbb4f0b9ab2d6d1", + "reference": "3e2587b34beb66f238f119b12fbb4f0b9ab2d6d1", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0.4", + "php": "8.1 - 8.4" + }, + "conflict": { + "nette/di": "<3.0.3", + "nette/schema": "<1.2" + }, + "require-dev": { + "nette/di": "^3.0", + "nette/security": "^3.0", + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect MIME type of uploaded files by Nette\\Http\\FileUpload", + "ext-gd": "to use image function in Nette\\Http\\FileUpload", + "ext-intl": "to support punycode by Nette\\Http\\Url", + "ext-session": "to use Nette\\Http\\Session" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🌐 Nette Http: abstraction for HTTP request, response and session. Provides careful data sanitization and utility for URL and cookies manipulation.", + "homepage": "https://nette.org", + "keywords": [ + "cookies", + "http", + "nette", + "proxy", + "request", + "response", + "security", + "session", + "url" + ], + "support": { + "issues": "https://github.com/nette/http/issues", + "source": "https://github.com/nette/http/tree/v3.3.2" + }, + "time": "2025-01-12T16:27:57+00:00" + }, + { + "name": "nette/mail", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nette/mail.git", + "reference": "d99839701c48031d6f35e3be95bdd9418f66ad2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/mail/zipball/d99839701c48031d6f35e3be95bdd9418f66ad2d", + "reference": "d99839701c48031d6f35e3be95bdd9418f66ad2d", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "nette/utils": "^4.0", + "php": "8.0 - 8.4" + }, + "require-dev": { + "nette/di": "^3.1 || ^4.0", + "nette/tester": "^2.4", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "suggest": { + "ext-fileinfo": "to detect type of attached files", + "ext-openssl": "to use Nette\\Mail\\DkimSigner" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📧 Nette Mail: A handy library for creating and sending emails in PHP.", + "homepage": "https://nette.org", + "keywords": [ + "mail", + "mailer", + "mime", + "nette", + "smtp" + ], + "support": { + "issues": "https://github.com/nette/mail/issues", + "source": "https://github.com/nette/mail/tree/v4.0.3" + }, + "time": "2024-10-05T03:15:12+00:00" + }, + { + "name": "nette/neon", + "version": "v3.4.4", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "3411aa86b104e2d5b7e760da4600865ead963c3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/3411aa86b104e2d5b7e760da4600865ead963c3c", + "reference": "3411aa86b104e2d5b7e760da4600865ead963c3c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "8.0 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.7" + }, + "bin": [ + "bin/neon-lint" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍸 Nette NEON: encodes and decodes NEON file format.", + "homepage": "https://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "support": { + "issues": "https://github.com/nette/neon/issues", + "source": "https://github.com/nette/neon/tree/v3.4.4" + }, + "time": "2024-10-04T22:00:08+00:00" + }, + { + "name": "nette/php-generator", + "version": "v4.1.7", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "d201c9bc217e0969d1b678d286be49302972fb56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/d201c9bc217e0969d1b678d286be49302972fb56", + "reference": "d201c9bc217e0969d1b678d286be49302972fb56", + "shasum": "" + }, + "require": { + "nette/utils": "^3.2.9 || ^4.0", + "php": "8.0 - 8.4" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.4", + "nikic/php-parser": "^4.18 || ^5.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.8" + }, + "suggest": { + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.4 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "support": { + "issues": "https://github.com/nette/php-generator/issues", + "source": "https://github.com/nette/php-generator/tree/v4.1.7" + }, + "time": "2024-11-29T01:41:18+00:00" + }, + { + "name": "nette/robot-loader", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nette/robot-loader.git", + "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/robot-loader/zipball/45d67753fb4865bb718e9a6c9be69cc9470137b7", + "reference": "45d67753fb4865bb718e9a6c9be69cc9470137b7", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/utils": "^4.0", + "php": "8.0 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🍀 Nette RobotLoader: high performance and comfortable autoloader that will search and autoload classes within your application.", + "homepage": "https://nette.org", + "keywords": [ + "autoload", + "class", + "interface", + "nette", + "trait" + ], + "support": { + "issues": "https://github.com/nette/robot-loader/issues", + "source": "https://github.com/nette/robot-loader/tree/v4.0.3" + }, + "time": "2024-06-18T20:26:39+00:00" + }, + { + "name": "nette/routing", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/nette/routing.git", + "reference": "5b0782d3b50af68614253a373fa663ed03206a3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/routing/zipball/5b0782d3b50af68614253a373fa663ed03206a3f", + "reference": "5b0782d3b50af68614253a373fa663ed03206a3f", + "shasum": "" + }, + "require": { + "nette/http": "^3.2 || ~4.0.0", + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5", + "phpstan/phpstan": "^1", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "Nette Routing: two-ways URL conversion", + "homepage": "https://nette.org", + "keywords": [ + "nette" + ], + "support": { + "issues": "https://github.com/nette/routing/issues", + "source": "https://github.com/nette/routing/tree/v3.1.1" + }, + "time": "2024-11-04T11:59:47+00:00" + }, + { + "name": "nette/schema", + "version": "v1.3.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/da801d52f0354f70a638673c4a0f04e16529431d", + "reference": "da801d52f0354f70a638673c4a0f04e16529431d", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "require-dev": { + "nette/tester": "^2.5.2", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.3.2" + }, + "time": "2024-10-06T23:10:23+00:00" + }, + { + "name": "nette/security", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/nette/security.git", + "reference": "6e19bf604934aec0cd3343a307e28fd997e40e96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/security/zipball/6e19bf604934aec0cd3343a307e28fd997e40e96", + "reference": "6e19bf604934aec0cd3343a307e28fd997e40e96", + "shasum": "" + }, + "require": { + "nette/utils": "^4.0", + "php": "8.1 - 8.4" + }, + "conflict": { + "nette/di": "<3.0-stable", + "nette/http": "<3.1.3" + }, + "require-dev": { + "mockery/mockery": "^1.5", + "nette/di": "^3.1", + "nette/http": "^3.2", + "nette/tester": "^2.5", + "phpstan/phpstan-nette": "^1.0", + "tracy/tracy": "^2.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🔑 Nette Security: provides authentication, authorization and a role-based access control management via ACL (Access Control List)", + "homepage": "https://nette.org", + "keywords": [ + "Authentication", + "acl", + "authorization", + "nette" + ], + "support": { + "issues": "https://github.com/nette/security/issues", + "source": "https://github.com/nette/security/tree/v3.2.1" + }, + "time": "2024-11-04T12:25:05+00:00" + }, + { + "name": "nette/utils", + "version": "v4.0.5", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "shasum": "" + }, + "require": { + "php": "8.0 - 8.4" + }, + "conflict": { + "nette/finder": "<3", + "nette/schema": "<1.2.2" + }, + "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.5", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.9" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v4.0.5" + }, + "time": "2024-08-07T15:39:19+00:00" + }, + { + "name": "nubium/this-should-never-happen-exception", + "version": "v1.0", + "source": { + "type": "git", + "url": "https://github.com/nubium/this-should-never-happen-exception.git", + "reference": "3ed1b6f725881c527050c235e2503a8300427b86" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nubium/this-should-never-happen-exception/zipball/3ed1b6f725881c527050c235e2503a8300427b86", + "reference": "3ed1b6f725881c527050c235e2503a8300427b86", + "shasum": "" + }, + "require-dev": { + "jakub-onderka/php-parallel-lint": "~1.0", + "phpstan/phpstan": "~0.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nubium\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jiri Travnicek", + "email": "jiri.travnicek@nubium.cz" + } + ], + "description": "Extend this exception and throw it anytime something unexpected happens.", + "support": { + "issues": "https://github.com/nubium/this-should-never-happen-exception/issues", + "source": "https://github.com/nubium/this-should-never-happen-exception/tree/master" + }, + "time": "2018-03-27T10:16:09+00:00" + }, + { + "name": "symfony/config", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/bcd3c4adf0144dee5011bb35454728c38adec055", + "reference": "bcd3c4adf0144dee5011bb35454728c38adec055", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/filesystem": "^7.1", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/finder": "<6.4", + "symfony/service-contracts": "<2.5" + }, + "require-dev": { + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-04T11:36:24+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-10-25T15:15:23+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/translation", + "version": "v7.2.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923", + "reference": "e2674a30132b7cc4d74540d6c2573aa363f05923", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.5|^3.0" + }, + "conflict": { + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/http-client-contracts": "<2.5", + "symfony/http-kernel": "<6.4", + "symfony/service-contracts": "<2.5", + "symfony/twig-bundle": "<6.4", + "symfony/yaml": "<6.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "nikic/php-parser": "^4.18|^5.0", + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client-contracts": "^2.5|^3.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/routing": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/yaml": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v7.2.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-07T08:18:10+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, + { + "name": "tracy/tracy", + "version": "v2.10.9", + "source": { + "type": "git", + "url": "https://github.com/nette/tracy.git", + "reference": "e7af75205b184ca8895bc57fafd331f8d5022d26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/tracy/zipball/e7af75205b184ca8895bc57fafd331f8d5022d26", + "reference": "e7af75205b184ca8895bc57fafd331f8d5022d26", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-session": "*", + "php": "8.0 - 8.4" + }, + "conflict": { + "nette/di": "<3.0" + }, + "require-dev": { + "latte/latte": "^2.5 || ^3.0", + "nette/di": "^3.0", + "nette/http": "^3.0", + "nette/mail": "^3.0 || ^4.0", + "nette/tester": "^2.2", + "nette/utils": "^3.0 || ^4.0", + "phpstan/phpstan": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.10-dev" + } + }, + "autoload": { + "files": [ + "src/Tracy/functions.php" + ], + "classmap": [ + "src" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "😎 Tracy: the addictive tool to ease debugging PHP code for cool developers. Friendly design, logging, profiler, advanced features like debugging AJAX calls or CLI support. You will love it.", + "homepage": "https://tracy.nette.org", + "keywords": [ + "Xdebug", + "debug", + "debugger", + "nette", + "profiler" + ], + "support": { + "issues": "https://github.com/nette/tracy/issues", + "source": "https://github.com/nette/tracy/tree/v2.10.9" + }, + "time": "2024-11-07T14:48:00+00:00" + } + ], + "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "time": "2023-01-05T11:28:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-11-08T17:47:46+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.4.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + }, + "time": "2024-12-30T11:07:19+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" + }, + "time": "2024-10-13T11:25:22+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-01-21T14:54:06+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-11T12:34:27+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "30e319e578a7b5da3543073e30002bf82042f701" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/30e319e578a7b5da3543073e30002bf82042f701", + "reference": "30e319e578a7b5da3543073e30002bf82042f701", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.3" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2025-01-13T09:36:00+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-12T09:59:06+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-01-06T10:28:19+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-12-05T09:17:50+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-17T13:12:04+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "8.15.0", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "7d1d957421618a3803b593ec31ace470177d7817" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7d1d957421618a3803b593ec31ace470177d7817", + "reference": "7d1d957421618a3803b593ec31ace470177d7817", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", + "php": "^7.2 || ^8.0", + "phpstan/phpdoc-parser": "^1.23.1", + "squizlabs/php_codesniffer": "^3.9.0" + }, + "require-dev": { + "phing/phing": "2.17.4", + "php-parallel-lint/php-parallel-lint": "1.3.2", + "phpstan/phpstan": "1.10.60", + "phpstan/phpstan-deprecation-rules": "1.1.4", + "phpstan/phpstan-phpunit": "1.3.16", + "phpstan/phpstan-strict-rules": "1.5.2", + "phpunit/phpunit": "8.5.21|9.6.8|10.5.11" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.15.0" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2024-03-09T15:20:58+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.11.2", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-12-11T16:04:26+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">= 8.1" + }, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/config/common.neon b/config/common.neon new file mode 100644 index 0000000..0feeae0 --- /dev/null +++ b/config/common.neon @@ -0,0 +1,44 @@ +parameters: + +extensions: + translation: Contributte\Translation\DI\TranslationExtension + +translation: + locales: + whitelist: [cs] + default: cs + fallback: [cs] + dirs: + - %appDir%/lang + returnOriginalMessage: true # to not translate undefined messages, default is true + + +application: + errorPresenter: + 4xx: Error:Error4xx + 5xx: Error:Error5xx + mapping: App\UI\*\**Presenter + +database: + dsn: 'mysql:host=mariadb;dbname=survey;charset=utf8mb4' + user: nette + password: nette + +latte: + strictTypes: yes + strictParsing: yes + extensions: + - App\UI\Accessory\LatteExtension + +session: + autoStart: true + save_handler: redis + save_path: 'tcp://redis?timeout=3' + +services: + - App\Repository\SurveyRepository + +di: + export: + parameters: no + tags: no diff --git a/config/local.neon b/config/local.neon new file mode 100644 index 0000000..05fbd68 --- /dev/null +++ b/config/local.neon @@ -0,0 +1,5 @@ +parameters: + debugMode: true + tracy: + showDebugBar: true + strictMode: true diff --git a/config/services.neon b/config/services.neon new file mode 100644 index 0000000..11c7684 --- /dev/null +++ b/config/services.neon @@ -0,0 +1,10 @@ +services: + - App\Core\RouterFactory::createRouter + +search: + - in: %appDir% + classes: + - *Facade + - *Factory + - *Repository + - *Service diff --git a/develop.sh b/develop.sh new file mode 100755 index 0000000..ac6a4a5 --- /dev/null +++ b/develop.sh @@ -0,0 +1,23 @@ + +#!/usr/bin/env sh + + +set -ex + + +docker compose up --build -d + +# composer +docker compose exec -it php-fpm composer install +# fix permissions (TODO: fix-me) - by user in dockerfile +docker compose exec -it php-fpm /bin/sh -c "mkdir -p /var/www/html/temp && chown -R www-data:www-data /var/www/html/temp" + + +docker compose up -d mariadb --wait +cat migrations/*.sql | docker compose exec -T mariadb mysql -pnette survey + +# run containers (and build again) +if [ "$NO_EXECUTE" != "1" ]; then + docker compose up +fi + diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..07edd1e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,59 @@ +services: + nginx: + build: + context: . + dockerfile: ./Dockerfile.nginx + ports: + - '8000:80' + volumes: + - ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf + - ./:/var/www/html/ + links: + - php-fpm + php-fpm: + build: + context: . + dockerfile: ./Dockerfile.fpm + volumes: + - ./:/var/www/html/ + environment: + - OTEL_LOG_LEVEL=debug + - OTEL_TRACES_EXPORTER=otlp + - OTEL_METRICS_EXPORTER=otlp + - OTEL_LOGS_EXPORTER=otlp + - OTEL_PHP_AUTOLOAD_ENABLED=true + - OTEL_PHP_TRACES_PROCESSOR=simple + - OTEL_PHP_LOG_DESTINATION=stderr + - OTEL_EXPORTER_OTLP_PROTOCOL=grpc + - OTEL_EXPORTER_OTLP_ENDPOINT=http://otelcol:4317 + - DB_CONNECTION=mysql + - DB_URL=mysql://laravel:laravel@mariadb:3306/postsystem + - REDIS_HOST=redis + - SESSION_DRIVER=file + - APP_DEBUG=true + - APP_ENV=local + - APP_KEY=base64:yFEh+jTepLsusyVKLmFY3ukDfJrshbB3J6jVzVk1guw= + links: + - mariadb + depends_on: + mariadb: + condition: service_healthy + dns: + - 8.8.8.8 + mariadb: + image: mariadb:10.6 + environment: + - MYSQL_ROOT_PASSWORD=nette + - MYSQL_DATABASE=survey + - MYSQL_USER=nette + - MYSQL_PASSWORD=nette + healthcheck: + test: [ "CMD", "healthcheck.sh", "--connect", "--innodb_initialized" ] + start_period: 10s + interval: 10s + timeout: 10s + retries: 10 + + redis: + image: redis:7.4.2 + diff --git a/docker/nginx/default.conf b/docker/nginx/default.conf new file mode 100644 index 0000000..75ee3ee --- /dev/null +++ b/docker/nginx/default.conf @@ -0,0 +1,20 @@ +server { + index index.php index.html; + server_name symfony_example_app; + error_log stderr debug; + access_log stderr; + listen 80; + root /var/www/html/www; + + + + location / { + try_files $uri /index.php$is_args$args; + } + + location ~ ^/.+\.php(/|$) { + fastcgi_pass php-fpm:9000; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + } +} diff --git a/migrations/001_init.sql b/migrations/001_init.sql new file mode 100644 index 0000000..399e875 --- /dev/null +++ b/migrations/001_init.sql @@ -0,0 +1,21 @@ + +CREATE TABLE survey ( + id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, + name VARCHAR(255) NOT NULL COLLATE utf8_czech_ci, + comments TEXT COLLATE utf8_czech_ci, + agreement BOOLEAN NOT NULL +); + +CREATE INDEX idx_survey_name ON survey (name); +CREATE FULLTEXT INDEX idx_survey_comments ON survey (comments); + +CREATE TABLE interests +( + id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, + survey_id BIGINT UNSIGNED NOT NULL, + interest VARCHAR(255) NOT NULL COLLATE utf8_czech_ci , + FOREIGN KEY (survey_id) REFERENCES survey (id) ON DELETE CASCADE ON UPDATE CASCADE +); + +CREATE INDEX idx_interests_survey_id ON interests (survey_id); +CREATE INDEX idx_interests_interest ON interests (interest); diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..807062f --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + 0 + + + + + + + + + + + + app/ + tests/ + + diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..c75314b --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,5 @@ +parameters: + level: 8 + paths: + - app/ + - tests/ diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..8c691f9 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,19 @@ + + + + + tests/Unit + + + + + app + + + + + diff --git a/tests/Unit/UI/DTO/FilterDTOTest.php b/tests/Unit/UI/DTO/FilterDTOTest.php new file mode 100644 index 0000000..87202bf --- /dev/null +++ b/tests/Unit/UI/DTO/FilterDTOTest.php @@ -0,0 +1,64 @@ + 'John', + 'age' => 30, + 'invalid_key' => 'should not be included', + ]; + + $acceptFilters = ['name', 'age']; + + $filterDTO = FilterDTO::createFromData($data, $acceptFilters); + + $this->assertInstanceOf(FilterDTO::class, $filterDTO); + $this->assertSame( + [ + 'name' => 'John', + 'age' => 30, + ], + $filterDTO->filters + ); + } + + public function testCreateFromInvalidDataWithNoAcceptedFilters(): void + { + $data = [ + 'name' => 'John', + 'age' => 30, + 'invalid_key' => 'should not be included', + ]; + + $acceptFilters = []; + + $filterDTO = FilterDTO::createFromData($data, $acceptFilters); + + $this->assertInstanceOf(FilterDTO::class, $filterDTO); + $this->assertSame([], $filterDTO->filters); + } + + public function testCreateFromInvalidDataWithoutMatchingKeys(): void + { + $data = [ + 'invalid_key1' => 'value1', + 'invalid_key2' => 'value2', + ]; + + $acceptFilters = ['name', 'age']; + + $filterDTO = FilterDTO::createFromData($data, $acceptFilters); + + $this->assertInstanceOf(FilterDTO::class, $filterDTO); + $this->assertSame([], $filterDTO->filters); + } +} diff --git a/tests/Unit/UI/DTO/OrderDTOTest.php b/tests/Unit/UI/DTO/OrderDTOTest.php new file mode 100644 index 0000000..57af5b8 --- /dev/null +++ b/tests/Unit/UI/DTO/OrderDTOTest.php @@ -0,0 +1,58 @@ +assertInstanceOf(OrderDTO::class, $orderDTO); + $this->assertSame($order, $orderDTO->column); + $this->assertSame(OrderDirection::ASC, $orderDTO->direction); + } + + public function testCreateOrReturnNullFromInvalidDataWithInvalidOrder(): void + { + $acceptFilters = ['name', 'created_at']; + $order = 'invalid_column'; + $direction = 'ASC'; + + $orderDTO = OrderDTO::createOrReturnNullFromData($order, $direction, $acceptFilters); + + $this->assertNull($orderDTO); + } + + public function testCreateOrReturnNullFromInvalidDataWithInvalidDirection(): void + { + $acceptFilters = ['name', 'created_at']; + $order = 'name'; + $direction = 'INVALID_DIRECTION'; + + $orderDTO = OrderDTO::createOrReturnNullFromData($order, $direction, $acceptFilters); + + $this->assertNull($orderDTO); + } + + public function testCreateOrReturnNullFromInvalidDataWithEmptyFilters(): void + { + $acceptFilters = []; + $order = 'name'; + $direction = 'ASC'; + + $orderDTO = OrderDTO::createOrReturnNullFromData($order, $direction, $acceptFilters); + + $this->assertNull($orderDTO); + } +} diff --git a/www/.htaccess b/www/.htaccess new file mode 100644 index 0000000..199409c --- /dev/null +++ b/www/.htaccess @@ -0,0 +1,41 @@ +# Apache configuration file (see https://httpd.apache.org/docs/current/mod/quickreference.html) + +# Allow access to all resources by default +Require all granted + +# Disable directory listing for security reasons + + Options -Indexes + + +# Enable pretty URLs (removing the need for "index.php" in the URL) + + RewriteEngine On + + # Uncomment the next line if you want to set the base URL for rewrites + # RewriteBase / + + # Force usage of HTTPS (secure connection). Uncomment if you have SSL setup. + # RewriteCond %{HTTPS} !on + # RewriteRule .? https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] + + # Permit requests to the '.well-known' directory (used for SSL verification and more) + RewriteRule ^\.well-known/.* - [L] + + # Block access to hidden files (starting with a dot) and URLs resembling WordPress admin paths + RewriteRule /\.|^\.|^wp-(login|admin|includes|content) - [F] + + # Return 404 for missing files with specific extensions (images, scripts, styles, archives) + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule \.(pdf|js|mjs|ico|gif|jpg|jpeg|png|webp|avif|svg|css|rar|zip|7z|tar\.gz|map|eot|ttf|otf|woff|woff2)$ - [L] + + # Front controller pattern - all requests are routed through index.php + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule . index.php [L] + + +# Enable gzip compression for text files + + AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json application/xml application/rss+xml image/svg+xml + diff --git a/www/favicon.ico b/www/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b20cfd0f056c1c9d43100f612f4319c66e2adb94 GIT binary patch literal 2550 zcmcgsdpy=>6#qV`h?U#SZJVg3NgD48bB$?q*(P0BnsTYks)Y)n7Gs6xwl1`?sD@_U z*mR*3ue;!TGX-%KzT!aoOgA9#8p?H)WL?RL7J%`}#?vCTxIT)jQ5SY=6*49?+ zh&_ole$lYAvxC8Q5iS=MLnsttXlMv`?%ctjEsbHE`WM;pN*(R2gPpQVcsz^BU^|{g zdOB}*utia3=3%>|9bp}tc@~XfN=iy^4Uf>sN#&@~UN&lzy{)*3spzf3^BSR||YZz~*6I;1wF3`8Euwo$so^QQ+fPxAeUii#5Rap}?} zI637bDXAWlCQX8umlyQ(DzI){DFgxmGBPq~J0F>ud>9)Wx9 zfgL;esHkY7xZ6lhPR71{g~-j##nPo0;O%`5H*eOUySp2Q4mF^^zn|iS2n`K|hDI$; zovJ}&<4uS}_n@M34_mgBKvq^3>gwt+H#bLFSs9iuUk*P%KTMxqN_*>}udk1soE*f( z#nC;_e;ul; zt8w}?A7jS!QZIBOE2|m`3JTEH))x21tXZ>QWo3op;$o_0Df094;o;#yaal-9OC!E& zp{go?j7&KuP88z$^;>9YXrMdSVdKV9NJ~poO)8i?c`_KQLVJ5Vi*e)nQB_rs;o(29XHPk%O)EoSARo=m&6HP2wf#l4 zH4*=<7(aeI#SKGEO$`GB1JKmeL|tgHl| z&&T4$i{a|(iW4VJVAZNs@bU41udgpcLP8K89*&rp7&_}APxI`(?@mKQ1HHYy(9+Vvg9i`L z)zw8kr-!?D??PU_7j12A;_p^j`9AIG#>|;BVPaweGcz;P)YQPz(vteE0@l{nm@{V% zN=iy#Z*Nb1a0PSc&P8EiA)K9^k(ZYT7Z(>SS+WFfZf?lV&c@1>E8*$siS+bz>eGGj z_xGpXNy6^kyRmiaR>a1}A}lNn(b3U}jEsboln`Ub3Nc{<$N329V+>PWBGDrZP)!2^ zgH$uuXI=CzePr8-qdwAy^oBz6>qtwft{!^Z9;%1y^ZT^+>g7P{OXUFj7df)}wRucq zmlm@v@hbOa8Ko5wENykg4mNL*D*qf~3xUi}fK4-w!qLe|`Yf=;$Q%fcQ2~x_S{3dI z1exGnPg=`oSp@5O5E7$6zbZYJ`mKgNaD~lBlrvWRaz2EePA_9@`j2`n7s~VV^4Wnj z`nAb@jO`Kl`fYGqwwdB8k@2B3#Tt)Nf%6LZidBEm%>U zIp^f3xWHJNw^!P)mp({kCuGbESuBup*#~gvu}K%ttO=2*{sN2{JA-W!z>@{nZxqL{ zh=QL_y(oY&ani$2@YEN_aY*gFm*aH@{||iK?3yQO>z|YV>W4Sqo9I6p5G09PXfCPx z;&Zb&aX?Vev-kV*{k_d?**5~-RN@c`{2gue-TH}%`ch3}=ROC&rnaYAkVqm}+BD5V za{pA9-^FlZ;_>*&Z%E=g`&+o(oUB|tP7=3%{UlJbB85M$22KZ{7Oda^FYEk~m9tOZv=@F{=&ov#vg;K8};8MS`EFL7E3`erDkr Rce72bootWebApplication(); + +$application = $container->getByType(Nette\Application\Application::class); +$application->run(); diff --git a/www/robots.txt b/www/robots.txt new file mode 100644 index 0000000..e69de29