diff --git a/.circleci/config.yml b/.circleci/config.yml
deleted file mode 100644
index 9ee462a60..000000000
--- a/.circleci/config.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-version: 2
-
-jobs:
- build:
- machine: true
- steps:
- - checkout
-
- - restore_cache:
- keys:
- - composer_{{ checksum "composer.lock" }}
-
- - run: cp .env.dist .env
- - run: make build
- # We need to wait until the mysql is ready, and since docker-compose remove the health check condition
- # on depends_on, we have to do this π© https://docs.docker.com/compose/compose-file/#depends_on
- - run: >
- while ! docker exec codelytv-cqrs_ddd_php_example-mysql mysqladmin --user=root --password=root --host "127.0.0.1" ping --silent &> /dev/null ; do
- echo "Waiting for database connection..."
- sleep 2
- done
- - run: make test
- - store_test_results:
- path: build/test_results
- - store_artifacts:
- path: build/test_results
-
- - save_cache:
- key: composer_{{ checksum "composer.lock" }}
- paths:
- - ~/.composer
diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 01490f6f8..000000000
--- a/.editorconfig
+++ /dev/null
@@ -1,9 +0,0 @@
-root = true
-
-[*]
-charset = utf-8
-end_of_line = lf
-
-[Makefile]
-indent_style = tab
-indent_size = 4
diff --git a/.env b/.env
new file mode 100644
index 000000000..8099dcd37
--- /dev/null
+++ b/.env
@@ -0,0 +1,41 @@
+### Symfony - framework-bundle
+APP_ENV=test
+APP_SECRET=29ac4a5187930cd4b689aa0f3ee7cbc0
+#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
+#TRUSTED_HOSTS='^localhost|example\.com$'
+
+# MOOC #
+#--------------------------------#
+# MySql
+MOOC_DATABASE_DRIVER=pdo_mysql
+MOOC_DATABASE_HOST=codely-php_ddd_skeleton-mooc-mysql
+MOOC_DATABASE_PORT=3306
+MOOC_DATABASE_NAME=mooc
+MOOC_DATABASE_USER=root
+MOOC_DATABASE_PASSWORD=
+
+# BACKOFFICE #
+#--------------------------------#
+# MySql
+BACKOFFICE_DATABASE_DRIVER=pdo_mysql
+BACKOFFICE_DATABASE_HOST=codely-php_ddd_skeleton-mooc-mysql
+BACKOFFICE_DATABASE_PORT=3306
+BACKOFFICE_DATABASE_NAME=mooc
+BACKOFFICE_DATABASE_USER=root
+BACKOFFICE_DATABASE_PASSWORD=
+
+# Elasticsearch
+BACKOFFICE_ELASTICSEARCH_HOST=codely-php_ddd_skeleton-backoffice-elastic
+BACKOFFICE_ELASTICSEARCH_INDEX_PREFIX=backoffice
+
+# COMMON #
+#--------------------------------#
+# RabbitMQ
+RABBITMQ_HOST=codely-php_ddd_skeleton-rabbitmq
+RABBITMQ_PORT=5672
+RABBITMQ_LOGIN=codely
+RABBITMQ_PASSWORD=c0d3ly
+RABBITMQ_EXCHANGE=domain_events
+RABBITMQ_MAX_RETRIES=5
+# RabbitMQ - Application Specific
+RABBITMQ_MOOC_VHOST=/
diff --git a/.env.dist b/.env.dist
deleted file mode 100644
index e7f98b90f..000000000
--- a/.env.dist
+++ /dev/null
@@ -1,11 +0,0 @@
-SYMFONY_ENV=dev
-
-MYSQL_HOST=codelytv-cqrs_ddd_php_example-mysql
-MYSQL_PORT=3306
-MYSQL_ROOT_PASSWORD=c0dely
-MYSQL_DATABASE=codelytv-cqrs_ddd_php_example
-
-PHP_IDE_CONFIG=serverName=CodelyTvCqrsDddPhpExample
-
-RABBITMQ_DEFAULT_USER=codelytv
-RABBITMQ_DEFAULT_PASS=c0d3ly
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 000000000..740910fde
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: https://bit.ly/CodelyTvPro
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index 747f8b603..000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-# Number of days of inactivity before an issue becomes stale
-daysUntilStale: 30
-# Number of days of inactivity before a stale issue is closed
-daysUntilClose: 7
-# Issues with these labels will never be considered stale
-exemptLabels:
- - Enhancement
- - Hacktoberfest
- - Bug
- - β‘ To review
- - π¬ Reviewed
-# Label to use when marking an issue as stale
-staleLabel: Stale
-# Comment to post when marking an issue as stale. Set to `false` to disable
-markComment: >
- Issue automatically set as `Stale` after 30 days of inactivity.
- It will be closed in 7 days if we don't move it forward.
- We would like to maintain the repo as clean as possible.
- Thanks for your comprehension πΌ
-# Comment to post when closing a stale issue. Set to `false` to disable
-closeComment: >
- Issue automatically closed due to being inactive during 7 days after flagging it as `Stale`.
- We would like to maintain the repo as clean as possible. Thanks for your comprehension πΌ
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 000000000..39fe081e4
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,59 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - run: docker compose pull
+
+ - name: π» Install dependencies
+ run: make composer-install
+
+ - name: π³ Start all the environment
+ run: make start
+
+ - name: π¦ Lint
+ run: make lint
+
+ - name: π Static analysis
+ run: make static-analysis
+
+ - name: ποΈ Architecture
+ run: make test-architecture
+
+ - name: ποΈ Mess detector
+ run: make mess-detector
+
+ - name: π¦ Wait for the database to get up
+ run: |
+ while ! make ping-mysql &>/dev/null; do
+ echo "Waiting for database connection..."
+ sleep 2
+ done
+
+ - name: π§ͺ Wait for the Elasticsearch to get up
+ run: |
+ while ! make ping-elasticsearch &>/dev/null; do
+ echo "Waiting for elasticsearch connection..."
+ sleep 2
+ done
+
+ - name: π° Wait for RabbitMQ to get up
+ run: |
+ while ! make ping-rabbitmq &>/dev/null; do
+ echo "Waiting for RabbitMQ connection..."
+ sleep 2
+ done
+
+ - name: β
Run the tests
+ run: make test
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
new file mode 100644
index 000000000..e99bf3b81
--- /dev/null
+++ b/.github/workflows/labeler.yml
@@ -0,0 +1,18 @@
+name: labeler
+
+on: [pull_request]
+
+jobs:
+ labeler:
+ runs-on: ubuntu-latest
+ name: Label the PR size
+ steps:
+ - uses: codelytv/pr-size-labeler@v1.8.1
+ with:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ xs_max_size: '10'
+ s_max_size: '300'
+ m_max_size: '600'
+ l_max_size: '1400'
+ fail_if_xl: 'true'
+ files_to_ignore: 'composer.lock'
diff --git a/.gitignore b/.gitignore
index 81f30f819..a4b4f3437 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,16 +1,15 @@
-applications/*/var/*
-!applications/*/var/*/.gitkeep
+/.env.local
+/.env.*.local
-src/*/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/*_parameters.yml
-src/*/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/*_parameters.yml
+/apps/*/*/var/
+!/apps/*/*/var/.gitkeep
-/applications/mooc_backend/config/supervisor/*
-!/applications/mooc_backend/config/supervisor/.gitkeep
+/apps/*/*/build/
+!/apps/*/*/build/supervisor/.gitkeep
-/phpunit.xml
+/vendor/
+.phpunit.result.cache
-vendor/
+/build
-.env
-
-build/
+.php-cs-fixer.cache
diff --git a/Dockerfile b/Dockerfile
index 7586942af..dd0f725bf 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,19 +1,25 @@
-FROM php:7.3.6-fpm-alpine
+FROM php:8.3-fpm-alpine
WORKDIR /app
RUN apk --update upgrade \
- && apk add --no-cache autoconf automake make gcc g++ icu-dev rabbitmq-c rabbitmq-c-dev \
- && pecl install amqp-1.9.4 \
- && pecl install apcu-5.1.17 \
- && pecl install xdebug-2.7.0RC2 \
- && docker-php-ext-install -j$(nproc) \
+ && apk add --no-cache autoconf automake make gcc g++ git bash icu-dev libzip-dev rabbitmq-c rabbitmq-c-dev linux-headers
+
+RUN pecl install apcu-5.1.23 && pecl install amqp-2.1.1 && pecl install xdebug-3.3.0
+
+RUN docker-php-ext-install -j$(nproc) \
bcmath \
opcache \
intl \
- pdo_mysql \
- && docker-php-ext-enable \
- amqp \
- apcu \
- opcache
+ zip \
+ pdo_mysql
+
+RUN docker-php-ext-enable amqp apcu opcache
+
+RUN curl -sS https://get.symfony.com/cli/installer | bash -s - --install-dir /usr/local/bin
COPY etc/infrastructure/php/ /usr/local/etc/php/
+
+# allow non-root users have home
+RUN mkdir -p /opt/home
+RUN chmod 777 /opt/home
+ENV HOME /opt/home
diff --git a/LICENCE b/LICENCE
deleted file mode 100644
index 618e6b9b6..000000000
--- a/LICENCE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 CodelyTV soporte@codely.tv
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/Makefile b/Makefile
index 0fa4f6bb1..efec06c20 100644
--- a/Makefile
+++ b/Makefile
@@ -1,60 +1,54 @@
-.PHONY: all build deps composer-install composer-update composer reload test run-tests start stop destroy doco rebuild
-
current-dir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
-# π Main targets
-
-build: deps start
-
-deps: composer-install
-
-# π Composer
-
-composer-install: CMD=install
-composer-update: CMD=update
-
-# Usage example (add a new dependency): `make composer CMD="require --dev symfony/var-dumper ^4.2"`
-composer composer-install composer-update:
- @docker run --rm --interactive --tty --volume $(current-dir):/app --user $(id -u):$(id -g) \
- gsingh1/prestissimo $(CMD) \
+composer-install:
+ @docker run --rm $(INTERACTIVE) --volume $(current-dir):/app --user $(id -u):$(id -g) \
+ composer:2.6.4 install \
--ignore-platform-reqs \
- --no-ansi \
- --no-interaction
-
-# π΅οΈ Clear cache
-# OpCache: Restarts the unique process running in the PHP FPM container
-# Nginx: Reloads the server
+ --no-ansi
-reload:
- @docker-compose exec php-fpm kill -USR2 1
- @docker-compose exec nginx nginx -s reload
+test:
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/phpunit --testsuite mooc
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/phpunit --testsuite shared
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/behat -p mooc_backend --format=progress -v
+ docker exec codely-php_ddd_skeleton-backoffice_backend-php ./vendor/bin/phpunit --testsuite backoffice
-# β
Tests
+static-analysis:
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/psalm --output-format=github --shepherd
-test:
- @docker exec -it codelytv-cqrs_ddd_php_example-php make run-tests
+lint:
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/ecs check
-run-tests:
- mkdir -p build/test_results/phpunit
- ./vendor/bin/phpstan analyse -l 7 -c etc/phpstan/phpstan.neon applications/mooc_backend/src
- ./vendor/bin/phpunit --exclude-group='disabled' --log-junit build/test_results/phpunit/junit.xml tests
- ./vendor/bin/behat -p mooc_backend --format=progress -v
+test-architecture:
+ docker exec codely-php_ddd_skeleton-mooc_backend-php php -d memory_limit=4G ./vendor/bin/phpstan analyse --error-format=github
-# π³ Docker Compose
+mess-detector:
+ docker exec codely-php_ddd_skeleton-mooc_backend-php ./vendor/bin/phpmd apps,src,tests github phpmd.xml
start:
- @docker-compose up -d
+ @if [ ! -f .env.local ]; then echo '' > .env.local; fi
+ UID=${shell id -u} GID=${shell id -g} docker compose up --build -d
+ make clean-cache
-stop: CMD=stop
+stop:
+ UID=${shell id -u} GID=${shell id -g} docker compose stop
-destroy: CMD=down
-
-# Usage: `make doco CMD="ps --services"`
-# Usage: `make doco CMD="build --parallel --pull --force-rm --no-cache"`
-doco stop destroy:
- @docker-compose $(CMD)
+destroy:
+ UID=${shell id -u} GID=${shell id -g} docker compose down
rebuild:
- docker-compose build --pull --force-rm --no-cache
- make deps
+ docker compose build --pull --force-rm --no-cache
+ make install
make start
+
+ping-mysql:
+ @docker exec codely-php_ddd_skeleton-mooc-mysql mysqladmin --user=root --password= --host "127.0.0.1" ping --silent
+
+ping-elasticsearch:
+ @curl -I -XHEAD localhost:9200
+
+ping-rabbitmq:
+ @docker exec codely-php_ddd_skeleton-rabbitmq rabbitmqctl ping --silent
+
+clean-cache:
+ @rm -rf apps/*/*/var
+ @docker exec codely-php_ddd_skeleton-mooc_backend-php ./apps/mooc/backend/bin/console cache:warmup
diff --git a/README.md b/README.md
index 41ee70a98..85d72efbe 100644
--- a/README.md
+++ b/README.md
@@ -1,96 +1,79 @@
-
-
+
+
+
+
+
+
- ππ― Hexagonal Architecture, DDD & CQRS in PHP Symfony
+ ππ― Hexagonal Architecture, DDD & CQRS in PHP
-
+
-
-
+
+
+
- Example of a PHP application following Domain-Driven Design (DDD) and
- Command Query Responsibility Segregation (CQRS) principles keeping the code as simple as possible.
+ Example of a PHP application using Domain-Driven Design (DDD) and Command Query Responsibility Segregation
+ (CQRS) principles keeping the code as simple as possible.
Take a look, play and have fun with this.
- Stars are welcomed π
-
-
- Explore the docs Β»
+ Stars are welcome π
View Demo
Β·
- Report Bug
+ Report a bug
Β·
- Request Feature
+ Request a feature
-
-
-## Table of Contents
-
-* [π Environment setup](#-environment-setup)
- * [π³ Needed tools](#-needed-tools)
- * [π οΈ Environment configuration](#-environment-configuration)
- * [π Application execution](#-application-execution)
- * [β
Tests execution](#-tests-execution)
-* [π€ Project explanation](#-project-explanation)
- * [Bounded Contexts](#-bounded-contexts)
- * [Hexagonal Architecture](#-hexagonal-architecture)
- * [Aggregates](#aggregates)
- * [Command Bus](#command-bus)
- * [Query Bus](#query-bus)
- * [Event Bus](#event-bus)
-* [π€ Contributing](#-contributing)
-* [π€© Extra](#-extra)
-
-## π Environment setup
+## π Environment Setup
### π³ Needed tools
1. [Install Docker](https://www.docker.com/get-started)
-2. Clone this project: `git clone https://github.com/CodelyTV/cqrs-ddd-php-example cqrs-ddd-php-example`
-3. Move to the project folder: `cd cqrs-ddd-php-example`
+2. Clone this project: `git clone https://github.com/CodelyTV/php-ddd-example php-ddd-example`
+3. Move to the project folder: `cd php-ddd-example`
### π οΈ Environment configuration
-1. Copy the default environment variables: `cp .env.dist .env`
-2. Modify the environment variables if needed: `vim .env`
-3. Add `api.codelytv.localhost` domain to your local hosts: `echo "127.0.0.1 api.codelytv.localhost"| sudo tee -a /etc/hosts > /dev/null`
+1. Create a local environment file (`cp .env .env.local`) if you want to modify any parameter
-### π Application execution
+### π₯ Application execution
-1. Install PHP dependencies and bring up the project Docker containers with Docker Compose: `make build`
-2. Go to [the API health check page](http://api.codelytv.localhost:8030/status)
+1. Install all the dependencies and bring up the project with Docker executing: `make build`
+2. Then you'll have 3 apps available (2 APIs and 1 Frontend):
+ 1. [Mooc Backend](apps/mooc/backend): http://localhost:8030/health-check
+ 2. [Backoffice Backend](apps/backoffice/backend): http://localhost:8040/health-check
+ 3. [Backoffice Frontend](apps/backoffice/frontend): http://localhost:8041/health-check
### β
Tests execution
-1. Install PHP dependencies if you haven't done so: `make deps`
-2. Execute Behat and PHP Unit tests: `make test`
+1. Install the dependencies if you haven't done it previously: `make deps`
+2. Execute PHPUnit and Behat tests: `make test`
-## π€ Project explanation
+## π©βπ» Project explanation
-This project tries to be a MOOC (Massive Open Online Course) platform.
-For now it only has an [API](applications/mooc_backend/src/Controller)
-and some [Consumers](applications/mooc_backend/src/Command).
+This project tries to be a MOOC (Massive Open Online Course) platform. It's decoupled from any framework, but it has
+some Symfony and Laravel implementations.
### β±οΈ Bounded Contexts
-* [Mooc](src/Mooc): Place to look in if you wanna see some code π. Massive Open Online Courses public platform with users, videos, notifications, and so on
-* [Backoffice](src/Backoffice): Work in progress. Here you'll find the use cases needed by the Customer Support department in order to manage users, courses, videos, and so on.
+- [Mooc](src/Mooc): Place to look in if you wanna see some code π. Massive Open Online Courses public platform with users, videos, notifications, and so on.
+- [Backoffice](src/Backoffice): Here you'll find the use cases needed by the Customer Support department in order to manage users, courses, videos, and so on.
### π― Hexagonal Architecture
-This repository follow the Hexagonal Architecture pattern. Also is structured using `modules`.
+This repository follows the Hexagonal Architecture pattern. Also, it's structured using `modules`.
With this, we can see that the current structure of a Bounded Context is:
```scala
@@ -121,43 +104,63 @@ src
| `-- Infrastructure // The infrastructure of our module
| |-- DependencyInjection
| `-- Persistence
-| `--VideoRepositoryMySql.php // An implementation of the repository
+| `--MySqlVideoRepository.php // An implementation of the repository
`-- Shared // Shared Kernel: Common infrastructure and domain shared between the different Bounded Contexts
|-- Domain
`-- Infrastructure
```
#### Repository pattern
+
Our repositories try to be as simple as possible usually only containing 2 methods `search` and `save`.
-If we need some query with more filters we use the `Strategy` pattern also known as `Criteria` pattern. So we add a
+If we need some query with more filters we use the `Specification` pattern also known as `Criteria` pattern. So we add a
`searchByCriteria` method.
-You can see an example [here](src/Mooc/Videos/Domain/VideoRepository.php)
-and its implementation [here](src/Mooc/Videos/Infrastructure/Persistence/VideoRepositoryMySql.php).
+You can see an example [here](src/Mooc/Courses/Domain/CourseRepository.php)
+and its implementation [here](src/Mooc/Courses/Infrastructure/Persistence/DoctrineCourseRepository.php).
### Aggregates
-You can see an example of an aggregate [here](src/Mooc/Videos/Domain/Video.php). All aggregates should
-extends the [AggregateRoot](src/Shared/Domain/Aggregate/AggregateRoot.php).
+
+You can see an example of an aggregate [here](src/Mooc/Courses/Domain/Course.php). All aggregates should
+extend the [AggregateRoot](src/Shared/Domain/Aggregate/AggregateRoot.php).
### Command Bus
-There are 2 implementations of the [command bus](src/Shared/Domain/Bus/Command/CommandBus.php).
-1. [Sync](src/Shared/Infrastructure/Bus/Command/SymfonySyncCommandBus.php) using the Symfony Message Bus
-2. [Async](src/Shared/Infrastructure/Bus/Command/CommandBusAsync.php) using a local file
+
+There is 1 implementations of the [command bus](src/Shared/Domain/Bus/Command/CommandBus.php).
+1. [Sync](src/Shared/Infrastructure/Bus/Command/InMemorySymfonyCommandBus.php) using the Symfony Message Bus.
+
### Query Bus
-The [Query Bus](src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBus.php) uses the Symfony Message Bus.
+
+The [Query Bus](src/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBus.php) uses the Symfony Message Bus.
### Event Bus
-The [Event Bus](src/Shared/Infrastructure/Bus/Event/SymfonySyncEventBus.php) uses the Symfony Message Bus.
+
+The [Event Bus](src/Shared/Infrastructure/Bus/Event/InMemory/InMemorySymfonyEventBus.php) uses the Symfony Message Bus.
+The [MySql Bus](src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBus.php) uses a MySql+Pulling as a bus.
+The [RabbitMQ Bus](src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBus.php) uses RabbitMQ C extension.
+
+## π± Monitoring
+
+Every time a domain event is published it's exported to Prometheus. You can access to the Prometheus panel [here](http://localhost:9999/).
## π€ Contributing
+
There are some things missing (add swagger, improve documentation...), feel free to add this if you want! If you want
some guidelines feel free to contact us :)
## π€© Extra
-This code was show in the [From framework coupled code to #microservices through #DDD](http://codely.tv/screencasts/codigo-acoplado-framework-microservicios-ddd) talk and doubts where answered in [DDD y CQRS: Preguntas Frecuentes](http://codely.tv/screencasts/ddd-cqrs-preguntas-frecuentes/) video.
+
+This code was shown in the [From framework coupled code to #microservices through #DDD](http://codely.tv/blog/screencasts/codigo-acoplado-framework-microservicios-ddd) talk and doubts where answered in the [DDD y CQRS: Preguntas Frecuentes](https://codely.com/blog/ddd-cqrs-preguntas-frecuentes) video.
+
π₯ Used in the CodelyTV Pro courses:
-* [πͺπΈ Arquitectura Hexagonal](https://pro.codely.tv/library/arquitectura-hexagonal/66748/about/)
-* [πͺπΈ CQRS: Command Query Responsibility Segregation](https://pro.codely.tv/library/cqrs-command-query-responsibility-segregation-3719e4aa/62554/about/)
-* [πͺπΈ ComunicaciΓ³n entre microservicios: Event-Driven Architecture](https://pro.codely.tv/library/comunicacion-entre-microservicios-event-driven-architecture/74823/about/)
+
+- [πͺπΈ DDD in PHP](https://pro.codely.tv/library/ddd-en-php/about/)
+- [πͺπΈ Arquitectura Hexagonal](https://pro.codely.tv/library/arquitectura-hexagonal/66748/about/)
+- [πͺπΈ CQRS: Command Query Responsibility Segregation](https://pro.codely.tv/library/cqrs-command-query-responsibility-segregation-3719e4aa/62554/about/)
+- [πͺπΈ ComunicaciΓ³n entre microservicios: Event-Driven Architecture](https://pro.codely.tv/library/comunicacion-entre-microservicios-event-driven-architecture/74823/about/)
+
+## π remember to visit our courses
+
+- [Courses codely](https://codely.com/cursos)
diff --git a/applications/bootstrap.php b/applications/bootstrap.php
deleted file mode 100644
index e0cd2cfaf..000000000
--- a/applications/bootstrap.php
+++ /dev/null
@@ -1,7 +0,0 @@
-loadEnv(dirname(__DIR__) . '/.env');
diff --git a/applications/mooc_backend/bin/console b/applications/mooc_backend/bin/console
deleted file mode 100755
index f38aa9998..000000000
--- a/applications/mooc_backend/bin/console
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env php
-getParameterOption(['--env', '-e'], getenv('SYMFONY_ENV') ?: 'dev');
-$debug = getenv('SYMFONY_DEBUG') !== '0' && !$input->hasParameterOption(['--no-debug', '']) && $env !== 'prod';
-
-if ($debug) {
- Debug::enable();
-}
-
-$kernel = new MoocBackendKernel($env, $debug);
-$application = new Application($kernel);
-$application->run($input);
diff --git a/applications/mooc_backend/config/bundles.php b/applications/mooc_backend/config/bundles.php
deleted file mode 100644
index 17bf53423..000000000
--- a/applications/mooc_backend/config/bundles.php
+++ /dev/null
@@ -1,26 +0,0 @@
- ['all' => true],
- CodelyTvMoocBundle::class => ['all' => true],
-
- FrameworkBundle::class => ['all' => true],
- TwigBundle::class => ['all' => true],
-
- MonologBundle::class => ['all' => true],
-
- FOSRestBundle::class => ['all' => true],
- JMSSerializerBundle::class => ['all' => true],
-
- FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true]
-];
-
diff --git a/applications/mooc_backend/config/commands/commands.yml b/applications/mooc_backend/config/commands/commands.yml
deleted file mode 100644
index 2c64d313c..000000000
--- a/applications/mooc_backend/config/commands/commands.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-services:
-
- CodelyTv\MoocBackend\Command\GenerateSupervisorFilesCommand:
- arguments: ['@CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventSubscribersConfiguration']
- tags:
- - { name: console.command }
diff --git a/applications/mooc_backend/config/config.yml b/applications/mooc_backend/config/config.yml
deleted file mode 100644
index b1fe5ffed..000000000
--- a/applications/mooc_backend/config/config.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-imports:
- - { resource: controllers/_controllers.yml }
- - { resource: commands/commands.yml }
- - { resource: rest/_rest.yml }
- - { resource: logs.yml }
- - { resource: symfony.yml }
-
-
-framework:
- secret: 'secret'
diff --git a/applications/mooc_backend/config/config_dev.yml b/applications/mooc_backend/config/config_dev.yml
deleted file mode 100644
index b4058bd5b..000000000
--- a/applications/mooc_backend/config/config_dev.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - { resource: "config.yml" }
diff --git a/applications/mooc_backend/config/config_prod.yml b/applications/mooc_backend/config/config_prod.yml
deleted file mode 100644
index b4058bd5b..000000000
--- a/applications/mooc_backend/config/config_prod.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - { resource: "config.yml" }
diff --git a/applications/mooc_backend/config/config_test.yml b/applications/mooc_backend/config/config_test.yml
deleted file mode 100644
index 3169e2776..000000000
--- a/applications/mooc_backend/config/config_test.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-imports:
- - { resource: config_dev.yml }
-
-parameters:
-
- test.client.parameters:
- HTTP_HOST:
- HTTP_USER_AGENT:
- HTTP_ACCEPT:
- HTTP_ACCEPT_LANGUAGE:
- HTTP_ACCEPT_CHARSET:
- SERVER_PROTOCOL:
- REQUEST_TIME:
-
-framework:
-
- test: ~
-
-services:
- _defaults:
- autowire: true
- autoconfigure: true
-
- CodelyTv\Test\:
- resource: '../../../tests/src/**/*Context.php'
diff --git a/applications/mooc_backend/config/controllers/_controllers.yml b/applications/mooc_backend/config/controllers/_controllers.yml
deleted file mode 100644
index 85e0942a8..000000000
--- a/applications/mooc_backend/config/controllers/_controllers.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-imports:
-
- - { resource: course.yml }
- - { resource: status.yml }
- - { resource: student.yml }
- - { resource: video.yml }
diff --git a/applications/mooc_backend/config/controllers/course.yml b/applications/mooc_backend/config/controllers/course.yml
deleted file mode 100644
index bb070c9a3..000000000
--- a/applications/mooc_backend/config/controllers/course.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-services:
-
- codely.mooc_backend.controller.course.post:
- class: CodelyTv\MoocBackend\Controller\Course\CoursePostController
- parent: codely.mooc_backend.controller
- public: true
diff --git a/applications/mooc_backend/config/controllers/status.yml b/applications/mooc_backend/config/controllers/status.yml
deleted file mode 100644
index d7ab6ebe0..000000000
--- a/applications/mooc_backend/config/controllers/status.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-services:
-
- codely.mooc_backend.controller.status.get:
- class: CodelyTv\MoocBackend\Controller\Status\StatusGetController
- public: true
diff --git a/applications/mooc_backend/config/controllers/student.yml b/applications/mooc_backend/config/controllers/student.yml
deleted file mode 100644
index fc9922532..000000000
--- a/applications/mooc_backend/config/controllers/student.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-services:
-
- codely.mooc_backend.controller.student.put:
- class: CodelyTv\MoocBackend\Controller\Student\StudentPutController
- parent: codely.mooc_backend.controller
- public: true
-
- codely.mooc_backend.controller.student.get:
- class: CodelyTv\MoocBackend\Controller\Student\StudentGetController
- parent: codely.mooc_backend.controller
- public: true
diff --git a/applications/mooc_backend/config/controllers/video.yml b/applications/mooc_backend/config/controllers/video.yml
deleted file mode 100644
index 3d617d9c2..000000000
--- a/applications/mooc_backend/config/controllers/video.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-services:
-
- codely.mooc_backend.controller.video.post:
- class: CodelyTv\MoocBackend\Controller\Video\VideoPostController
- parent: codely.mooc_backend.controller
- public: true
-
- codely.mooc_backend.controller.video.get:
- class: CodelyTv\MoocBackend\Controller\Video\VideoGetController
- parent: codely.mooc_backend.controller
- public: true
-
- codely.mooc_backend.controller.video.duration.path:
- class: CodelyTv\MoocBackend\Controller\Video\VideoDurationPatchController
- parent: codely.mooc_backend.controller
- public: true
diff --git a/applications/mooc_backend/config/logs.yml b/applications/mooc_backend/config/logs.yml
deleted file mode 100644
index f94d0e5e1..000000000
--- a/applications/mooc_backend/config/logs.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-monolog:
-
- handlers:
- main:
- type: stream
- level: warning
- formatter: codely.infrastructure.monolog.formatter.logstash
- channels: ['!api']
- api_request:
- type: stream
- path: "%kernel.logs_dir%/%kernel.environment%.api.requests.log"
- level: warning
- formatter: codely.infrastructure.monolog.formatter.logstash
- channels: ['api']
- events:
- type: stream
- path: "%kernel.logs_dir%/%kernel.environment%.events.log"
- level: error
- formatter: codely.infrastructure.monolog.formatter.logstash
- channels: ['events']
- channels: ['api', 'events']
-
-
-services:
-
- monolog.processor.codely_request:
- class: CodelyTv\Shared\Infrastructure\Monolog\Processor\CodelyTvRequestProcessor
- arguments:
- - '@request_stack'
- tags:
- - { name: monolog.processor, handler: api_request }
-
- codely.infrastructure.monolog.formatter.logstash:
- class: CodelyTv\Shared\Infrastructure\Monolog\Formatter\LogstashFormatter
diff --git a/applications/mooc_backend/config/rest/_rest.yml b/applications/mooc_backend/config/rest/_rest.yml
deleted file mode 100644
index 8aa563825..000000000
--- a/applications/mooc_backend/config/rest/_rest.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-imports:
- - { resource: event_subscribers.yml }
- - { resource: fos_rest.yml }
- - { resource: jms_serializer.yml }
- - { resource: controllers.yml }
- - { resource: twig.yml }
diff --git a/applications/mooc_backend/config/rest/controllers.yml b/applications/mooc_backend/config/rest/controllers.yml
deleted file mode 100644
index bd8c92aec..000000000
--- a/applications/mooc_backend/config/rest/controllers.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-services:
-
- codely.mooc_backend.controller:
- class: CodelyTv\Shared\Infrastructure\Api\Controller\ApiController
- abstract: true
- arguments:
- - '@CodelyTv\Shared\Domain\Bus\Query\QueryBus'
- - '@CodelyTv\Shared\Domain\Bus\Command\CommandBus'
- - '@CodelyTv\Shared\Infrastructure\Api\Exception\ApiExceptionsHttpStatusCodeMapping'
diff --git a/applications/mooc_backend/config/rest/event_subscribers.yml b/applications/mooc_backend/config/rest/event_subscribers.yml
deleted file mode 100644
index d1a2c0faf..000000000
--- a/applications/mooc_backend/config/rest/event_subscribers.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-services:
-
- codely.mooc_backend.subscriber.exception_response:
- class: CodelyTv\Shared\Infrastructure\Api\EventSubscriber\ApiExceptionSubscriber
- arguments:
- - '@fos_rest.view_handler.default'
- - '@CodelyTv\Shared\Infrastructure\Api\Exception\ApiExceptionsHttpStatusCodeMapping'
- tags:
- - { name: kernel.event_subscriber }
-
- codely.mooc_backend.subscriber.exception_logger:
- class: CodelyTv\Shared\Infrastructure\Api\EventSubscriber\ApiExceptionLoggerSubscriber
- arguments:
- - '@monolog.logger.api'
- - '@CodelyTv\Shared\Infrastructure\Api\Exception\ApiExceptionsHttpStatusCodeMapping'
- tags:
- - { name: kernel.event_subscriber }
-
- codely.mooc_backend.subscriber.response_view:
- class: CodelyTv\Shared\Infrastructure\Api\EventSubscriber\ApiResponseViewSubscriber
- tags:
- - { name: kernel.event_subscriber }
-
- CodelyTv\Shared\Infrastructure\Api\Exception\ApiExceptionsHttpStatusCodeMapping: ~
diff --git a/applications/mooc_backend/config/rest/fos_rest.yml b/applications/mooc_backend/config/rest/fos_rest.yml
deleted file mode 100644
index 6cf85f0b8..000000000
--- a/applications/mooc_backend/config/rest/fos_rest.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-fos_rest:
-
- format_listener:
- rules:
- - path: ~
- host: ~
- prefer_extension: false
- fallback_format: json
-
- view:
- view_response_listener: force
-
- serializer:
- serialize_null: true
diff --git a/applications/mooc_backend/config/rest/jms_serializer.yml b/applications/mooc_backend/config/rest/jms_serializer.yml
deleted file mode 100644
index 5e9d19964..000000000
--- a/applications/mooc_backend/config/rest/jms_serializer.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-jms_serializer:
-
- visitors:
- json:
- options: JSON_PRETTY_PRINT
-
-
-services:
-
- codely.mooc_backend.serializer.metadata.php_driver:
- class: CodelyTv\Shared\Infrastructure\Api\Serializer\ApiSerializerDriver
-
- jms_serializer.metadata_driver:
- alias: codely.mooc_backend.serializer.metadata.php_driver
- public: true
-
-
-parameters:
-
- jms_serializer.infer_types_from_doctrine_metadata: false
- jms_serializer.datetime_handler.class: CodelyTv\Shared\Infrastructure\Api\Serializer\DateTimeHandler
diff --git a/applications/mooc_backend/config/rest/twig.yml b/applications/mooc_backend/config/rest/twig.yml
deleted file mode 100644
index 42d272f99..000000000
--- a/applications/mooc_backend/config/rest/twig.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-twig:
- strict_variables: '%kernel.debug%'
diff --git a/applications/mooc_backend/config/routing/_routing.yml b/applications/mooc_backend/config/routing/_routing.yml
deleted file mode 100644
index 93944875c..000000000
--- a/applications/mooc_backend/config/routing/_routing.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-status:
- resource: status.yml
-
-student:
- resource: student.yml
-
-video:
- resource: video.yml
diff --git a/applications/mooc_backend/config/routing/status.yml b/applications/mooc_backend/config/routing/status.yml
deleted file mode 100644
index 2a63a7d88..000000000
--- a/applications/mooc_backend/config/routing/status.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-status_get:
- path: /status
- defaults: { _controller: codely.mooc_backend.controller.status.get }
- methods: [GET]
diff --git a/applications/mooc_backend/config/routing/student.yml b/applications/mooc_backend/config/routing/student.yml
deleted file mode 100644
index cb40bf800..000000000
--- a/applications/mooc_backend/config/routing/student.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-student_put:
- path: /students/{id}
- defaults: { _controller: codely.mooc_backend.controller.student.put }
- methods: [PUT]
-
-student_get:
- path: /students/{id}
- defaults: { _controller: codely.mooc_backend.controller.student.get }
- methods: [GET]
diff --git a/applications/mooc_backend/config/routing/video.yml b/applications/mooc_backend/config/routing/video.yml
deleted file mode 100644
index cdef44024..000000000
--- a/applications/mooc_backend/config/routing/video.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-video_post:
- path: /video
- defaults: { _controller: codely.mooc_backend.controller.video.post }
- methods: [POST]
-
-video_get:
- path: /video/{id}
- defaults: { _controller: codely.mooc_backend.controller.video.get }
- methods: [GET]
diff --git a/applications/mooc_backend/config/symfony.yml b/applications/mooc_backend/config/symfony.yml
deleted file mode 100644
index dcb4795f7..000000000
--- a/applications/mooc_backend/config/symfony.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-framework:
-
- secret: 'secret'
- router:
- resource: '%kernel.root_dir%/config/routing/_routing.yml'
- strict_requirements: '%kernel.debug%'
- templating:
- engines: ['twig']
- default_locale: 'en'
- session: ~
- fragments: ~
- http_method_override: true
diff --git a/applications/mooc_backend/src/Command/ConsumeDomainEventsCommand.php b/applications/mooc_backend/src/Command/ConsumeDomainEventsCommand.php
deleted file mode 100644
index 05e479f1e..000000000
--- a/applications/mooc_backend/src/Command/ConsumeDomainEventsCommand.php
+++ /dev/null
@@ -1,61 +0,0 @@
-consumer = $consumer;
- $this->mapping = $mapping;
- $this->connections = $connections;
- }
-
- protected function configure(): void
- {
- $this
- ->setName('codelytv:domain-events:consume')
- ->setDescription('Consume domain events')
- ->addArgument('subscriber', InputArgument::REQUIRED, 'Subscriber to process')
- ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of events to process');
- }
-
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- /** @var string $subscriberName */
- $subscriberName = $input->getArgument('subscriber');
- /** @var int $messagesToProcess */
- $messagesToProcess = $input->getArgument('quantity');
-
- repeat(pipe($this->consume($subscriberName), $this->connections->allConnectionsClearer()), $messagesToProcess);
- }
-
- private function consume(string $subscriberName): callable
- {
- return function () use ($subscriberName) {
- apply($this->consumer, [$this->mapping->byName($subscriberName), $subscriberName]);
- };
- }
-}
diff --git a/applications/mooc_backend/src/Command/GenerateSupervisorFilesCommand.php b/applications/mooc_backend/src/Command/GenerateSupervisorFilesCommand.php
deleted file mode 100644
index a518db485..000000000
--- a/applications/mooc_backend/src/Command/GenerateSupervisorFilesCommand.php
+++ /dev/null
@@ -1,75 +0,0 @@
-configuration = $configuration;
- }
-
- protected function configure(): void
- {
- $this
- ->setName('codelytv:domain-events:generate-supervisor-files')
- ->setDescription('Generate the supervisor configuration for every subscriber')
- ->addArgument('command-path', InputArgument::OPTIONAL, 'Path on this is gonna be deployed', '/var/www');
- }
-
- protected function execute(InputInterface $input, OutputInterface $output)
- {
- /** @var string $path */
- $path = $input->getArgument('command-path');
-
- each($this->configCreator($path), $this->configuration->all());
- }
-
- private function configCreator(string $path): callable
- {
- return function (DomainEventSubscriberConfig $config) use ($path) {
- $fileContent = str_replace(
- ['{subscriber}', '{path}', '{processes}', '{events_to_process}', '{enabled}'],
- [$config->name(), $path, $config->processes(), $config->eventsToProcess(), $config->enabledString()],
- $this->template()
- );
-
- file_put_contents($this->fileName($config->name()), $fileContent);
- };
- }
-
- private function template(): string
- {
- return <<asyncRequestFinder = $asyncRequestFinder;
- $this->exceptionHandler = $exceptionHandler;
-
- each($this->exceptionRegistrar(), $this->exceptions());
- }
-
- public function __invoke($requestId)
- {
- $asyncRequest = $this->asyncRequestFinder->__invoke(new Uuid($requestId));
-
- return $asyncRequest->toArray();
- }
-
- private function exceptions(): array
- {
- return [
- AsyncRequestNotExists::class => Response::HTTP_NOT_FOUND,
- ];
- }
-
- private function exceptionRegistrar(): callable
- {
- return function ($httpCode, $exception) {
- $this->exceptionHandler->register($exception, $httpCode);
- };
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Course/CoursePostController.php b/applications/mooc_backend/src/Controller/Course/CoursePostController.php
deleted file mode 100644
index 7991526fa..000000000
--- a/applications/mooc_backend/src/Controller/Course/CoursePostController.php
+++ /dev/null
@@ -1,33 +0,0 @@
-get('request_id')),
- $request->get('id'),
- $request->get('title'),
- $request->get('description')
- );
-
- $this->dispatch($command);
-
- return new ApiHttpCreatedResponse();
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Status/StatusGetController.php b/applications/mooc_backend/src/Controller/Status/StatusGetController.php
deleted file mode 100644
index b455ecaba..000000000
--- a/applications/mooc_backend/src/Controller/Status/StatusGetController.php
+++ /dev/null
@@ -1,15 +0,0 @@
- 'OK']);
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Student/StudentGetController.php b/applications/mooc_backend/src/Controller/Student/StudentGetController.php
deleted file mode 100644
index b51463eda..000000000
--- a/applications/mooc_backend/src/Controller/Student/StudentGetController.php
+++ /dev/null
@@ -1,25 +0,0 @@
- Response::HTTP_NOT_FOUND,
- ];
- }
-
- public function __invoke(string $id)
- {
- return $this->ask(new FindStudentQuery($id));
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Student/StudentPutController.php b/applications/mooc_backend/src/Controller/Student/StudentPutController.php
deleted file mode 100644
index aa852ada1..000000000
--- a/applications/mooc_backend/src/Controller/Student/StudentPutController.php
+++ /dev/null
@@ -1,21 +0,0 @@
-get('request_id'));
-
- $command = new TrimVideoCommand(
- $requestId,
- $videoId,
- $request->get('keep_from_second'),
- $request->get('keep_to_second')
- );
-
- $this->dispatch($command);
-
- return new ApiHttpAcceptedResponse($request->getPathInfo(), $requestId);
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Video/VideoGetController.php b/applications/mooc_backend/src/Controller/Video/VideoGetController.php
deleted file mode 100644
index 9d559b0ad..000000000
--- a/applications/mooc_backend/src/Controller/Video/VideoGetController.php
+++ /dev/null
@@ -1,25 +0,0 @@
- Response::HTTP_NOT_FOUND,
- ];
- }
-
- public function __invoke(string $id)
- {
- return $this->ask(new FindVideoQuery($id));
- }
-}
diff --git a/applications/mooc_backend/src/Controller/Video/VideoPostController.php b/applications/mooc_backend/src/Controller/Video/VideoPostController.php
deleted file mode 100644
index 04b57969c..000000000
--- a/applications/mooc_backend/src/Controller/Video/VideoPostController.php
+++ /dev/null
@@ -1,35 +0,0 @@
-get('request_id')),
- $request->get('id'),
- $request->get('type'),
- $request->get('title'),
- $request->get('url'),
- $request->get('course_id')
- );
-
- $this->dispatch($command);
-
- return new ApiHttpCreatedResponse();
- }
-}
diff --git a/applications/mooc_backend/src/MoocBackendKernel.php b/applications/mooc_backend/src/MoocBackendKernel.php
deleted file mode 100644
index dd9305369..000000000
--- a/applications/mooc_backend/src/MoocBackendKernel.php
+++ /dev/null
@@ -1,74 +0,0 @@
-getRootDir() . '/config/bundles.php';
-
- return map($this->instanciateBundle(), filter($this->hasToBeRemoved(), $bundles));
- }
-
- public function getCacheDir()
- {
- return $this->getRootDir() . '/var/cache';
- }
-
- public function getLogDir()
- {
- return $this->getRootDir() . '/var/logs';
- }
-
- public function registerContainerConfiguration(LoaderInterface $loader)
- {
- $loader->load($this->getRootDir() . '/config/config_' . $this->getEnvironment() . '.yml');
- }
-
- public function getContainer()
- {
- $this->bootKernelInTestEnvironmentToDiscoverErrorsWhenDeveloping();
-
- return parent::getContainer();
- }
-
- private function bootKernelInTestEnvironmentToDiscoverErrorsWhenDeveloping(): void
- {
- if ('test' === $this->getEnvironment()) {
- $this->boot();
- }
- }
-
- public function getRootDir(): string
- {
- return dirname(__DIR__);
- }
-
- private function hasToBeRemoved(): callable
- {
- return function (array $environmentOptions) {
- if ('test' === $this->getEnvironment()) {
- return true;
- }
-
- return !array_key_exists('test', $environmentOptions);
- };
- }
-
- private function instanciateBundle(): callable
- {
- return function (array $unused, $class) {
- return new $class();
- };
- }
-}
diff --git a/applications/mooc_backend/web/api.php b/applications/mooc_backend/web/api.php
deleted file mode 100644
index 15afdc26f..000000000
--- a/applications/mooc_backend/web/api.php
+++ /dev/null
@@ -1,18 +0,0 @@
-server->get('REMOTE_ADDR')], Request::HEADER_X_FORWARDED_ALL);
-
-$response = $kernel->handle($request);
-$response->send();
-$kernel->terminate($request, $response);
diff --git a/apps/backoffice/backend/bin/console b/apps/backoffice/backend/bin/console
new file mode 100755
index 000000000..29bc8b83f
--- /dev/null
+++ b/apps/backoffice/backend/bin/console
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getParameterOption(['--env', '-e'], null, true)) {
+ putenv('APP_ENV=' . $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
+}
+
+if ($input->hasParameterOption('--no-debug', true)) {
+ putenv('APP_DEBUG=' . $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
+}
+
+require dirname(__DIR__) . '/../../bootstrap.php';
+
+if ($_SERVER['APP_DEBUG']) {
+ umask(0000);
+
+ if (class_exists(Debug::class)) {
+ Debug::enable();
+ }
+}
+
+$kernel = new BackofficeBackendKernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
+$application = new Application($kernel);
+$application->run($input);
diff --git a/apps/backoffice/backend/config/bundles.php b/apps/backoffice/backend/config/bundles.php
new file mode 100644
index 000000000..15c297c9f
--- /dev/null
+++ b/apps/backoffice/backend/config/bundles.php
@@ -0,0 +1,9 @@
+ ['all' => true],
+ FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true],
+ // WouterJ\EloquentBundle\WouterJEloquentBundle::class => ['test' => true]
+];
diff --git a/apps/backoffice/backend/config/routes/courses.yaml b/apps/backoffice/backend/config/routes/courses.yaml
new file mode 100644
index 000000000..06ae46ee8
--- /dev/null
+++ b/apps/backoffice/backend/config/routes/courses.yaml
@@ -0,0 +1,5 @@
+courses_get:
+ path: /courses
+ controller: CodelyTv\Apps\Backoffice\Backend\Controller\Courses\CoursesGetController
+ defaults: { auth: false }
+ methods: [GET]
diff --git a/apps/backoffice/backend/config/routes/health-check.yaml b/apps/backoffice/backend/config/routes/health-check.yaml
new file mode 100644
index 000000000..37223ceda
--- /dev/null
+++ b/apps/backoffice/backend/config/routes/health-check.yaml
@@ -0,0 +1,4 @@
+health-check_get:
+ path: /health-check
+ controller: CodelyTv\Apps\Backoffice\Backend\Controller\HealthCheck\HealthCheckGetController
+ methods: [GET]
diff --git a/apps/backoffice/backend/config/routes/metrics.yaml b/apps/backoffice/backend/config/routes/metrics.yaml
new file mode 100644
index 000000000..af36aa15d
--- /dev/null
+++ b/apps/backoffice/backend/config/routes/metrics.yaml
@@ -0,0 +1,4 @@
+metrics_get:
+ path: /metrics
+ controller: CodelyTv\Apps\Backoffice\Backend\Controller\Metrics\MetricsController
+ methods: [GET]
diff --git a/apps/backoffice/backend/config/services.yaml b/apps/backoffice/backend/config/services.yaml
new file mode 100644
index 000000000..d0e25db62
--- /dev/null
+++ b/apps/backoffice/backend/config/services.yaml
@@ -0,0 +1,98 @@
+imports:
+ - { resource: ../../../../src/Backoffice/Shared/Infrastructure/Symfony/DependencyInjection/backoffice_services.yaml }
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ # Configure
+ _instanceof:
+ CodelyTv\Shared\Domain\Bus\Event\DomainEventSubscriber:
+ tags: ['codely.domain_event_subscriber']
+
+ CodelyTv\Shared\Domain\Bus\Command\CommandHandler:
+ tags: ['codely.command_handler']
+
+ CodelyTv\Shared\Domain\Bus\Query\QueryHandler:
+ tags: ['codely.query_handler']
+
+ CodelyTv\Apps\Backoffice\Backend\Controller\:
+ resource: '../src/Controller'
+ tags: ['controller.service_arguments']
+
+
+ # Wire
+ CodelyTv\Shared\:
+ resource: '../../../../src/Shared'
+
+ CodelyTv\Backoffice\:
+ resource: '../../../../src/Backoffice'
+
+ # -- TAGGING --
+ CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus:
+ arguments: [!tagged codely.domain_event_subscriber]
+ lazy: true
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventMapping:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventSubscriberLocator:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Doctrine\DatabaseConnections:
+ arguments: [!tagged codely.database_connection]
+
+ CodelyTv\Shared\Infrastructure\Symfony\AddJsonBodyToRequestListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
+
+ CodelyTv\Shared\Infrastructure\Symfony\ApiExceptionListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.exception, method: onException }
+
+ CodelyTv\Shared\Infrastructure\Symfony\BasicHttpAuthMiddleware:
+ tags:
+ - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
+
+
+ # -- APP DEFINITIONS --
+ # Command/Query Handlers
+ CodelyTv\Shared\Infrastructure\Bus\Command\InMemorySymfonyCommandBus:
+ arguments: [!tagged codely.command_handler]
+
+ CodelyTv\Shared\Infrastructure\Bus\Query\InMemorySymfonyQueryBus:
+ arguments: [!tagged codely.query_handler]
+
+ # RabbitMQ
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection:
+ arguments:
+ - host: '%env(RABBITMQ_HOST)%'
+ port: '%env(RABBITMQ_PORT)%'
+ vhost: '%env(RABBITMQ_MOOC_VHOST)%'
+ login: '%env(RABBITMQ_LOGIN)%'
+ password: '%env(RABBITMQ_PASSWORD)%'
+ read_timeout: 2
+ write_timeout: 2
+ connect_timeout: 5
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection', '%env(RABBITMQ_EXCHANGE)%']
+
+ CodelyTv\Shared\Infrastructure\Elasticsearch\ElasticsearchClient:
+ factory: '@CodelyTv\Shared\Infrastructure\Elasticsearch\ElasticsearchClientFactory'
+ arguments:
+ - '%env(BACKOFFICE_ELASTICSEARCH_HOST)%'
+ - '%env(BACKOFFICE_ELASTICSEARCH_INDEX_PREFIX)%'
+ - '%kernel.project_dir%/../../../etc/databases/backoffice'
+ - '%env(APP_ENV)%'
+ public: true
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Monitoring\PrometheusMonitor', 'backoffice_backend', '@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus']
+
+ # -- IMPLEMENTATIONS SELECTOR --
+
+ # -- IMPLEMENTATIONS SELECTOR --
+ CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus'
+ CodelyTv\Backoffice\Courses\Domain\BackofficeCourseRepository: '@CodelyTv\Backoffice\Courses\Infrastructure\Persistence\ElasticsearchBackofficeCourseRepository'
diff --git a/apps/backoffice/backend/config/services/framework.yaml b/apps/backoffice/backend/config/services/framework.yaml
new file mode 100644
index 000000000..b7cea6492
--- /dev/null
+++ b/apps/backoffice/backend/config/services/framework.yaml
@@ -0,0 +1,17 @@
+framework:
+ secret: '%env(APP_SECRET)%'
+ #csrf_protection: true
+ #http_method_override: true
+
+ # Enables session support. Note that the session will ONLY be started if you read or write from it.
+ # Remove or comment this section to explicitly disable session support.
+ session:
+ handler_id: null
+ cookie_secure: auto
+ cookie_samesite: lax
+ enabled: true
+
+ #esi: true
+ #fragments: true
+ php_errors:
+ log: true
diff --git a/apps/backoffice/backend/config/services_test.yaml b/apps/backoffice/backend/config/services_test.yaml
new file mode 100644
index 000000000..3a81827df
--- /dev/null
+++ b/apps/backoffice/backend/config/services_test.yaml
@@ -0,0 +1,13 @@
+framework:
+ test: true
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ CodelyTv\Tests\:
+ resource: '../../../../tests'
+
+ # -- IMPLEMENTATIONS SELECTOR --
+ CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus'
diff --git a/apps/backoffice/backend/public/index.php b/apps/backoffice/backend/public/index.php
new file mode 100644
index 000000000..45fd7eab5
--- /dev/null
+++ b/apps/backoffice/backend/public/index.php
@@ -0,0 +1,32 @@
+handle($request);
+$response->send();
+$kernel->terminate($request, $response);
diff --git a/apps/backoffice/backend/src/BackofficeBackendKernel.php b/apps/backoffice/backend/src/BackofficeBackendKernel.php
new file mode 100644
index 000000000..321bf5524
--- /dev/null
+++ b/apps/backoffice/backend/src/BackofficeBackendKernel.php
@@ -0,0 +1,46 @@
+getProjectDir() . '/config/bundles.php';
+ foreach ($contents as $class => $envs) {
+ if ($envs[$this->environment] ?? $envs['all'] ?? false) {
+ yield new $class();
+ }
+ }
+ }
+
+ public function getProjectDir(): string
+ {
+ return dirname(__DIR__);
+ }
+
+ protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
+ {
+ $container->addResource(new FileResource($this->getProjectDir() . '/config/bundles.php'));
+ $container->setParameter('.container.dumper.inline_class_loader', true);
+ $confDir = $this->getProjectDir() . '/config';
+
+ $loader->load($confDir . '/services' . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services/*' . self::CONFIG_EXTS, 'glob');
+ }
+}
diff --git a/apps/backoffice/backend/src/Controller/Courses/CoursesGetController.php b/apps/backoffice/backend/src/Controller/Courses/CoursesGetController.php
new file mode 100644
index 000000000..4fcf89a26
--- /dev/null
+++ b/apps/backoffice/backend/src/Controller/Courses/CoursesGetController.php
@@ -0,0 +1,51 @@
+query->get('order_by');
+ $order = $request->query->get('order');
+ $limit = $request->query->get('limit');
+ $offset = $request->query->get('offset');
+
+ /** @var BackofficeCoursesResponse $response */
+ $response = $this->queryBus->ask(
+ new SearchBackofficeCoursesByCriteriaQuery(
+ (array) $request->query->get('filters'),
+ $orderBy,
+ $order,
+ $limit === null ? null : (int) $limit,
+ $offset === null ? null : (int) $offset
+ )
+ );
+
+ return new JsonResponse(
+ map(
+ fn (BackofficeCourseResponse $course): array => [
+ 'id' => $course->id(),
+ 'name' => $course->name(),
+ 'duration' => $course->duration(),
+ ],
+ $response->courses()
+ ),
+ 200,
+ ['Access-Control-Allow-Origin' => '*']
+ );
+ }
+}
diff --git a/apps/backoffice/backend/src/Controller/HealthCheck/HealthCheckGetController.php b/apps/backoffice/backend/src/Controller/HealthCheck/HealthCheckGetController.php
new file mode 100644
index 000000000..fe2256009
--- /dev/null
+++ b/apps/backoffice/backend/src/Controller/HealthCheck/HealthCheckGetController.php
@@ -0,0 +1,20 @@
+ 'ok',
+ ]
+ );
+ }
+}
diff --git a/apps/backoffice/backend/src/Controller/Metrics/MetricsController.php b/apps/backoffice/backend/src/Controller/Metrics/MetricsController.php
new file mode 100644
index 000000000..e0ae59059
--- /dev/null
+++ b/apps/backoffice/backend/src/Controller/Metrics/MetricsController.php
@@ -0,0 +1,23 @@
+render($this->monitor->registry()->getMetricFamilySamples());
+
+ return new Response($result, 200, ['Content-Type' => RenderTextFormat::MIME_TYPE]);
+ }
+}
diff --git a/applications/mooc_backend/config/supervisor/.gitkeep b/apps/backoffice/backend/var/.gitkeep
similarity index 100%
rename from applications/mooc_backend/config/supervisor/.gitkeep
rename to apps/backoffice/backend/var/.gitkeep
diff --git a/apps/backoffice/frontend/bin/console b/apps/backoffice/frontend/bin/console
new file mode 100755
index 000000000..d680ab53c
--- /dev/null
+++ b/apps/backoffice/frontend/bin/console
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getParameterOption(['--env', '-e'], null, true)) {
+ putenv('APP_ENV=' . $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
+}
+
+if ($input->hasParameterOption('--no-debug', true)) {
+ putenv('APP_DEBUG=' . $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
+}
+
+require dirname(__DIR__) . '/../../bootstrap.php';
+
+if ($_SERVER['APP_DEBUG']) {
+ umask(0000);
+
+ if (class_exists(Debug::class)) {
+ Debug::enable();
+ }
+}
+
+$kernel = new BackofficeFrontendKernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
+$application = new Application($kernel);
+$application->run($input);
diff --git a/apps/backoffice/frontend/config/bundles.php b/apps/backoffice/frontend/config/bundles.php
new file mode 100644
index 000000000..ef8009558
--- /dev/null
+++ b/apps/backoffice/frontend/config/bundles.php
@@ -0,0 +1,10 @@
+ ['all' => true],
+ FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true],
+ Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
+ // WouterJ\EloquentBundle\WouterJEloquentBundle::class => ['test' => true]
+];
diff --git a/apps/backoffice/frontend/config/routes/api_courses.yaml b/apps/backoffice/frontend/config/routes/api_courses.yaml
new file mode 100644
index 000000000..3be1e106f
--- /dev/null
+++ b/apps/backoffice/frontend/config/routes/api_courses.yaml
@@ -0,0 +1,4 @@
+api_courses_get:
+ path: /api/courses
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\Courses\ApiCoursesGetController
+ methods: [GET]
diff --git a/apps/backoffice/frontend/config/routes/courses.yaml b/apps/backoffice/frontend/config/routes/courses.yaml
new file mode 100644
index 000000000..bb3b30cde
--- /dev/null
+++ b/apps/backoffice/frontend/config/routes/courses.yaml
@@ -0,0 +1,9 @@
+courses_get:
+ path: /courses
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\Courses\CoursesGetWebController
+ methods: [GET]
+
+courses_post:
+ path: /courses
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\Courses\CoursesPostWebController
+ methods: [POST]
diff --git a/apps/backoffice/frontend/config/routes/health-check.yaml b/apps/backoffice/frontend/config/routes/health-check.yaml
new file mode 100644
index 000000000..c5035a4bc
--- /dev/null
+++ b/apps/backoffice/frontend/config/routes/health-check.yaml
@@ -0,0 +1,4 @@
+health-check_get:
+ path: /health-check
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\HealthCheck\HealthCheckGetController
+ methods: [GET]
diff --git a/apps/backoffice/frontend/config/routes/home.yaml b/apps/backoffice/frontend/config/routes/home.yaml
new file mode 100644
index 000000000..687b22467
--- /dev/null
+++ b/apps/backoffice/frontend/config/routes/home.yaml
@@ -0,0 +1,4 @@
+home_get:
+ path: /
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\Home\HomeGetWebController
+ methods: [GET]
diff --git a/apps/backoffice/frontend/config/routes/metrics.yaml b/apps/backoffice/frontend/config/routes/metrics.yaml
new file mode 100644
index 000000000..65ad0004d
--- /dev/null
+++ b/apps/backoffice/frontend/config/routes/metrics.yaml
@@ -0,0 +1,4 @@
+metrics_get:
+ path: /metrics
+ controller: CodelyTv\Apps\Backoffice\Frontend\Controller\Metrics\MetricsController
+ methods: [GET]
diff --git a/apps/backoffice/frontend/config/services.yaml b/apps/backoffice/frontend/config/services.yaml
new file mode 100644
index 000000000..23de22805
--- /dev/null
+++ b/apps/backoffice/frontend/config/services.yaml
@@ -0,0 +1,106 @@
+imports:
+ - { resource: ../../../../src/Backoffice/Shared/Infrastructure/Symfony/DependencyInjection/backoffice_services.yaml }
+ - { resource: ../../../../src/Mooc/Shared/Infrastructure/Symfony/DependencyInjection/mooc_services.yaml }
+
+framework:
+ session:
+ handler_id: null
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ # Configure
+ _instanceof:
+ CodelyTv\Shared\Domain\Bus\Event\DomainEventSubscriber:
+ tags: ['codely.domain_event_subscriber']
+
+ CodelyTv\Shared\Domain\Bus\Command\CommandHandler:
+ tags: ['codely.command_handler']
+
+ CodelyTv\Shared\Domain\Bus\Query\QueryHandler:
+ tags: ['codely.query_handler']
+
+ CodelyTv\Apps\Backoffice\Frontend\Controller\:
+ resource: '../src/Controller'
+ tags: ['controller.service_arguments']
+
+
+ # Wire
+ CodelyTv\Shared\:
+ resource: '../../../../src/Shared'
+
+ CodelyTv\Backoffice\:
+ resource: '../../../../src/Backoffice'
+
+ CodelyTv\Mooc\:
+ resource: '../../../../src/Mooc'
+
+ # -- TAGGING --
+ CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus:
+ arguments: [!tagged codely.domain_event_subscriber]
+ lazy: true
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventMapping:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventSubscriberLocator:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Doctrine\DatabaseConnections:
+ arguments: [!tagged codely.database_connection]
+
+ CodelyTv\Shared\Infrastructure\Symfony\ApiExceptionListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.exception, method: onException }
+
+ CodelyTv\Shared\Infrastructure\Symfony\AddJsonBodyToRequestListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
+
+
+ # -- APP DEFINITIONS --
+ # Command/Query Handlers
+ CodelyTv\Shared\Infrastructure\Bus\Command\InMemorySymfonyCommandBus:
+ arguments: [!tagged codely.command_handler]
+
+ CodelyTv\Shared\Infrastructure\Bus\Query\InMemorySymfonyQueryBus:
+ arguments: [!tagged codely.query_handler]
+
+ # RabbitMQ
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection:
+ arguments:
+ - host: '%env(RABBITMQ_HOST)%'
+ port: '%env(RABBITMQ_PORT)%'
+ vhost: '%env(RABBITMQ_MOOC_VHOST)%'
+ login: '%env(RABBITMQ_LOGIN)%'
+ password: '%env(RABBITMQ_PASSWORD)%'
+ read_timeout: 2
+ write_timeout: 2
+ connect_timeout: 5
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection', '%env(RABBITMQ_EXCHANGE)%']
+
+ CodelyTv\Shared\Infrastructure\Elasticsearch\ElasticsearchClient:
+ factory: '@CodelyTv\Shared\Infrastructure\Elasticsearch\ElasticsearchClientFactory'
+ arguments:
+ - '%env(BACKOFFICE_ELASTICSEARCH_HOST)%'
+ - '%env(BACKOFFICE_ELASTICSEARCH_INDEX_PREFIX)%'
+ - '%kernel.project_dir%/../../../etc/databases/backoffice'
+ - '%env(APP_ENV)%'
+ public: true
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Monitoring\PrometheusMonitor', 'backoffice_frontend', '@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus']
+
+ # -- IMPLEMENTATIONS SELECTOR --
+ CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus'
+ CodelyTv\Backoffice\Courses\Domain\BackofficeCourseRepository: '@CodelyTv\Backoffice\Courses\Infrastructure\Persistence\ElasticsearchBackofficeCourseRepository'
+
+twig:
+ default_path: '%kernel.project_dir%/templates'
+ strict_variables: true
+ globals:
+ flash: '@CodelyTv\Shared\Infrastructure\Symfony\FlashSession'
diff --git a/apps/backoffice/frontend/config/services/framework.yaml b/apps/backoffice/frontend/config/services/framework.yaml
new file mode 100644
index 000000000..b7cea6492
--- /dev/null
+++ b/apps/backoffice/frontend/config/services/framework.yaml
@@ -0,0 +1,17 @@
+framework:
+ secret: '%env(APP_SECRET)%'
+ #csrf_protection: true
+ #http_method_override: true
+
+ # Enables session support. Note that the session will ONLY be started if you read or write from it.
+ # Remove or comment this section to explicitly disable session support.
+ session:
+ handler_id: null
+ cookie_secure: auto
+ cookie_samesite: lax
+ enabled: true
+
+ #esi: true
+ #fragments: true
+ php_errors:
+ log: true
diff --git a/apps/backoffice/frontend/config/services_test.yaml b/apps/backoffice/frontend/config/services_test.yaml
new file mode 100644
index 000000000..3a81827df
--- /dev/null
+++ b/apps/backoffice/frontend/config/services_test.yaml
@@ -0,0 +1,13 @@
+framework:
+ test: true
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ CodelyTv\Tests\:
+ resource: '../../../../tests'
+
+ # -- IMPLEMENTATIONS SELECTOR --
+ CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus'
diff --git a/apps/backoffice/frontend/public/images/logo.png b/apps/backoffice/frontend/public/images/logo.png
new file mode 100644
index 000000000..759395922
Binary files /dev/null and b/apps/backoffice/frontend/public/images/logo.png differ
diff --git a/apps/backoffice/frontend/public/index.php b/apps/backoffice/frontend/public/index.php
new file mode 100644
index 000000000..6dd7c188e
--- /dev/null
+++ b/apps/backoffice/frontend/public/index.php
@@ -0,0 +1,32 @@
+handle($request);
+$response->send();
+$kernel->terminate($request, $response);
diff --git a/apps/backoffice/frontend/src/BackofficeFrontendKernel.php b/apps/backoffice/frontend/src/BackofficeFrontendKernel.php
new file mode 100644
index 000000000..ae109b24a
--- /dev/null
+++ b/apps/backoffice/frontend/src/BackofficeFrontendKernel.php
@@ -0,0 +1,46 @@
+getProjectDir() . '/config/bundles.php';
+ foreach ($contents as $class => $envs) {
+ if ($envs[$this->environment] ?? $envs['all'] ?? false) {
+ yield new $class();
+ }
+ }
+ }
+
+ public function getProjectDir(): string
+ {
+ return dirname(__DIR__);
+ }
+
+ protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
+ {
+ $container->addResource(new FileResource($this->getProjectDir() . '/config/bundles.php'));
+ $container->setParameter('.container.dumper.inline_class_loader', true);
+ $confDir = $this->getProjectDir() . '/config';
+
+ $loader->load($confDir . '/services' . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services/*' . self::CONFIG_EXTS, 'glob');
+ }
+}
diff --git a/apps/backoffice/frontend/src/Command/ImportCoursesToElasticsearchCommand.php b/apps/backoffice/frontend/src/Command/ImportCoursesToElasticsearchCommand.php
new file mode 100644
index 000000000..c27dd2396
--- /dev/null
+++ b/apps/backoffice/frontend/src/Command/ImportCoursesToElasticsearchCommand.php
@@ -0,0 +1,32 @@
+mySqlRepository->searchAll();
+
+ foreach ($courses as $course) {
+ $this->elasticRepository->save($course);
+ }
+
+ return 0;
+ }
+}
diff --git a/apps/backoffice/frontend/src/Controller/Courses/CoursesGetWebController.php b/apps/backoffice/frontend/src/Controller/Courses/CoursesGetWebController.php
new file mode 100644
index 000000000..a9604d1b2
--- /dev/null
+++ b/apps/backoffice/frontend/src/Controller/Courses/CoursesGetWebController.php
@@ -0,0 +1,36 @@
+ask(new FindCoursesCounterQuery());
+
+ return $this->render(
+ 'pages/courses/courses.html.twig',
+ [
+ 'title' => 'Courses',
+ 'description' => 'Courses CodelyTV - Backoffice',
+ 'courses_counter' => $coursesCounterResponse->total(),
+ 'new_course_id' => SimpleUuid::random()->value(),
+ ]
+ );
+ }
+
+ protected function exceptions(): array
+ {
+ return [];
+ }
+}
diff --git a/apps/backoffice/frontend/src/Controller/Courses/CoursesPostWebController.php b/apps/backoffice/frontend/src/Controller/Courses/CoursesPostWebController.php
new file mode 100644
index 000000000..625d2a1d0
--- /dev/null
+++ b/apps/backoffice/frontend/src/Controller/Courses/CoursesPostWebController.php
@@ -0,0 +1,61 @@
+validateRequest($request);
+
+ return $validationErrors->count()
+ ? $this->redirectWithErrors('courses_get', $validationErrors, $request)
+ : $this->createCourse($request);
+ }
+
+ protected function exceptions(): array
+ {
+ return [];
+ }
+
+ private function validateRequest(Request $request): ConstraintViolationListInterface
+ {
+ $constraint = new Assert\Collection(
+ [
+ 'id' => new Assert\Uuid(),
+ 'name' => [new Assert\NotBlank(), new Assert\Length(['min' => 1, 'max' => 255])],
+ 'duration' => [new Assert\NotBlank(), new Assert\Length(['min' => 4, 'max' => 100])],
+ ]
+ );
+
+ $input = $request->request->all();
+
+ return Validation::createValidator()->validate($input, $constraint);
+ }
+
+ private function createCourse(Request $request): RedirectResponse
+ {
+ $this->dispatch(
+ new CreateCourseCommand(
+ (string) $request->request->get('id'),
+ (string) $request->request->get('name'),
+ (string) $request->request->get('duration')
+ )
+ );
+
+ return $this->redirectWithMessage(
+ 'courses_get',
+ sprintf('Feliciades, el curso %s ha sido creado!', $request->request->getAlpha('name'))
+ );
+ }
+}
diff --git a/apps/backoffice/frontend/src/Controller/HealthCheck/HealthCheckGetController.php b/apps/backoffice/frontend/src/Controller/HealthCheck/HealthCheckGetController.php
new file mode 100644
index 000000000..a38a47d39
--- /dev/null
+++ b/apps/backoffice/frontend/src/Controller/HealthCheck/HealthCheckGetController.php
@@ -0,0 +1,20 @@
+ 'ok',
+ ]
+ );
+ }
+}
diff --git a/apps/backoffice/frontend/src/Controller/Home/HomeGetWebController.php b/apps/backoffice/frontend/src/Controller/Home/HomeGetWebController.php
new file mode 100644
index 000000000..30e011847
--- /dev/null
+++ b/apps/backoffice/frontend/src/Controller/Home/HomeGetWebController.php
@@ -0,0 +1,25 @@
+render('pages/home.html.twig', [
+ 'title' => 'Welcome',
+ 'description' => 'CodelyTV - Backoffice',
+ ]);
+ }
+
+ protected function exceptions(): array
+ {
+ return [];
+ }
+}
diff --git a/apps/backoffice/frontend/src/Controller/Metrics/MetricsController.php b/apps/backoffice/frontend/src/Controller/Metrics/MetricsController.php
new file mode 100644
index 000000000..a10a699ea
--- /dev/null
+++ b/apps/backoffice/frontend/src/Controller/Metrics/MetricsController.php
@@ -0,0 +1,23 @@
+render($this->monitor->registry()->getMetricFamilySamples());
+
+ return new Response($result, 200, ['Content-Type' => RenderTextFormat::MIME_TYPE]);
+ }
+}
diff --git a/apps/backoffice/frontend/templates/master.html.twig b/apps/backoffice/frontend/templates/master.html.twig
new file mode 100644
index 000000000..965f9ad4d
--- /dev/null
+++ b/apps/backoffice/frontend/templates/master.html.twig
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+ {{ title }}
+ {{ description }}
+
+
+{{ include('partials/header.html.twig') }}
+
+{% if flash.has('message') %}
+
+
+
+
+
{{ flash.get('message') }}
+
+{% endif %}
+
+
+
{% block page_title %}{% endblock %}
+ {% block main %}{% endblock %}
+
+
+
+{{ include('partials/footer.html.twig') }}
+
+
+
diff --git a/apps/backoffice/frontend/templates/pages/courses/courses.html.twig b/apps/backoffice/frontend/templates/pages/courses/courses.html.twig
new file mode 100644
index 000000000..adfd9b003
--- /dev/null
+++ b/apps/backoffice/frontend/templates/pages/courses/courses.html.twig
@@ -0,0 +1,19 @@
+{% extends 'master.html.twig' %}
+
+{% block page_title %}Cursos{% endblock %}
+
+{% block main %}
+
+
+
+
Cursos
+
+ Actualmente CodelyTV Pro cuenta con {{ courses_counter }} cursos.
+
+
+
+ {{ include('pages/courses/partials/new_course_form.html.twig') }}
+
+
+ {{ include('pages/courses/partials/list_courses.html.twig') }}
+{% endblock %}
diff --git a/apps/backoffice/frontend/templates/pages/courses/partials/list_courses.html.twig b/apps/backoffice/frontend/templates/pages/courses/partials/list_courses.html.twig
new file mode 100644
index 000000000..51b18eea1
--- /dev/null
+++ b/apps/backoffice/frontend/templates/pages/courses/partials/list_courses.html.twig
@@ -0,0 +1,153 @@
+Cursos existentes
+
+
+
+
+
+
+
+ Id
+
+
+ Nombre
+
+
+ DuraciΓ³n
+
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html.twig b/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html.twig
new file mode 100644
index 000000000..3dab08075
--- /dev/null
+++ b/apps/backoffice/frontend/templates/pages/courses/partials/new_course_form.html.twig
@@ -0,0 +1,48 @@
+
diff --git a/apps/backoffice/frontend/templates/pages/home.html.twig b/apps/backoffice/frontend/templates/pages/home.html.twig
new file mode 100644
index 000000000..3b6a5bcb1
--- /dev/null
+++ b/apps/backoffice/frontend/templates/pages/home.html.twig
@@ -0,0 +1,7 @@
+{% extends 'master.html.twig' %}
+
+{% block page_title %}HOME{% endblock %}
+
+{% block main %}
+ HOLIII HOME
+{% endblock %}
diff --git a/apps/backoffice/frontend/templates/partials/footer.html.twig b/apps/backoffice/frontend/templates/partials/footer.html.twig
new file mode 100644
index 000000000..27a640fa6
--- /dev/null
+++ b/apps/backoffice/frontend/templates/partials/footer.html.twig
@@ -0,0 +1,7 @@
+
diff --git a/apps/backoffice/frontend/templates/partials/header.html.twig b/apps/backoffice/frontend/templates/partials/header.html.twig
new file mode 100644
index 000000000..c944f266b
--- /dev/null
+++ b/apps/backoffice/frontend/templates/partials/header.html.twig
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/apps/backoffice/frontend/var/.gitkeep b/apps/backoffice/frontend/var/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/bootstrap.php b/apps/bootstrap.php
new file mode 100644
index 000000000..8edbfc3b1
--- /dev/null
+++ b/apps/bootstrap.php
@@ -0,0 +1,17 @@
+loadEnv($rootPath . '/.env');
+
+$_SERVER += $_ENV;
+$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
+$_SERVER['APP_DEBUG'] ??= $_ENV['APP_DEBUG'] ?? $_SERVER['APP_ENV'] !== 'prod';
+$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] =
+ (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
diff --git a/apps/mooc/backend/bin/console b/apps/mooc/backend/bin/console
new file mode 100755
index 000000000..d013ee7a8
--- /dev/null
+++ b/apps/mooc/backend/bin/console
@@ -0,0 +1,42 @@
+#!/usr/bin/env php
+getParameterOption(['--env', '-e'], null, true)) {
+ putenv('APP_ENV=' . $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
+}
+
+if ($input->hasParameterOption('--no-debug', true)) {
+ putenv('APP_DEBUG=' . $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
+}
+
+require dirname(__DIR__) . '/../../bootstrap.php';
+
+if ($_SERVER['APP_DEBUG']) {
+ umask(0000);
+
+ if (class_exists(Debug::class)) {
+ Debug::enable();
+ }
+}
+
+$kernel = new MoocBackendKernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
+$application = new Application($kernel);
+$application->run($input);
diff --git a/apps/mooc/backend/config/bundles.php b/apps/mooc/backend/config/bundles.php
new file mode 100644
index 000000000..15c297c9f
--- /dev/null
+++ b/apps/mooc/backend/config/bundles.php
@@ -0,0 +1,9 @@
+ ['all' => true],
+ FriendsOfBehat\SymfonyExtension\Bundle\FriendsOfBehatSymfonyExtensionBundle::class => ['test' => true],
+ // WouterJ\EloquentBundle\WouterJEloquentBundle::class => ['test' => true]
+];
diff --git a/apps/mooc/backend/config/routes/courses.yaml b/apps/mooc/backend/config/routes/courses.yaml
new file mode 100644
index 000000000..89d6e575b
--- /dev/null
+++ b/apps/mooc/backend/config/routes/courses.yaml
@@ -0,0 +1,4 @@
+courses_put:
+ path: /courses/{id}
+ controller: CodelyTv\Apps\Mooc\Backend\Controller\Courses\CoursesPutController
+ methods: [PUT]
diff --git a/apps/mooc/backend/config/routes/courses_counter.yaml b/apps/mooc/backend/config/routes/courses_counter.yaml
new file mode 100644
index 000000000..8641b6d20
--- /dev/null
+++ b/apps/mooc/backend/config/routes/courses_counter.yaml
@@ -0,0 +1,4 @@
+courses_counter_get:
+ path: /courses-counter
+ controller: CodelyTv\Apps\Mooc\Backend\Controller\CoursesCounter\CoursesCounterGetController
+ methods: [GET]
diff --git a/apps/mooc/backend/config/routes/health-check.yaml b/apps/mooc/backend/config/routes/health-check.yaml
new file mode 100644
index 000000000..203ddbec5
--- /dev/null
+++ b/apps/mooc/backend/config/routes/health-check.yaml
@@ -0,0 +1,4 @@
+health-check_get:
+ path: /health-check
+ controller: CodelyTv\Apps\Mooc\Backend\Controller\HealthCheck\HealthCheckGetController
+ methods: [GET]
diff --git a/apps/mooc/backend/config/routes/metrics.yaml b/apps/mooc/backend/config/routes/metrics.yaml
new file mode 100644
index 000000000..d680b5046
--- /dev/null
+++ b/apps/mooc/backend/config/routes/metrics.yaml
@@ -0,0 +1,4 @@
+metrics_get:
+ path: /metrics
+ controller: CodelyTv\Apps\Mooc\Backend\Controller\Metrics\MetricsController
+ methods: [GET]
diff --git a/apps/mooc/backend/config/services.yaml b/apps/mooc/backend/config/services.yaml
new file mode 100644
index 000000000..7d81f0953
--- /dev/null
+++ b/apps/mooc/backend/config/services.yaml
@@ -0,0 +1,98 @@
+imports:
+ - { resource: ../../../../src/Mooc/Shared/Infrastructure/Symfony/DependencyInjection/mooc_services.yaml }
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ # Configure
+ _instanceof:
+ CodelyTv\Shared\Domain\Bus\Event\DomainEventSubscriber:
+ tags: ['codely.domain_event_subscriber']
+
+ CodelyTv\Shared\Domain\Bus\Command\CommandHandler:
+ tags: ['codely.command_handler']
+
+ CodelyTv\Shared\Domain\Bus\Query\QueryHandler:
+ tags: ['codely.query_handler']
+
+ CodelyTv\Apps\Mooc\Backend\Controller\:
+ resource: '../src/Controller'
+ tags: ['controller.service_arguments']
+
+ CodelyTv\Apps\Mooc\Backend\Command\:
+ resource: '../src/Command'
+ tags: ['console.command']
+
+ # Wire
+ CodelyTv\Shared\:
+ resource: '../../../../src/Shared'
+
+ CodelyTv\Mooc\:
+ resource: '../../../../src/Mooc'
+
+ # -- TAGGING --
+ CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus:
+ arguments: [!tagged codely.domain_event_subscriber]
+ lazy: true
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventMapping:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventSubscriberLocator:
+ arguments: [!tagged codely.domain_event_subscriber]
+
+ CodelyTv\Shared\Infrastructure\Doctrine\DatabaseConnections:
+ arguments: [!tagged codely.database_connection]
+
+ CodelyTv\Shared\Infrastructure\Symfony\AddJsonBodyToRequestListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
+
+ CodelyTv\Shared\Infrastructure\Symfony\ApiExceptionListener:
+ tags:
+ - { name: kernel.event_listener, event: kernel.exception, method: onException }
+
+
+ # -- APP DEFINITIONS --
+ # Command/Query Handlers
+ CodelyTv\Shared\Infrastructure\Bus\Command\InMemorySymfonyCommandBus:
+ arguments: [!tagged codely.command_handler]
+
+ CodelyTv\Shared\Infrastructure\Bus\Query\InMemorySymfonyQueryBus:
+ arguments: [!tagged codely.query_handler]
+
+ # RabbitMQ
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection:
+ arguments:
+ - host: '%env(RABBITMQ_HOST)%'
+ port: '%env(RABBITMQ_PORT)%'
+ vhost: '%env(RABBITMQ_MOOC_VHOST)%'
+ login: '%env(RABBITMQ_LOGIN)%'
+ password: '%env(RABBITMQ_PASSWORD)%'
+ read_timeout: 2
+ write_timeout: 2
+ connect_timeout: 5
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection', '%env(RABBITMQ_EXCHANGE)%']
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqDomainEventsConsumer:
+ arguments:
+ - '@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConnection'
+ - '@CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventJsonDeserializer'
+ - '%env(RABBITMQ_EXCHANGE)%'
+ - '%env(RABBITMQ_MAX_RETRIES)%'
+
+ CodelyTv\Apps\Mooc\Backend\Command\DomainEvents\RabbitMq\ConfigureRabbitMqCommand:
+ arguments:
+ - '@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqConfigurer'
+ - '%env(RABBITMQ_EXCHANGE)%'
+ - !tagged codely.domain_event_subscriber
+
+ CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus:
+ arguments: ['@CodelyTv\Shared\Infrastructure\Monitoring\PrometheusMonitor', 'mooc_backend', '@CodelyTv\Shared\Infrastructure\Bus\Event\RabbitMq\RabbitMqEventBus']
+
+ # -- IMPLEMENTATIONS SELECTOR --
+ CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\WithMonitoring\WithPrometheusMonitoringEventBus'
diff --git a/apps/mooc/backend/config/services/framework.yaml b/apps/mooc/backend/config/services/framework.yaml
new file mode 100644
index 000000000..06fb3f3b4
--- /dev/null
+++ b/apps/mooc/backend/config/services/framework.yaml
@@ -0,0 +1,16 @@
+framework:
+ secret: '%env(APP_SECRET)%'
+ #csrf_protection: true
+ #http_method_override: true
+
+ # Enables session support. Note that the session will ONLY be started if you read or write from it.
+ # Remove or comment this section to explicitly disable session support.
+ session:
+ handler_id: ~
+ cookie_secure: auto
+ cookie_samesite: lax
+
+ #esi: true
+ #fragments: true
+ php_errors:
+ log: true
diff --git a/apps/mooc/backend/config/services_test.yaml b/apps/mooc/backend/config/services_test.yaml
new file mode 100644
index 000000000..8e4fe2146
--- /dev/null
+++ b/apps/mooc/backend/config/services_test.yaml
@@ -0,0 +1,14 @@
+framework:
+ test: true
+
+services:
+ _defaults:
+ autoconfigure: true
+ autowire: true
+
+ CodelyTv\Tests\:
+ resource: '../../../../tests'
+
+ # Instance selector
+ CodelyTv\Shared\Domain\RandomNumberGenerator: '@CodelyTv\Tests\Shared\Infrastructure\ConstantRandomNumberGenerator'
+# CodelyTv\Shared\Domain\Bus\Event\EventBus: '@CodelyTv\Shared\Infrastructure\Bus\Event\InMemory\InMemorySymfonyEventBus'
diff --git a/apps/mooc/backend/public/index.php b/apps/mooc/backend/public/index.php
new file mode 100644
index 000000000..b8655fe09
--- /dev/null
+++ b/apps/mooc/backend/public/index.php
@@ -0,0 +1,32 @@
+handle($request);
+$response->send();
+$kernel->terminate($request, $response);
diff --git a/apps/mooc/backend/src/Command/DomainEvents/MySql/ConsumeMySqlDomainEventsCommand.php b/apps/mooc/backend/src/Command/DomainEvents/MySql/ConsumeMySqlDomainEventsCommand.php
new file mode 100644
index 000000000..16d96c2a6
--- /dev/null
+++ b/apps/mooc/backend/src/Command/DomainEvents/MySql/ConsumeMySqlDomainEventsCommand.php
@@ -0,0 +1,56 @@
+addArgument('quantity', InputArgument::REQUIRED, 'Quantity of events to process');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $quantityEventsToProcess = (int) $input->getArgument('quantity');
+
+ $consumer = pipe($this->consumer(), fn () => $this->connections->clear());
+
+ $this->consumer->consume($consumer, $quantityEventsToProcess);
+
+ return 0;
+ }
+
+ private function consumer(): callable
+ {
+ return function (DomainEvent $domainEvent): void {
+ $subscribers = $this->subscriberLocator->allSubscribedTo($domainEvent::class);
+
+ foreach ($subscribers as $subscriber) {
+ $subscriber($domainEvent);
+ }
+ };
+ }
+}
diff --git a/apps/mooc/backend/src/Command/DomainEvents/PublishDomainEventsFromMutationsCommand.php b/apps/mooc/backend/src/Command/DomainEvents/PublishDomainEventsFromMutationsCommand.php
new file mode 100644
index 000000000..945784311
--- /dev/null
+++ b/apps/mooc/backend/src/Command/DomainEvents/PublishDomainEventsFromMutationsCommand.php
@@ -0,0 +1,91 @@
+transformers = [
+ 'courses' => [
+ DatabaseMutationAction::INSERT->value => DatabaseMutationToCourseCreatedDomainEvent::class,
+ DatabaseMutationAction::UPDATE->value => null,
+ DatabaseMutationAction::DELETE->value => null,
+ ],
+ ];
+ }
+
+ protected function configure(): void
+ {
+ $this->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of mutations to process');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $totalMutations = (int) $input->getArgument('quantity');
+
+ $this->entityManager->wrapInTransaction(function (EntityManager $entityManager) use ($totalMutations) {
+ $mutations = $entityManager->getConnection()
+ ->executeQuery("SELECT * FROM mutations ORDER BY id ASC LIMIT $totalMutations FOR UPDATE")
+ ->fetchAllAssociative();
+
+ foreach ($mutations as $mutation) {
+ $transformer = $this->findTransformer($mutation['table_name'], $mutation['operation']);
+
+ if ($transformer === null) {
+ echo sprintf("Ignoring %s %s\n", $mutation['table_name'], $mutation['operation']);
+ continue;
+ }
+
+ $domainEvents = $transformer->transform($mutation);
+
+ $this->eventBus->publish(...$domainEvents);
+ }
+
+ $entityManager->getConnection()->executeStatement(
+ sprintf('DELETE FROM mutations WHERE id IN (%s)', implode(',', array_column($mutations, 'id')))
+ );
+ });
+
+ return 0;
+ }
+
+ private function findTransformer(string $tableName, string $operation): ?DatabaseMutationToDomainEvent
+ {
+ if (!array_key_exists($tableName, $this->transformers) && array_key_exists(
+ $operation,
+ $this->transformers[$tableName]
+ )) {
+ throw new RuntimeException("Transformer not found for table $tableName and operation $operation");
+ }
+
+ /** @var class-string|null $class */
+ $class = $this->transformers[$tableName][$operation];
+
+ return $class ? new $class() : null;
+ }
+}
diff --git a/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConfigureRabbitMqCommand.php b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConfigureRabbitMqCommand.php
new file mode 100644
index 000000000..72801af71
--- /dev/null
+++ b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConfigureRabbitMqCommand.php
@@ -0,0 +1,34 @@
+configurer->configure($this->exchangeName, ...iterator_to_array($this->subscribers));
+
+ return 0;
+ }
+}
diff --git a/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConsumeRabbitMqDomainEventsCommand.php b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConsumeRabbitMqDomainEventsCommand.php
new file mode 100644
index 000000000..c29c056d8
--- /dev/null
+++ b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/ConsumeRabbitMqDomainEventsCommand.php
@@ -0,0 +1,59 @@
+addArgument('queue', InputArgument::REQUIRED, 'Queue name')
+ ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of events to process');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $queueName = $input->getArgument('queue');
+ $eventsToProcess = (int) $input->getArgument('quantity');
+
+ repeat($this->consumer($queueName), $eventsToProcess);
+
+ return 0;
+ }
+
+ private function consumer(string $queueName): callable
+ {
+ return function () use ($queueName): void {
+ $subscriber = $this->locator->withRabbitMqQueueNamed($queueName);
+
+ $this->consumer->consume($subscriber, $queueName);
+
+ $this->connections->clear();
+ };
+ }
+}
diff --git a/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/GenerateSupervisorRabbitMqConsumerFilesCommand.php b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/GenerateSupervisorRabbitMqConsumerFilesCommand.php
new file mode 100644
index 000000000..646392bf3
--- /dev/null
+++ b/apps/mooc/backend/src/Command/DomainEvents/RabbitMq/GenerateSupervisorRabbitMqConsumerFilesCommand.php
@@ -0,0 +1,88 @@
+addArgument('command-path', InputArgument::OPTIONAL, 'Path on this is gonna be deployed', '/var/www');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $path = $input->getArgument('command-path');
+
+ each($this->configCreator($path), $this->locator->all());
+
+ return 0;
+ }
+
+ private function configCreator(string $path): callable
+ {
+ return function (DomainEventSubscriber $subscriber) use ($path): void {
+ $queueName = RabbitMqQueueNameFormatter::format($subscriber);
+ $subscriberName = RabbitMqQueueNameFormatter::shortFormat($subscriber);
+
+ $fileContent = str_replace(
+ ['{subscriber_name}', '{queue_name}', '{path}', '{processes}', '{events_to_process}', ],
+ [
+ $subscriberName,
+ $queueName,
+ $path,
+ self::NUMBERS_OF_PROCESSES_PER_SUBSCRIBER,
+ self::EVENTS_TO_PROCESS_AT_TIME,
+ ],
+ $this->template()
+ );
+
+ file_put_contents($this->fileName($subscriberName), $fileContent);
+ };
+ }
+
+ private function template(): string
+ {
+ return <<dispatch(
+ new CreateCourseCommand(
+ $id,
+ (string) $request->request->get('name'),
+ (string) $request->request->get('duration')
+ )
+ );
+
+ return new Response('', Response::HTTP_CREATED);
+ }
+
+ protected function exceptions(): array
+ {
+ return [];
+ }
+}
diff --git a/apps/mooc/backend/src/Controller/CoursesCounter/CoursesCounterGetController.php b/apps/mooc/backend/src/Controller/CoursesCounter/CoursesCounterGetController.php
new file mode 100644
index 000000000..0fb94b6ff
--- /dev/null
+++ b/apps/mooc/backend/src/Controller/CoursesCounter/CoursesCounterGetController.php
@@ -0,0 +1,34 @@
+ask(new FindCoursesCounterQuery());
+
+ return new JsonResponse(
+ [
+ 'total' => $response->total(),
+ ]
+ );
+ }
+
+ protected function exceptions(): array
+ {
+ return [
+ CoursesCounterNotExist::class => Response::HTTP_NOT_FOUND,
+ ];
+ }
+}
diff --git a/apps/mooc/backend/src/Controller/HealthCheck/HealthCheckGetController.php b/apps/mooc/backend/src/Controller/HealthCheck/HealthCheckGetController.php
new file mode 100644
index 000000000..1c20feae2
--- /dev/null
+++ b/apps/mooc/backend/src/Controller/HealthCheck/HealthCheckGetController.php
@@ -0,0 +1,24 @@
+ 'ok',
+ 'rand' => $this->generator->generate(),
+ ]
+ );
+ }
+}
diff --git a/apps/mooc/backend/src/Controller/Metrics/MetricsController.php b/apps/mooc/backend/src/Controller/Metrics/MetricsController.php
new file mode 100644
index 000000000..9db1cebc2
--- /dev/null
+++ b/apps/mooc/backend/src/Controller/Metrics/MetricsController.php
@@ -0,0 +1,23 @@
+render($this->monitor->registry()->getMetricFamilySamples());
+
+ return new Response($result, 200, ['Content-Type' => RenderTextFormat::MIME_TYPE]);
+ }
+}
diff --git a/apps/mooc/backend/src/MoocBackendKernel.php b/apps/mooc/backend/src/MoocBackendKernel.php
new file mode 100644
index 000000000..e0b82d39e
--- /dev/null
+++ b/apps/mooc/backend/src/MoocBackendKernel.php
@@ -0,0 +1,46 @@
+getProjectDir() . '/config/bundles.php';
+ foreach ($contents as $class => $envs) {
+ if ($envs[$this->environment] ?? $envs['all'] ?? false) {
+ yield new $class();
+ }
+ }
+ }
+
+ public function getProjectDir(): string
+ {
+ return dirname(__DIR__);
+ }
+
+ protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
+ {
+ $container->addResource(new FileResource($this->getProjectDir() . '/config/bundles.php'));
+ $container->setParameter('.container.dumper.inline_class_loader', true);
+ $confDir = $this->getProjectDir() . '/config';
+
+ $loader->load($confDir . '/services' . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
+ $loader->load($confDir . '/services/*' . self::CONFIG_EXTS, 'glob');
+ }
+}
diff --git a/apps/mooc/backend/tests/features/courses/course_put.feature b/apps/mooc/backend/tests/features/courses/course_put.feature
new file mode 100644
index 000000000..803bc2a5d
--- /dev/null
+++ b/apps/mooc/backend/tests/features/courses/course_put.feature
@@ -0,0 +1,15 @@
+Feature: Create a new course
+ In order to have courses on the platform
+ As a user with admin permissions
+ I want to create a new course
+
+ Scenario: A valid non existing course
+ Given I send a PUT request to "/courses/1aab45ba-3c7a-4344-8936-78466eca77fa" with body:
+ """
+ {
+ "name": "The best course",
+ "duration": "5 hours"
+ }
+ """
+ Then the response status code should be 201
+ And the response should be empty
diff --git a/apps/mooc/backend/tests/features/courses_counter/courses_counter_get.feature b/apps/mooc/backend/tests/features/courses_counter/courses_counter_get.feature
new file mode 100644
index 000000000..13719be7f
--- /dev/null
+++ b/apps/mooc/backend/tests/features/courses_counter/courses_counter_get.feature
@@ -0,0 +1,96 @@
+Feature: Obtain the total number of courses
+ In order to have a courses counter
+ As a user
+ I want to see the courses counter
+
+ Scenario: With one course
+ Given I send an event to the event bus:
+ """
+ {
+ "data": {
+ "id": "c77fa036-cbc7-4414-996b-c6a7a93cae09",
+ "type": "course.created",
+ "occurred_on": "2019-08-08T08:37:32+00:00",
+ "attributes": {
+ "id": "8c900b20-e04a-4777-9183-32faab6d2fb5",
+ "name": "DDD en PHP!",
+ "duration": "25 hours"
+ },
+ "meta" : {
+ "host": "111.26.06.93"
+ }
+ }
+ }
+ """
+ When I send a "GET" request to "/courses-counter"
+ Then the response status code should be 200
+ And the response content should be:
+ """
+ {
+ "total": 1
+ }
+ """
+
+ Scenario: With more than one course having duplicates
+ Given I send an event to the event bus:
+ """
+ {
+ "data": {
+ "id": "c77fa036-cbc7-4414-996b-c6a7a93cae09",
+ "type": "course.created",
+ "occurred_on": "2019-08-08T08:37:32+00:00",
+ "attributes": {
+ "id": "8c900b20-e04a-4777-9183-32faab6d2fb5",
+ "name": "DDD en PHP!",
+ "duration": "25 hours"
+ },
+ "meta" : {
+ "host": "111.26.06.93"
+ }
+ }
+ }
+ """
+ And I send an event to the event bus:
+ """
+ {
+ "data": {
+ "id": "8c4a4ed8-9458-489e-a167-b099d81fa096",
+ "type": "course.created",
+ "occurred_on": "2019-08-09T08:36:32+00:00",
+ "attributes": {
+ "id": "8c4a4ed8-9458-489e-a167-b099d81fa096",
+ "name": "DDD en Java",
+ "duration": "24 hours"
+ },
+ "meta" : {
+ "host": "111.26.06.93"
+ }
+ }
+ }
+ """
+ And I send an event to the event bus:
+ """
+ {
+ "data": {
+ "id": "8c4a4ed8-9458-489e-a167-b099d81fa096",
+ "type": "course.created",
+ "occurred_on": "2019-08-09T08:36:32+00:00",
+ "attributes": {
+ "id": "8c4a4ed8-9458-489e-a167-b099d81fa096",
+ "name": "DDD en Java",
+ "duration": "24 hours"
+ },
+ "meta" : {
+ "host": "111.26.06.93"
+ }
+ }
+ }
+ """
+ When I send a "GET" request to "/courses-counter"
+ Then the response status code should be 200
+ And the response content should be:
+ """
+ {
+ "total": 2
+ }
+ """
diff --git a/tests/applications/mooc_backend/features/status/status_get.feature b/apps/mooc/backend/tests/features/health_check/health_check_get.feature
similarity index 70%
rename from tests/applications/mooc_backend/features/status/status_get.feature
rename to apps/mooc/backend/tests/features/health_check/health_check_get.feature
index 1e05acd5e..96f4c0e75 100644
--- a/tests/applications/mooc_backend/features/status/status_get.feature
+++ b/apps/mooc/backend/tests/features/health_check/health_check_get.feature
@@ -4,10 +4,11 @@ Feature: Api status
I want to check the api status
Scenario: Check the api status
- Given I send a GET request to "/status"
+ Given I send a GET request to "/health-check"
Then the response content should be:
"""
{
- "status": "OK"
+ "mooc-backend": "ok",
+ "rand": 1
}
"""
diff --git a/apps/mooc/backend/tests/mooc_backend.yml b/apps/mooc/backend/tests/mooc_backend.yml
new file mode 100644
index 000000000..75681594e
--- /dev/null
+++ b/apps/mooc/backend/tests/mooc_backend.yml
@@ -0,0 +1,29 @@
+mooc_backend:
+ extensions:
+ FriendsOfBehat\SymfonyExtension:
+ kernel:
+ class: CodelyTv\Apps\Mooc\Backend\MoocBackendKernel
+ bootstrap: apps/bootstrap.php
+ Behat\MinkExtension:
+ sessions:
+ symfony:
+ symfony: ~
+ base_url: ''
+
+ suites:
+ health_check:
+ paths: [ apps/mooc/backend/tests/features/health_check ]
+ contexts:
+ - CodelyTv\Tests\Shared\Infrastructure\Behat\ApiContext
+
+ courses:
+ paths: [ apps/mooc/backend/tests/features/courses ]
+ contexts:
+ - CodelyTv\Tests\Shared\Infrastructure\Behat\ApplicationFeatureContext
+ - CodelyTv\Tests\Shared\Infrastructure\Behat\ApiContext
+
+ courses_counter:
+ paths: [ apps/mooc/backend/tests/features/courses_counter ]
+ contexts:
+ - CodelyTv\Tests\Shared\Infrastructure\Behat\ApplicationFeatureContext
+ - CodelyTv\Tests\Shared\Infrastructure\Behat\ApiContext
diff --git a/apps/mooc/backend/var/.gitkeep b/apps/mooc/backend/var/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/mooc/frontend/src/.gitkeep b/apps/mooc/frontend/src/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/apps/mooc/frontend/var/.gitkeep b/apps/mooc/frontend/var/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/behat.yml b/behat.yml
new file mode 100644
index 000000000..af66723dd
--- /dev/null
+++ b/behat.yml
@@ -0,0 +1,2 @@
+imports:
+ - apps/mooc/backend/tests/mooc_backend.yml
diff --git a/behat.yml.dist b/behat.yml.dist
deleted file mode 100644
index 994de435a..000000000
--- a/behat.yml.dist
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - tests/applications/mooc_backend/mooc_backend.yml
diff --git a/composer.json b/composer.json
index df19dbe51..52f696576 100644
--- a/composer.json
+++ b/composer.json
@@ -1,93 +1,88 @@
{
- "name": "codelytv/cqrs-ddd-example",
+ "name": "codelytv/php-ddd-example",
"license": "MIT",
"type": "project",
- "description": "A simple skeleton for CQRS code :)",
+ "description": "An example project applying Domain-Driven Design, Hexagonal Architecture and CQRS in a Monorepository",
"require": {
- "php": "7.3.6",
+ "php": "^8.3",
"ext-amqp": "*",
"ext-apcu": "*",
- "ext-bcmath": "*",
- "ext-ctype": "*",
- "ext-intl": "*",
"ext-json": "*",
"ext-zend-opcache": "*",
"ext-pdo": "*",
- "incenteev/composer-parameter-handler": "^2.1",
+ "symfony/framework-bundle": "^7",
+ "symfony/messenger": "^7",
+ "symfony/dotenv": "^7",
+ "symfony/yaml": "^7",
+ "symfony/twig-bundle": "^7",
+ "symfony/validator": "^7",
+ "symfony/cache": "^7",
- "symfony/framework-bundle": "^4.2",
- "symfony/console": "^4.2",
- "symfony/process": "^4.2",
- "symfony/messenger": "^4.2",
- "symfony/monolog-bundle": "^3.3",
- "symfony/dotenv": "^4.2",
+ "lambdish/phunctional": "^2",
- "friendsofsymfony/rest-bundle": "^2.4",
- "jms/serializer-bundle": "^2.4",
- "symfony/twig-bundle": "^4.2",
+ "ramsey/uuid": "^4",
- "ocramius/proxy-manager": "2.2.*",
+ "doctrine/dbal": "^3",
+ "doctrine/orm": "^2",
- "doctrine/dbal": "^2.8",
- "doctrine/orm": "^2.6",
+ "ocramius/proxy-manager": "^2",
+ "laminas/laminas-zendframework-bridge": "^1",
- "lambdish/phunctional": "^1.0",
+ "elasticsearch/elasticsearch": "^7",
+ "monolog/monolog": "^3",
- "swiftmailer/swiftmailer": "^5.4",
- "maknz/slack": "^1.7",
-
- "ramsey/uuid": "^3.8"
+ "promphp/prometheus_client_php": "^2.7.2"
},
"require-dev": {
"ext-xdebug": "*",
"roave/security-advisories": "dev-master",
- "phpunit/phpunit": "^6.5",
- "symfony/phpunit-bridge": "^4.2",
- "mockery/mockery": "^1.0",
- "fzaninotto/faker": "^1.7",
- "squizlabs/php_codesniffer": "^2.9",
+ "behat/behat": "^3.13",
+ "friends-of-behat/mink-extension": "2.7.5",
+ "friends-of-behat/symfony-extension": "2.6.0",
+ "behat/mink-browserkit-driver": "2.2.0",
- "behat/behat": "^3.4",
- "behat/mink-extension": "^2.3",
- "behat/mink-browserkit-driver": "^1.3",
- "friends-of-behat/symfony-extension": "^2.0",
+ "phpunit/phpunit": "^9",
+ "mockery/mockery": "^1",
- "phpstan/phpstan": "^0.10.3",
- "phpstan/phpstan-mockery": "^0.10.2"
- },
- "scripts": {
- "post-install-cmd": ["Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"],
- "post-update-cmd": ["Incenteev\\ParameterHandler\\ScriptHandler::buildParameters"],
- "behat": "behat -p api && behat -p applications",
- "phpunit": "phpunit --exclude-group='disabled'",
- "phpstan": "phpstan analyse -l 7 -c etc/phpstan/phpstan.neon applications/api/src applications/codely/src --quiet",
- "test": ["@phpstan", "@phpunit", "@behat"]
- },
- "extra": {
- "incenteev-parameters": [
- { "file": "src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_parameters.yml"},
- { "file": "src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_parameters.yml"}
- ]
+ "fakerphp/faker": "^1",
+
+ "symfony/error-handler": "^7",
+
+ "symplify/easy-coding-standard": "^12.0",
+ "vimeo/psalm": "^5.15",
+ "rector/rector": "^0.18.12",
+ "psalm/plugin-mockery": "^1.1",
+ "psalm/plugin-symfony": "^5.0",
+ "psalm/plugin-phpunit": "^0.18.4",
+ "phpstan/phpstan": "^1.10",
+ "phpat/phpat": "^0.10.10",
+ "phpmd/phpmd": "^2.14",
+ "codelytv/coding-style": "^1.1"
},
"autoload": {
"psr-4": {
- "CodelyTv\\MoocBackend\\": "applications/mooc_backend/src",
+ "CodelyTv\\Apps\\Mooc\\Backend\\": "apps/mooc/backend/src",
+ "CodelyTv\\Apps\\Mooc\\Frontend\\": "apps/mooc/frontend/src",
+
+ "CodelyTv\\Apps\\Backoffice\\Backend\\": "apps/backoffice/backend/src",
+ "CodelyTv\\Apps\\Backoffice\\Frontend\\": "apps/backoffice/frontend/src",
+
"CodelyTv\\": ["src"]
- },
- "files": [
- "src/Shared/utils.php"
- ]
+ }
},
"autoload-dev": {
"psr-4": {
- "CodelyTv\\Test\\": "tests/src"
- },
- "files": [
- "tests/src/Shared/utils.php"
- ]
+ "CodelyTv\\Tests\\": ["tests"]
+ }
+ },
+ "minimum-stability": "RC",
+ "config": {
+ "allow-plugins": {
+ "ocramius/package-versions": true
+ }
}
}
diff --git a/composer.lock b/composer.lock
index f34be2433..534d648f6 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,112 +4,97 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "b6fd292758a9cc7b516ef0bbeb0f5928",
+ "content-hash": "1384ca0a67984f7a0296f15a4373fed1",
"packages": [
{
- "name": "doctrine/annotations",
- "version": "v1.6.1",
+ "name": "brick/math",
+ "version": "0.12.1",
"source": {
"type": "git",
- "url": "https://github.com/doctrine/annotations.git",
- "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24"
+ "url": "https://github.com/brick/math.git",
+ "reference": "f510c0a40911935b77b86859eb5223d58d660df1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/53120e0eb10355388d6ccbe462f1fea34ddadb24",
- "reference": "53120e0eb10355388d6ccbe462f1fea34ddadb24",
+ "url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1",
+ "reference": "f510c0a40911935b77b86859eb5223d58d660df1",
"shasum": ""
},
"require": {
- "doctrine/lexer": "1.*",
- "php": "^7.1"
+ "php": "^8.1"
},
"require-dev": {
- "doctrine/cache": "1.*",
- "phpunit/phpunit": "^6.4"
+ "php-coveralls/php-coveralls": "^2.2",
+ "phpunit/phpunit": "^10.1",
+ "vimeo/psalm": "5.16.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.6.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
+ "Brick\\Math\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
- },
- {
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
- }
- ],
- "description": "Docblock Annotations Parser",
- "homepage": "http://www.doctrine-project.org",
+ "description": "Arbitrary-precision arithmetic library",
"keywords": [
- "annotations",
- "docblock",
- "parser"
- ],
- "time": "2019-03-25T19:12:02+00:00"
+ "Arbitrary-precision",
+ "BigInteger",
+ "BigRational",
+ "arithmetic",
+ "bigdecimal",
+ "bignum",
+ "bignumber",
+ "brick",
+ "decimal",
+ "integer",
+ "math",
+ "mathematics",
+ "rational"
+ ],
+ "support": {
+ "issues": "https://github.com/brick/math/issues",
+ "source": "https://github.com/brick/math/tree/0.12.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/BenMorel",
+ "type": "github"
+ }
+ ],
+ "time": "2023-11-29T23:19:16+00:00"
},
{
"name": "doctrine/cache",
- "version": "v1.8.0",
+ "version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
- "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57"
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/cache/zipball/d768d58baee9a4862ca783840eca1b9add7a7f57",
- "reference": "d768d58baee9a4862ca783840eca1b9add7a7f57",
+ "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb",
+ "reference": "1ca8f21980e770095a31456042471a57bc4c68fb",
"shasum": ""
},
"require": {
- "php": "~7.1"
+ "php": "~7.1 || ^8.0"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
- "alcaeus/mongo-php-adapter": "^1.1",
- "doctrine/coding-standard": "^4.0",
- "mongodb/mongodb": "^1.1",
- "phpunit/phpunit": "^7.0",
- "predis/predis": "~1.0"
- },
- "suggest": {
- "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+ "cache/integration-tests": "dev-master",
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0",
+ "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.8.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
@@ -120,6 +105,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -128,10 +117,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -141,46 +126,69 @@
"email": "schmittjoh@gmail.com"
}
],
- "description": "Caching library offering an object-oriented API for many cache backends",
- "homepage": "https://www.doctrine-project.org",
+ "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+ "homepage": "https://www.doctrine-project.org/projects/cache.html",
"keywords": [
+ "abstraction",
+ "apcu",
"cache",
- "caching"
+ "caching",
+ "couchdb",
+ "memcached",
+ "php",
+ "redis",
+ "xcache"
],
- "time": "2018-08-21T18:01:43+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/cache/issues",
+ "source": "https://github.com/doctrine/cache/tree/2.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-20T20:07:39+00:00"
},
{
"name": "doctrine/collections",
- "version": "v1.6.1",
+ "version": "2.2.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
- "reference": "d2ae4ef05e25197343b6a39bae1d3c427a2f6956"
+ "reference": "d8af7f248c74f195f7347424600fd9e17b57af59"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/collections/zipball/d2ae4ef05e25197343b6a39bae1d3c427a2f6956",
- "reference": "d2ae4ef05e25197343b6a39bae1d3c427a2f6956",
+ "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59",
+ "reference": "d8af7f248c74f195f7347424600fd9e17b57af59",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "doctrine/deprecations": "^1",
+ "php": "^8.1"
},
"require-dev": {
- "doctrine/coding-standard": "^6.0",
- "phpstan/phpstan-shim": "^0.9.2",
- "phpunit/phpunit": "^7.0",
- "vimeo/psalm": "^3.2.2"
+ "doctrine/coding-standard": "^12",
+ "ext-json": "*",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^10.5",
+ "vimeo/psalm": "^5.11"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.6.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections"
+ "Doctrine\\Common\\Collections\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -188,6 +196,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -196,10 +208,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -217,48 +225,58 @@
"iterators",
"php"
],
- "time": "2019-03-25T19:03:48+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/collections/issues",
+ "source": "https://github.com/doctrine/collections/tree/2.2.2"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-04-18T06:56:21+00:00"
},
{
"name": "doctrine/common",
- "version": "v2.10.0",
+ "version": "3.4.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/common.git",
- "reference": "30e33f60f64deec87df728c02b107f82cdafad9d"
+ "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/common/zipball/30e33f60f64deec87df728c02b107f82cdafad9d",
- "reference": "30e33f60f64deec87df728c02b107f82cdafad9d",
+ "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a",
+ "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a",
"shasum": ""
},
"require": {
- "doctrine/annotations": "^1.0",
- "doctrine/cache": "^1.0",
- "doctrine/collections": "^1.0",
- "doctrine/event-manager": "^1.0",
- "doctrine/inflector": "^1.0",
- "doctrine/lexer": "^1.0",
- "doctrine/persistence": "^1.1",
- "doctrine/reflection": "^1.0",
- "php": "^7.1"
+ "doctrine/persistence": "^2.0 || ^3.0",
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^1.0",
- "phpunit/phpunit": "^6.3",
+ "doctrine/coding-standard": "^9.0 || ^10.0",
+ "doctrine/collections": "^1",
+ "phpstan/phpstan": "^1.4.1",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0",
"squizlabs/php_codesniffer": "^3.0",
- "symfony/phpunit-bridge": "^4.0.5"
+ "symfony/phpunit-bridge": "^6.1",
+ "vimeo/psalm": "^4.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.10.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\": "lib/Doctrine/Common"
+ "Doctrine\\Common\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -266,6 +284,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -274,10 +296,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -291,42 +309,69 @@
"email": "ocramius@gmail.com"
}
],
- "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, persistence interfaces, proxies, event system and much more.",
+ "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.",
"homepage": "https://www.doctrine-project.org/projects/common.html",
"keywords": [
"common",
"doctrine",
"php"
],
- "time": "2018-11-21T01:24:55+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/common/issues",
+ "source": "https://github.com/doctrine/common/tree/3.4.4"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-04-16T13:35:33+00:00"
},
{
"name": "doctrine/dbal",
- "version": "v2.9.2",
+ "version": "3.8.6",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
- "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9"
+ "reference": "b7411825cf7efb7e51f9791dea19d86e43b399a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/dbal/zipball/22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
- "reference": "22800bd651c1d8d2a9719e2a3dc46d5108ebfcc9",
+ "url": "https://api.github.com/repos/doctrine/dbal/zipball/b7411825cf7efb7e51f9791dea19d86e43b399a1",
+ "reference": "b7411825cf7efb7e51f9791dea19d86e43b399a1",
"shasum": ""
},
"require": {
- "doctrine/cache": "^1.0",
- "doctrine/event-manager": "^1.0",
- "ext-pdo": "*",
- "php": "^7.1"
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.11|^2.0",
+ "doctrine/deprecations": "^0.5.3|^1",
+ "doctrine/event-manager": "^1|^2",
+ "php": "^7.4 || ^8.0",
+ "psr/cache": "^1|^2|^3",
+ "psr/log": "^1|^2|^3"
},
"require-dev": {
- "doctrine/coding-standard": "^5.0",
- "jetbrains/phpstorm-stubs": "^2018.1.2",
- "phpstan/phpstan": "^0.10.1",
- "phpunit/phpunit": "^7.4",
- "symfony/console": "^2.0.5|^3.0|^4.0",
- "symfony/phpunit-bridge": "^3.4.5|^4.0.5"
+ "doctrine/coding-standard": "12.0.0",
+ "fig/log-test": "^1",
+ "jetbrains/phpstorm-stubs": "2023.1",
+ "phpstan/phpstan": "1.11.5",
+ "phpstan/phpstan-strict-rules": "^1.6",
+ "phpunit/phpunit": "9.6.19",
+ "psalm/plugin-phpunit": "0.18.4",
+ "slevomat/coding-standard": "8.13.1",
+ "squizlabs/php_codesniffer": "3.10.1",
+ "symfony/cache": "^5.4|^6.0|^7.0",
+ "symfony/console": "^4.4|^5.4|^6.0|^7.0",
+ "vimeo/psalm": "4.30.0"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
@@ -335,15 +380,9 @@
"bin/doctrine-dbal"
],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.9.x-dev",
- "dev-develop": "3.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\DBAL\\": "lib/Doctrine/DBAL"
+ "Doctrine\\DBAL\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -351,6 +390,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -359,10 +402,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -373,48 +412,120 @@
"keywords": [
"abstraction",
"database",
+ "db2",
"dbal",
+ "mariadb",
+ "mssql",
"mysql",
- "persistence",
+ "oci8",
+ "oracle",
+ "pdo",
"pgsql",
- "php",
- "queryobject"
+ "postgresql",
+ "queryobject",
+ "sasql",
+ "sql",
+ "sqlite",
+ "sqlserver",
+ "sqlsrv"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/dbal/issues",
+ "source": "https://github.com/doctrine/dbal/tree/3.8.6"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-06-19T10:38:17+00:00"
+ },
+ {
+ "name": "doctrine/deprecations",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpstan/phpstan": "1.4.10 || 1.10.15",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "0.18.4",
+ "psr/log": "^1 || ^2 || ^3",
+ "vimeo/psalm": "4.30.0 || 5.12.0"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
],
- "time": "2018-12-31T03:27:51+00:00"
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/1.1.3"
+ },
+ "time": "2024-01-30T19:34:25+00:00"
},
{
"name": "doctrine/event-manager",
- "version": "v1.0.0",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/event-manager.git",
- "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3"
+ "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/event-manager/zipball/a520bc093a0170feeb6b14e9d83f3a14452e64b3",
- "reference": "a520bc093a0170feeb6b14e9d83f3a14452e64b3",
+ "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e",
+ "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": "^8.1"
},
"conflict": {
- "doctrine/common": "<2.9@dev"
+ "doctrine/common": "<2.9"
},
"require-dev": {
- "doctrine/coding-standard": "^4.0",
- "phpunit/phpunit": "^7.0"
+ "doctrine/coding-standard": "^12",
+ "phpstan/phpstan": "^1.8.8",
+ "phpunit/phpunit": "^10.5",
+ "vimeo/psalm": "^5.24"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\": "lib/Doctrine/Common"
+ "Doctrine\\Common\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -422,6 +533,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -430,10 +545,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -447,44 +558,64 @@
"email": "ocramius@gmail.com"
}
],
- "description": "Doctrine Event Manager component",
+ "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
"homepage": "https://www.doctrine-project.org/projects/event-manager.html",
"keywords": [
"event",
- "eventdispatcher",
- "eventmanager"
+ "event dispatcher",
+ "event manager",
+ "event system",
+ "events"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/event-manager/issues",
+ "source": "https://github.com/doctrine/event-manager/tree/2.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
+ "type": "tidelift"
+ }
],
- "time": "2018-06-11T11:59:03+00:00"
+ "time": "2024-05-22T20:47:39+00:00"
},
{
"name": "doctrine/inflector",
- "version": "v1.3.0",
+ "version": "2.0.10",
"source": {
"type": "git",
"url": "https://github.com/doctrine/inflector.git",
- "reference": "5527a48b7313d15261292c149e55e26eae771b0a"
+ "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/inflector/zipball/5527a48b7313d15261292c149e55e26eae771b0a",
- "reference": "5527a48b7313d15261292c149e55e26eae771b0a",
+ "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc",
+ "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": "^7.2 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.2"
+ "doctrine/coding-standard": "^11.0",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpstan/phpstan-strict-rules": "^1.3",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "vimeo/psalm": "^4.25 || ^5.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.3.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\Inflector\\": "lib/Doctrine/Common/Inflector"
+ "Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -492,6 +623,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -500,10 +635,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -513,48 +644,68 @@
"email": "schmittjoh@gmail.com"
}
],
- "description": "Common String Manipulations with regard to casing and singular/plural rules.",
- "homepage": "http://www.doctrine-project.org",
+ "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
+ "homepage": "https://www.doctrine-project.org/projects/inflector.html",
"keywords": [
"inflection",
- "pluralize",
- "singularize",
- "string"
+ "inflector",
+ "lowercase",
+ "manipulation",
+ "php",
+ "plural",
+ "singular",
+ "strings",
+ "uppercase",
+ "words"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/inflector/issues",
+ "source": "https://github.com/doctrine/inflector/tree/2.0.10"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
+ "type": "tidelift"
+ }
],
- "time": "2018-01-09T20:05:19+00:00"
+ "time": "2024-02-18T20:23:39+00:00"
},
{
"name": "doctrine/instantiator",
- "version": "1.2.0",
+ "version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a"
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a",
- "reference": "a2c590166b2133a4633738648b6b064edae0814a",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
+ "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": "^8.1"
},
"require-dev": {
- "doctrine/coding-standard": "^6.0",
+ "doctrine/coding-standard": "^11",
"ext-pdo": "*",
"ext-phar": "*",
- "phpbench/phpbench": "^0.13",
- "phpstan/phpstan-phpunit": "^0.11",
- "phpstan/phpstan-shim": "^0.11",
- "phpunit/phpunit": "^7.0"
+ "phpbench/phpbench": "^1.2",
+ "phpstan/phpstan": "^1.9.4",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^9.5.27",
+ "vimeo/psalm": "^5.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
@@ -568,7 +719,7 @@
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
+ "homepage": "https://ocramius.github.io/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
@@ -577,34 +728,54 @@
"constructor",
"instantiate"
],
- "time": "2019-03-17T17:37:11+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-30T00:23:10+00:00"
},
{
"name": "doctrine/lexer",
- "version": "v1.0.1",
+ "version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
- "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
- "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
+ "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": "^8.1"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "require-dev": {
+ "doctrine/coding-standard": "^12",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^10.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^5.21"
},
+ "type": "library",
"autoload": {
- "psr-0": {
- "Doctrine\\Common\\Lexer\\": "lib/"
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -612,73 +783,109 @@
"MIT"
],
"authors": [
- {
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
- "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
- "homepage": "http://www.doctrine-project.org",
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
"keywords": [
+ "annotations",
+ "docblock",
"lexer",
- "parser"
+ "parser",
+ "php"
],
- "time": "2014-09-09T13:34:57+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-02-05T11:56:58+00:00"
},
{
"name": "doctrine/orm",
- "version": "v2.6.3",
+ "version": "2.19.6",
"source": {
"type": "git",
"url": "https://github.com/doctrine/orm.git",
- "reference": "434820973cadf2da2d66e7184be370084cc32ca8"
+ "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/orm/zipball/434820973cadf2da2d66e7184be370084cc32ca8",
- "reference": "434820973cadf2da2d66e7184be370084cc32ca8",
+ "url": "https://api.github.com/repos/doctrine/orm/zipball/c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073",
+ "reference": "c1bb2ccf4b19c845f91ff7c4c01dc7cbba7f4073",
"shasum": ""
},
"require": {
- "doctrine/annotations": "~1.5",
- "doctrine/cache": "~1.6",
- "doctrine/collections": "^1.4",
- "doctrine/common": "^2.7.1",
- "doctrine/dbal": "^2.6",
- "doctrine/instantiator": "~1.1",
- "ext-pdo": "*",
- "php": "^7.1",
- "symfony/console": "~3.0|~4.0"
+ "composer-runtime-api": "^2",
+ "doctrine/cache": "^1.12.1 || ^2.1.1",
+ "doctrine/collections": "^1.5 || ^2.1",
+ "doctrine/common": "^3.0.3",
+ "doctrine/dbal": "^2.13.1 || ^3.2",
+ "doctrine/deprecations": "^0.5.3 || ^1",
+ "doctrine/event-manager": "^1.2 || ^2",
+ "doctrine/inflector": "^1.4 || ^2.0",
+ "doctrine/instantiator": "^1.3 || ^2",
+ "doctrine/lexer": "^2 || ^3",
+ "doctrine/persistence": "^2.4 || ^3",
+ "ext-ctype": "*",
+ "php": "^7.1 || ^8.0",
+ "psr/cache": "^1 || ^2 || ^3",
+ "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/polyfill-php72": "^1.23",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "conflict": {
+ "doctrine/annotations": "<1.13 || >= 3.0"
},
"require-dev": {
- "doctrine/coding-standard": "^1.0",
- "phpunit/phpunit": "^6.5",
- "squizlabs/php_codesniffer": "^3.2",
- "symfony/yaml": "~3.4|~4.0"
+ "doctrine/annotations": "^1.13 || ^2",
+ "doctrine/coding-standard": "^9.0.2 || ^12.0",
+ "phpbench/phpbench": "^0.16.10 || ^1.0",
+ "phpstan/phpstan": "~1.4.10 || 1.11.1",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6",
+ "psr/log": "^1 || ^2 || ^3",
+ "squizlabs/php_codesniffer": "3.7.2",
+ "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0",
+ "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0",
+ "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
+ "vimeo/psalm": "4.30.0 || 5.24.0"
},
"suggest": {
+ "ext-dom": "Provides support for XSD validation for XML mapping files",
+ "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0",
"symfony/yaml": "If you want to use YAML Metadata Mapping Driver"
},
"bin": [
"bin/doctrine"
],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.6.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\ORM\\": "lib/Doctrine/ORM"
+ "Doctrine\\ORM\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -686,6 +893,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -694,10 +905,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -708,52 +915,53 @@
}
],
"description": "Object-Relational-Mapper for PHP",
- "homepage": "http://www.doctrine-project.org",
+ "homepage": "https://www.doctrine-project.org/projects/orm.html",
"keywords": [
"database",
"orm"
],
- "time": "2018-11-20T23:46:46+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/orm/issues",
+ "source": "https://github.com/doctrine/orm/tree/2.19.6"
+ },
+ "time": "2024-06-26T17:24:40+00:00"
},
{
"name": "doctrine/persistence",
- "version": "v1.1.0",
+ "version": "3.3.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/persistence.git",
- "reference": "c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38"
+ "reference": "b337726451f5d530df338fc7f68dee8781b49779"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/persistence/zipball/c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38",
- "reference": "c0f1c17602afc18b4cbd8e1c8125f264c9cf7d38",
+ "url": "https://api.github.com/repos/doctrine/persistence/zipball/b337726451f5d530df338fc7f68dee8781b49779",
+ "reference": "b337726451f5d530df338fc7f68dee8781b49779",
"shasum": ""
},
"require": {
- "doctrine/annotations": "^1.0",
- "doctrine/cache": "^1.0",
- "doctrine/collections": "^1.0",
- "doctrine/event-manager": "^1.0",
- "doctrine/reflection": "^1.0",
- "php": "^7.1"
+ "doctrine/event-manager": "^1 || ^2",
+ "php": "^7.2 || ^8.0",
+ "psr/cache": "^1.0 || ^2.0 || ^3.0"
},
"conflict": {
- "doctrine/common": "<2.10@dev"
+ "doctrine/common": "<2.10"
},
"require-dev": {
- "doctrine/coding-standard": "^5.0",
- "phpstan/phpstan": "^0.8",
- "phpunit/phpunit": "^7.0"
+ "doctrine/coding-standard": "^12",
+ "doctrine/common": "^3.0",
+ "phpstan/phpstan": "1.11.1",
+ "phpstan/phpstan-phpunit": "^1",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "symfony/cache": "^4.4 || ^5.4 || ^6.0",
+ "vimeo/psalm": "4.30.0 || 5.24.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.1.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Doctrine\\Common\\": "lib/Doctrine/Common"
+ "Doctrine\\Persistence\\": "src/Persistence"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -761,6 +969,10 @@
"MIT"
],
"authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
@@ -769,10 +981,6 @@
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
@@ -787,7 +995,7 @@
}
],
"description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.",
- "homepage": "https://doctrine-project.org/projects/persistence.html",
+ "homepage": "https://www.doctrine-project.org/projects/persistence.html",
"keywords": [
"mapper",
"object",
@@ -795,225 +1003,122 @@
"orm",
"persistence"
],
- "time": "2018-11-21T00:33:13+00:00"
- },
- {
- "name": "doctrine/reflection",
- "version": "v1.0.0",
- "source": {
- "type": "git",
- "url": "https://github.com/doctrine/reflection.git",
- "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/doctrine/reflection/zipball/02538d3f95e88eb397a5f86274deb2c6175c2ab6",
- "reference": "02538d3f95e88eb397a5f86274deb2c6175c2ab6",
- "shasum": ""
- },
- "require": {
- "doctrine/annotations": "^1.0",
- "ext-tokenizer": "*",
- "php": "^7.1"
- },
- "require-dev": {
- "doctrine/coding-standard": "^4.0",
- "doctrine/common": "^2.8",
- "phpstan/phpstan": "^0.9.2",
- "phpstan/phpstan-phpunit": "^0.9.4",
- "phpunit/phpunit": "^7.0",
- "squizlabs/php_codesniffer": "^3.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Doctrine\\Common\\": "lib/Doctrine/Common"
- }
+ "support": {
+ "issues": "https://github.com/doctrine/persistence/issues",
+ "source": "https://github.com/doctrine/persistence/tree/3.3.3"
},
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
+ "funding": [
{
- "name": "Roman Borschel",
- "email": "roman@code-factory.org"
- },
- {
- "name": "Benjamin Eberlei",
- "email": "kontakt@beberlei.de"
- },
- {
- "name": "Guilherme Blanco",
- "email": "guilhermeblanco@gmail.com"
- },
- {
- "name": "Jonathan Wage",
- "email": "jonwage@gmail.com"
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
},
{
- "name": "Johannes Schmitt",
- "email": "schmittjoh@gmail.com"
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
},
{
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence",
+ "type": "tidelift"
}
],
- "description": "Doctrine Reflection component",
- "homepage": "https://www.doctrine-project.org/projects/reflection.html",
- "keywords": [
- "reflection"
- ],
- "time": "2018-06-14T14:45:07+00:00"
+ "time": "2024-06-20T10:14:30+00:00"
},
{
- "name": "friendsofsymfony/rest-bundle",
- "version": "2.5.0",
+ "name": "elasticsearch/elasticsearch",
+ "version": "v7.17.2",
"source": {
"type": "git",
- "url": "https://github.com/FriendsOfSymfony/FOSRestBundle.git",
- "reference": "a5fc73b84bdb2f0fdf58a717b322ceb6997f7bf3"
+ "url": "https://github.com/elastic/elasticsearch-php.git",
+ "reference": "2d302233f2bb0926812d82823bb820d405e130fc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfSymfony/FOSRestBundle/zipball/a5fc73b84bdb2f0fdf58a717b322ceb6997f7bf3",
- "reference": "a5fc73b84bdb2f0fdf58a717b322ceb6997f7bf3",
+ "url": "https://api.github.com/repos/elastic/elasticsearch-php/zipball/2d302233f2bb0926812d82823bb820d405e130fc",
+ "reference": "2d302233f2bb0926812d82823bb820d405e130fc",
"shasum": ""
},
"require": {
- "doctrine/inflector": "^1.0",
- "php": "^5.5.9|~7.0",
- "psr/log": "^1.0",
- "symfony/config": "^3.4|^4.0",
- "symfony/debug": "^3.4|^4.0",
- "symfony/dependency-injection": "^3.4|^4.0",
- "symfony/event-dispatcher": "^3.4|^4.0",
- "symfony/finder": "^3.4|^4.0",
- "symfony/framework-bundle": "^3.4|^4.0",
- "symfony/http-foundation": "^3.4|^4.0",
- "symfony/http-kernel": "^3.4|^4.0",
- "symfony/routing": "^3.4|^4.0",
- "symfony/security-core": "^3.4|^4.0",
- "symfony/templating": "^3.4|^4.0",
- "willdurand/jsonp-callback-validator": "^1.0",
- "willdurand/negotiation": "^2.0"
- },
- "conflict": {
- "jms/serializer": "<1.13.0",
- "jms/serializer-bundle": "<2.0.0",
- "sensio/framework-extra-bundle": "<3.0.13"
+ "ext-json": ">=1.3.7",
+ "ezimuel/ringphp": "^1.1.2",
+ "php": "^7.3 || ^8.0",
+ "psr/log": "^1|^2|^3"
},
"require-dev": {
- "jms/serializer": "^1.13|^2.0",
- "jms/serializer-bundle": "^2.3.1|^3.0",
- "phpoption/phpoption": "^1.1",
- "psr/http-message": "^1.0",
- "sensio/framework-extra-bundle": "^3.0.13|^4.0|^5.0",
- "symfony/asset": "^3.4|^4.0",
- "symfony/browser-kit": "^3.4|^4.0",
- "symfony/css-selector": "^3.4|^4.0",
- "symfony/dependency-injection": "^2.7.20|^3.0|^4.0",
- "symfony/expression-language": "~2.7|^3.0|^4.0",
- "symfony/form": "^3.4|^4.0",
- "symfony/phpunit-bridge": "^4.1.8",
- "symfony/security-bundle": "^3.4|^4.0",
- "symfony/serializer": "^2.7.11|^3.0.4|^4.0",
- "symfony/twig-bundle": "^3.4|^4.0",
- "symfony/validator": "^3.4|^4.0",
- "symfony/web-profiler-bundle": "^3.4|^4.0",
- "symfony/yaml": "^3.4|^4.0"
+ "ext-yaml": "*",
+ "ext-zip": "*",
+ "mockery/mockery": "^1.2",
+ "phpstan/phpstan": "^1.10",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "^3.4",
+ "symfony/finder": "~4.0"
},
"suggest": {
- "jms/serializer-bundle": "Add support for advanced serialization capabilities, recommended, requires ^2.0|^3.0",
- "sensio/framework-extra-bundle": "Add support for the request body converter and the view response listener, requires ^3.0",
- "symfony/expression-language": "Add support for using the expression language in the routing, requires ^2.7|^3.0",
- "symfony/serializer": "Add support for basic serialization capabilities and xml decoding, requires ^2.7|^3.0",
- "symfony/validator": "Add support for validation capabilities in the ParamFetcher, requires ^2.7|^3.0"
- },
- "type": "symfony-bundle",
- "extra": {
- "branch-alias": {
- "dev-master": "2.5-dev"
- }
+ "ext-curl": "*",
+ "monolog/monolog": "Allows for client-level logging and tracing"
},
+ "type": "library",
"autoload": {
+ "files": [
+ "src/autoload.php"
+ ],
"psr-4": {
- "FOS\\RestBundle\\": ""
- },
- "exclude-from-classmap": [
- "Tests/"
- ]
+ "Elasticsearch\\": "src/Elasticsearch/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "Apache-2.0",
+ "LGPL-2.1-only"
],
"authors": [
{
- "name": "Lukas Kahwe Smith",
- "email": "smith@pooteeweet.org"
- },
- {
- "name": "FriendsOfSymfony Community",
- "homepage": "https://github.com/friendsofsymfony/FOSRestBundle/contributors"
+ "name": "Zachary Tong"
},
{
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com"
+ "name": "Enrico Zimuel"
}
],
- "description": "This Bundle provides various tools to rapidly develop RESTful API's with Symfony",
- "homepage": "http://friendsofsymfony.github.com",
+ "description": "PHP Client for Elasticsearch",
"keywords": [
- "rest"
+ "client",
+ "elasticsearch",
+ "search"
],
- "time": "2019-01-03T13:05:12+00:00"
+ "support": {
+ "issues": "https://github.com/elastic/elasticsearch-php/issues",
+ "source": "https://github.com/elastic/elasticsearch-php/tree/v7.17.2"
+ },
+ "time": "2023-04-21T15:31:12+00:00"
},
{
- "name": "guzzlehttp/guzzle",
- "version": "6.3.3",
+ "name": "ezimuel/guzzlestreams",
+ "version": "3.1.0",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/guzzle.git",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
+ "url": "https://github.com/ezimuel/guzzlestreams.git",
+ "reference": "b4b5a025dfee70d6cd34c780e07330eb93d5b997"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
- "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
+ "url": "https://api.github.com/repos/ezimuel/guzzlestreams/zipball/b4b5a025dfee70d6cd34c780e07330eb93d5b997",
+ "reference": "b4b5a025dfee70d6cd34c780e07330eb93d5b997",
"shasum": ""
},
"require": {
- "guzzlehttp/promises": "^1.0",
- "guzzlehttp/psr7": "^1.4",
- "php": ">=5.5"
+ "php": ">=5.4.0"
},
"require-dev": {
- "ext-curl": "*",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
- "psr/log": "^1.0"
- },
- "suggest": {
- "psr/log": "Required for using the Log middleware"
+ "phpunit/phpunit": "~9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.3-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
- "files": [
- "src/functions_include.php"
- ],
"psr-4": {
- "GuzzleHttp\\": "src/"
+ "GuzzleHttp\\Stream\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1027,52 +1132,56 @@
"homepage": "https://github.com/mtdowling"
}
],
- "description": "Guzzle is a PHP HTTP client library",
+ "description": "Fork of guzzle/streams (abandoned) to be used with elasticsearch-php",
"homepage": "http://guzzlephp.org/",
"keywords": [
- "client",
- "curl",
- "framework",
- "http",
- "http client",
- "rest",
- "web service"
+ "Guzzle",
+ "stream"
],
- "time": "2018-04-22T15:46:56+00:00"
+ "support": {
+ "source": "https://github.com/ezimuel/guzzlestreams/tree/3.1.0"
+ },
+ "time": "2022-10-24T12:58:50+00:00"
},
{
- "name": "guzzlehttp/promises",
- "version": "v1.3.1",
+ "name": "ezimuel/ringphp",
+ "version": "1.2.2",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/promises.git",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646"
+ "url": "https://github.com/ezimuel/ringphp.git",
+ "reference": "7887fc8488013065f72f977dcb281994f5fde9f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646",
- "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646",
+ "url": "https://api.github.com/repos/ezimuel/ringphp/zipball/7887fc8488013065f72f977dcb281994f5fde9f4",
+ "reference": "7887fc8488013065f72f977dcb281994f5fde9f4",
"shasum": ""
},
"require": {
- "php": ">=5.5.0"
+ "ezimuel/guzzlestreams": "^3.0.1",
+ "php": ">=5.4.0",
+ "react/promise": "~2.0"
+ },
+ "replace": {
+ "guzzlehttp/ringphp": "self.version"
},
"require-dev": {
- "phpunit/phpunit": "^4.0"
+ "ext-curl": "*",
+ "phpunit/phpunit": "~9.0"
+ },
+ "suggest": {
+ "ext-curl": "Guzzle will use specific adapters if cURL is present"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4-dev"
+ "dev-master": "1.1-dev"
}
},
"autoload": {
"psr-4": {
- "GuzzleHttp\\Promise\\": "src/"
- },
- "files": [
- "src/functions_include.php"
- ]
+ "GuzzleHttp\\Ring\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1085,49 +1194,37 @@
"homepage": "https://github.com/mtdowling"
}
],
- "description": "Guzzle promises library",
- "keywords": [
- "promise"
- ],
- "time": "2016-12-20T10:07:11+00:00"
+ "description": "Fork of guzzle/RingPHP (abandoned) to be used with elasticsearch-php",
+ "support": {
+ "source": "https://github.com/ezimuel/ringphp/tree/1.2.2"
+ },
+ "time": "2022-12-07T11:28:53+00:00"
},
{
- "name": "guzzlehttp/psr7",
- "version": "1.5.2",
+ "name": "lambdish/phunctional",
+ "version": "v2.1.0",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/psr7.git",
- "reference": "9f83dded91781a01c63574e387eaa769be769115"
+ "url": "https://github.com/Lambdish/phunctional.git",
+ "reference": "ed3482e7da134d886789abb33c6df22a5d2f271c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
- "reference": "9f83dded91781a01c63574e387eaa769be769115",
+ "url": "https://api.github.com/repos/Lambdish/phunctional/zipball/ed3482e7da134d886789abb33c6df22a5d2f271c",
+ "reference": "ed3482e7da134d886789abb33c6df22a5d2f271c",
"shasum": ""
},
"require": {
- "php": ">=5.4.0",
- "psr/http-message": "~1.0",
- "ralouphie/getallheaders": "^2.0.5"
- },
- "provide": {
- "psr/http-message-implementation": "1.0"
+ "php": ">=7.2"
},
"require-dev": {
- "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
+ "phpstan/phpstan": "^0.11.16",
+ "phpunit/phpunit": "^8.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.5-dev"
- }
- },
"autoload": {
- "psr-4": {
- "GuzzleHttp\\Psr7\\": "src/"
- },
"files": [
- "src/functions_include.php"
+ "src/_bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -1136,226 +1233,299 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Eloi Poch"
+ },
+ {
+ "name": "Jorge Γvila"
},
{
- "name": "Tobias Schultze",
- "homepage": "https://github.com/Tobion"
+ "name": "Rafa GΓ³mez"
}
],
- "description": "PSR-7 message implementation that also provides common utility methods",
+ "description": "Ξ» PHP functional library",
"keywords": [
- "http",
- "message",
- "psr-7",
- "request",
- "response",
- "stream",
- "uri",
- "url"
+ "functional",
+ "generator",
+ "lambda",
+ "library",
+ "php"
],
- "time": "2018-12-04T20:46:45+00:00"
+ "support": {
+ "issues": "https://github.com/Lambdish/phunctional/issues",
+ "source": "https://github.com/Lambdish/phunctional/tree/v2.1.0"
+ },
+ "time": "2020-09-18T07:22:08+00:00"
},
{
- "name": "incenteev/composer-parameter-handler",
- "version": "v2.1.3",
+ "name": "laminas/laminas-code",
+ "version": "4.14.0",
"source": {
"type": "git",
- "url": "https://github.com/Incenteev/ParameterHandler.git",
- "reference": "933c45a34814f27f2345c11c37d46b3ca7303550"
+ "url": "https://github.com/laminas/laminas-code.git",
+ "reference": "562e02b7d85cb9142b5116cc76c4c7c162a11a1c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Incenteev/ParameterHandler/zipball/933c45a34814f27f2345c11c37d46b3ca7303550",
- "reference": "933c45a34814f27f2345c11c37d46b3ca7303550",
+ "url": "https://api.github.com/repos/laminas/laminas-code/zipball/562e02b7d85cb9142b5116cc76c4c7c162a11a1c",
+ "reference": "562e02b7d85cb9142b5116cc76c4c7c162a11a1c",
"shasum": ""
},
"require": {
- "php": ">=5.3.3",
- "symfony/yaml": "^2.3 || ^3.0 || ^4.0"
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
},
"require-dev": {
- "composer/composer": "^1.0@dev",
- "symfony/filesystem": "^2.3 || ^3 || ^4",
- "symfony/phpunit-bridge": "^4.0"
+ "doctrine/annotations": "^2.0.1",
+ "ext-phar": "*",
+ "laminas/laminas-coding-standard": "^2.5.0",
+ "laminas/laminas-stdlib": "^3.17.0",
+ "phpunit/phpunit": "^10.3.3",
+ "psalm/plugin-phpunit": "^0.19.0",
+ "vimeo/psalm": "^5.15.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.1.x-dev"
- }
+ "suggest": {
+ "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features",
+ "laminas/laminas-stdlib": "Laminas\\Stdlib component"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Incenteev\\ParameterHandler\\": ""
+ "Laminas\\Code\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
- "authors": [
+ "description": "Extensions to the PHP Reflection API, static code scanning, and code generation",
+ "homepage": "https://laminas.dev",
+ "keywords": [
+ "code",
+ "laminas",
+ "laminasframework"
+ ],
+ "support": {
+ "chat": "https://laminas.dev/chat",
+ "docs": "https://docs.laminas.dev/laminas-code/",
+ "forum": "https://discourse.laminas.dev",
+ "issues": "https://github.com/laminas/laminas-code/issues",
+ "rss": "https://github.com/laminas/laminas-code/releases.atom",
+ "source": "https://github.com/laminas/laminas-code"
+ },
+ "funding": [
{
- "name": "Christophe Coevoet",
- "email": "stof@notk.org"
+ "url": "https://funding.communitybridge.org/projects/laminas-project",
+ "type": "community_bridge"
}
],
- "description": "Composer script handling your ignored parameter file",
- "homepage": "https://github.com/Incenteev/ParameterHandler",
- "keywords": [
- "parameters management"
- ],
- "time": "2018-02-13T18:05:56+00:00"
+ "time": "2024-06-17T08:50:25+00:00"
},
{
- "name": "jms/metadata",
- "version": "1.7.0",
+ "name": "laminas/laminas-zendframework-bridge",
+ "version": "1.8.0",
"source": {
"type": "git",
- "url": "https://github.com/schmittjoh/metadata.git",
- "reference": "e5854ab1aa643623dc64adde718a8eec32b957a8"
+ "url": "https://github.com/laminas/laminas-zendframework-bridge.git",
+ "reference": "eb0d96c708b92177a92bc2239543d3ed523452c6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/metadata/zipball/e5854ab1aa643623dc64adde718a8eec32b957a8",
- "reference": "e5854ab1aa643623dc64adde718a8eec32b957a8",
+ "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/eb0d96c708b92177a92bc2239543d3ed523452c6",
+ "reference": "eb0d96c708b92177a92bc2239543d3ed523452c6",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": "~8.1.0 || ~8.2.0 || ~8.3.0"
},
"require-dev": {
- "doctrine/cache": "~1.0",
- "symfony/cache": "~3.1"
+ "phpunit/phpunit": "^10.4",
+ "psalm/plugin-phpunit": "^0.18.0",
+ "squizlabs/php_codesniffer": "^3.7.1",
+ "vimeo/psalm": "^5.16.0"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "1.5.x-dev"
+ "laminas": {
+ "module": "Laminas\\ZendFrameworkBridge"
}
},
"autoload": {
- "psr-0": {
- "Metadata\\": "src/"
+ "files": [
+ "src/autoload.php"
+ ],
+ "psr-4": {
+ "Laminas\\ZendFrameworkBridge\\": "src//"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
- "authors": [
- {
- "name": "Asmir Mustafic",
- "email": "goetas@gmail.com"
- },
+ "description": "Alias legacy ZF class names to Laminas Project equivalents.",
+ "keywords": [
+ "ZendFramework",
+ "autoloading",
+ "laminas",
+ "zf"
+ ],
+ "support": {
+ "forum": "https://discourse.laminas.dev/",
+ "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues",
+ "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom",
+ "source": "https://github.com/laminas/laminas-zendframework-bridge"
+ },
+ "funding": [
{
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
+ "url": "https://funding.communitybridge.org/projects/laminas-project",
+ "type": "community_bridge"
}
],
- "description": "Class/method/property metadata management in PHP",
- "keywords": [
- "annotations",
- "metadata",
- "xml",
- "yaml"
- ],
- "time": "2018-10-26T12:40:10+00:00"
+ "abandoned": true,
+ "time": "2023-11-24T13:56:19+00:00"
},
{
- "name": "jms/parser-lib",
- "version": "1.0.0",
+ "name": "monolog/monolog",
+ "version": "3.7.0",
"source": {
"type": "git",
- "url": "https://github.com/schmittjoh/parser-lib.git",
- "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d"
+ "url": "https://github.com/Seldaek/monolog.git",
+ "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/parser-lib/zipball/c509473bc1b4866415627af0e1c6cc8ac97fa51d",
- "reference": "c509473bc1b4866415627af0e1c6cc8ac97fa51d",
+ "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
+ "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
"shasum": ""
},
"require": {
- "phpoption/phpoption": ">=0.9,<2.0-dev"
+ "php": ">=8.1",
+ "psr/log": "^2.0 || ^3.0"
+ },
+ "provide": {
+ "psr/log-implementation": "3.0.0"
+ },
+ "require-dev": {
+ "aws/aws-sdk-php": "^3.0",
+ "doctrine/couchdb": "~1.0@dev",
+ "elasticsearch/elasticsearch": "^7 || ^8",
+ "ext-json": "*",
+ "graylog2/gelf-php": "^1.4.2 || ^2.0",
+ "guzzlehttp/guzzle": "^7.4.5",
+ "guzzlehttp/psr7": "^2.2",
+ "mongodb/mongodb": "^1.8",
+ "php-amqplib/php-amqplib": "~2.4 || ^3",
+ "phpstan/phpstan": "^1.9",
+ "phpstan/phpstan-deprecation-rules": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.4",
+ "phpunit/phpunit": "^10.5.17",
+ "predis/predis": "^1.1 || ^2",
+ "ruflin/elastica": "^7",
+ "symfony/mailer": "^5.4 || ^6",
+ "symfony/mime": "^5.4 || ^6"
+ },
+ "suggest": {
+ "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
+ "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
+ "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
+ "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
+ "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
+ "ext-mbstring": "Allow to work properly with unicode symbols",
+ "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
+ "ext-openssl": "Required to send log messages using SSL",
+ "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
+ "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
+ "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
+ "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
+ "rollbar/rollbar": "Allow sending log messages to Rollbar",
+ "ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
- "psr-0": {
- "JMS\\": "src/"
+ "psr-4": {
+ "Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "Apache2"
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "https://seld.be"
+ }
+ ],
+ "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
+ "homepage": "https://github.com/Seldaek/monolog",
+ "keywords": [
+ "log",
+ "logging",
+ "psr-3"
+ ],
+ "support": {
+ "issues": "https://github.com/Seldaek/monolog/issues",
+ "source": "https://github.com/Seldaek/monolog/tree/3.7.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Seldaek",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
+ "type": "tidelift"
+ }
],
- "description": "A library for easily creating recursive-descent parsers.",
- "time": "2012-11-18T18:08:43+00:00"
+ "time": "2024-06-28T09:40:51+00:00"
},
{
- "name": "jms/serializer",
- "version": "1.13.0",
+ "name": "ocramius/proxy-manager",
+ "version": "2.14.1",
"source": {
"type": "git",
- "url": "https://github.com/schmittjoh/serializer.git",
- "reference": "00863e1d55b411cc33ad3e1de09a4c8d3aae793c"
+ "url": "https://github.com/Ocramius/ProxyManager.git",
+ "reference": "3990d60ef79001badbab4927a6a811682274a0d1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/serializer/zipball/00863e1d55b411cc33ad3e1de09a4c8d3aae793c",
- "reference": "00863e1d55b411cc33ad3e1de09a4c8d3aae793c",
+ "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/3990d60ef79001badbab4927a6a811682274a0d1",
+ "reference": "3990d60ef79001badbab4927a6a811682274a0d1",
"shasum": ""
},
"require": {
- "doctrine/annotations": "^1.0",
- "doctrine/instantiator": "^1.0.3",
- "jms/metadata": "^1.3",
- "jms/parser-lib": "1.*",
- "php": "^5.5|^7.0",
- "phpcollection/phpcollection": "~0.1",
- "phpoption/phpoption": "^1.1"
+ "composer-runtime-api": "^2.1.0",
+ "laminas/laminas-code": "^4.4.2",
+ "php": "~8.0.0",
+ "webimpress/safe-writer": "^2.2.0"
},
"conflict": {
- "twig/twig": "<1.12"
+ "thecodingmachine/safe": "<1.3.3"
},
"require-dev": {
- "doctrine/orm": "~2.1",
- "doctrine/phpcr-odm": "^1.3|^2.0",
- "ext-pdo_sqlite": "*",
- "jackalope/jackalope-doctrine-dbal": "^1.1.5",
- "phpunit/phpunit": "^4.8|^5.0",
- "propel/propel1": "~1.7",
- "psr/container": "^1.0",
- "symfony/dependency-injection": "^2.7|^3.3|^4.0",
- "symfony/expression-language": "^2.6|^3.0",
- "symfony/filesystem": "^2.1",
- "symfony/form": "~2.1|^3.0",
- "symfony/translation": "^2.1|^3.0",
- "symfony/validator": "^2.2|^3.0",
- "symfony/yaml": "^2.1|^3.0",
- "twig/twig": "~1.12|~2.0"
+ "codelicia/xulieta": "^0.1.6",
+ "doctrine/coding-standard": "^9.0.0",
+ "ext-phar": "*",
+ "phpbench/phpbench": "^1.0.3",
+ "phpunit/phpunit": "^9.5.6",
+ "roave/infection-static-analysis-plugin": "^1.8",
+ "squizlabs/php_codesniffer": "^3.6.0",
+ "vimeo/psalm": "^4.8.1"
},
"suggest": {
- "doctrine/cache": "Required if you like to use cache functionality.",
- "doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.",
- "symfony/yaml": "Required if you'd like to serialize data to YAML format."
+ "laminas/laminas-json": "To have the JsonRpc adapter (Remote Object feature)",
+ "laminas/laminas-soap": "To have the Soap adapter (Remote Object feature)",
+ "laminas/laminas-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)",
+ "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-1.x": "1.13-dev"
- }
- },
"autoload": {
- "psr-0": {
- "JMS\\Serializer": "src/"
+ "psr-4": {
+ "ProxyManager\\": "src/ProxyManager"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1364,124 +1534,131 @@
],
"authors": [
{
- "name": "Asmir Mustafic",
- "email": "goetas@gmail.com"
- },
- {
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "https://ocramius.github.io/"
}
],
- "description": "Library for (de-)serializing data of any complexity; supports XML, JSON, and YAML.",
- "homepage": "http://jmsyst.com/libs/serializer",
+ "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies",
+ "homepage": "https://github.com/Ocramius/ProxyManager",
"keywords": [
- "deserialization",
- "jaxb",
- "json",
- "serialization",
- "xml"
+ "aop",
+ "lazy loading",
+ "proxy",
+ "proxy pattern",
+ "service proxies"
+ ],
+ "support": {
+ "issues": "https://github.com/Ocramius/ProxyManager/issues",
+ "source": "https://github.com/Ocramius/ProxyManager/tree/2.14.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Ocramius",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/ocramius/proxy-manager",
+ "type": "tidelift"
+ }
],
- "time": "2018-07-25T13:58:54+00:00"
+ "time": "2022-03-05T18:43:14+00:00"
},
{
- "name": "jms/serializer-bundle",
- "version": "2.4.4",
+ "name": "promphp/prometheus_client_php",
+ "version": "v2.11.0",
"source": {
"type": "git",
- "url": "https://github.com/schmittjoh/JMSSerializerBundle.git",
- "reference": "92ee808c64c1c180775a0e57d00e3be0674668fb"
+ "url": "https://github.com/PromPHP/prometheus_client_php.git",
+ "reference": "35d5a68628ea18209938bc1b8796646015ab93cf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/JMSSerializerBundle/zipball/92ee808c64c1c180775a0e57d00e3be0674668fb",
- "reference": "92ee808c64c1c180775a0e57d00e3be0674668fb",
+ "url": "https://api.github.com/repos/PromPHP/prometheus_client_php/zipball/35d5a68628ea18209938bc1b8796646015ab93cf",
+ "reference": "35d5a68628ea18209938bc1b8796646015ab93cf",
"shasum": ""
},
"require": {
- "jms/serializer": "^1.10",
- "php": "^5.4|^7.0",
- "phpoption/phpoption": "^1.1.0",
- "symfony/framework-bundle": "~2.3|~3.0|~4.0"
+ "ext-json": "*",
+ "php": "^7.2|^8.0"
+ },
+ "replace": {
+ "endclothing/prometheus_client_php": "*",
+ "jimdo/prometheus_client_php": "*",
+ "lkaemmerling/prometheus_client_php": "*"
},
"require-dev": {
- "doctrine/orm": "*",
- "phpunit/phpunit": "^4.8.35|^5.4.3|^6.0",
- "symfony/expression-language": "~2.6|~3.0|~4.0",
- "symfony/finder": "^2.3|^3.0|^4.0",
- "symfony/form": "*",
- "symfony/stopwatch": "*",
- "symfony/twig-bundle": "*",
- "symfony/validator": "*",
- "symfony/yaml": "*"
+ "guzzlehttp/guzzle": "^6.3|^7.0",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^1.5.4",
+ "phpstan/phpstan-phpunit": "^1.1.0",
+ "phpstan/phpstan-strict-rules": "^1.1.0",
+ "phpunit/phpunit": "^9.4",
+ "squizlabs/php_codesniffer": "^3.6",
+ "symfony/polyfill-apcu": "^1.6"
},
"suggest": {
- "jms/di-extra-bundle": "Required to get lazy loading (de)serialization visitors, ~1.3",
- "symfony/finder": "Required for cache warmup, supported versions ^2.3|^3.0|^4.0"
+ "ext-apc": "Required if using APCu.",
+ "ext-pdo": "Required if using PDO.",
+ "ext-redis": "Required if using Redis.",
+ "promphp/prometheus_push_gateway_php": "An easy client for using Prometheus PushGateway.",
+ "symfony/polyfill-apcu": "Required if you use APCu on PHP8.0+"
},
- "type": "symfony-bundle",
+ "type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.4-dev"
+ "dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
- "JMS\\SerializerBundle\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Prometheus\\": "src/Prometheus/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "Apache-2.0"
],
"authors": [
{
- "name": "Asmir Mustafic",
- "email": "goetas@gmail.com"
- },
- {
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Lukas KΓ€mmerling",
+ "email": "kontakt@lukas-kaemmerling.de"
}
],
- "description": "Allows you to easily serialize, and deserialize data of any complexity",
- "homepage": "http://jmsyst.com/bundles/JMSSerializerBundle",
- "keywords": [
- "deserialization",
- "jaxb",
- "json",
- "serialization",
- "xml"
- ],
- "time": "2019-03-30T10:26:09+00:00"
+ "description": "Prometheus instrumentation library for PHP applications.",
+ "support": {
+ "issues": "https://github.com/PromPHP/prometheus_client_php/issues",
+ "source": "https://github.com/PromPHP/prometheus_client_php/tree/v2.11.0"
+ },
+ "time": "2024-08-05T07:58:08+00:00"
},
{
- "name": "lambdish/phunctional",
- "version": "v1.0.6",
+ "name": "psr/cache",
+ "version": "3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/Lambdish/phunctional.git",
- "reference": "46fe90f9b2f7eb2c02d077a53ba05fc75396e7ad"
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Lambdish/phunctional/zipball/46fe90f9b2f7eb2c02d077a53ba05fc75396e7ad",
- "reference": "46fe90f9b2f7eb2c02d077a53ba05fc75396e7ad",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
+ "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf",
"shasum": ""
},
"require": {
- "php": ">=5.6.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^5.0"
+ "php": ">=8.0.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
"autoload": {
- "files": [
- "src/_bootstrap.php"
- ]
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1489,123 +1666,85 @@
],
"authors": [
{
- "name": "Jorge Γvila",
- "email": "avilacardenosa@gmail.com"
- },
- {
- "name": "Rafa GΓ³mez",
- "email": "rgomezcasas@gmail.com"
- },
- {
- "name": "Eloi Poch",
- "email": "eloi.poch@gmail.com"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "Ξ» PHP functional library",
+ "description": "Common interface for caching libraries",
"keywords": [
- "functional",
- "generator",
- "lambda",
- "library",
- "php"
+ "cache",
+ "psr",
+ "psr-6"
],
- "time": "2018-10-21T08:21:53+00:00"
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/3.0.0"
+ },
+ "time": "2021-02-03T23:26:27+00:00"
},
{
- "name": "maknz/slack",
- "version": "1.7.0",
+ "name": "psr/clock",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/maknz/slack.git",
- "reference": "7f21fefc70c76b304adc1b3a780c8740dfcfb595"
+ "url": "https://github.com/php-fig/clock.git",
+ "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/maknz/slack/zipball/7f21fefc70c76b304adc1b3a780c8740dfcfb595",
- "reference": "7f21fefc70c76b304adc1b3a780c8740dfcfb595",
+ "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d",
+ "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d",
"shasum": ""
},
"require": {
- "ext-mbstring": "*",
- "guzzlehttp/guzzle": "~6.0|~5.0|~4.0",
- "php": ">=5.4.0"
- },
- "require-dev": {
- "mockery/mockery": "0.9.*",
- "phpunit/phpunit": "4.2.*"
- },
- "suggest": {
- "illuminate/support": "Required for Laravel support"
+ "php": "^7.0 || ^8.0"
},
"type": "library",
"autoload": {
"psr-4": {
- "Maknz\\Slack\\": "src/"
+ "Psr\\Clock\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-2-Clause"
+ "MIT"
],
"authors": [
{
- "name": "maknz",
- "email": "github@mak.geek.nz"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "A simple PHP package for sending messages to Slack, with a focus on ease of use and elegant syntax. Includes Laravel support out of the box.",
+ "description": "Common interface for reading the clock.",
+ "homepage": "https://github.com/php-fig/clock",
"keywords": [
- "laravel",
- "slack"
+ "clock",
+ "now",
+ "psr",
+ "psr-20",
+ "time"
],
- "time": "2015-06-03T03:35:16+00:00"
+ "support": {
+ "issues": "https://github.com/php-fig/clock/issues",
+ "source": "https://github.com/php-fig/clock/tree/1.0.0"
+ },
+ "time": "2022-11-25T14:36:26+00:00"
},
{
- "name": "monolog/monolog",
- "version": "1.24.0",
+ "name": "psr/container",
+ "version": "2.0.2",
"source": {
"type": "git",
- "url": "https://github.com/Seldaek/monolog.git",
- "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
- "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
- "php": ">=5.3.0",
- "psr/log": "~1.0"
- },
- "provide": {
- "psr/log-implementation": "1.0.0"
- },
- "require-dev": {
- "aws/aws-sdk-php": "^2.4.9 || ^3.0",
- "doctrine/couchdb": "~1.0@dev",
- "graylog2/gelf-php": "~1.0",
- "jakub-onderka/php-parallel-lint": "0.9",
- "php-amqplib/php-amqplib": "~2.4",
- "php-console/php-console": "^3.1.3",
- "phpunit/phpunit": "~4.5",
- "phpunit/phpunit-mock-objects": "2.3.0",
- "ruflin/elastica": ">=0.90 <3.0",
- "sentry/sentry": "^0.13",
- "swiftmailer/swiftmailer": "^5.3|^6.0"
- },
- "suggest": {
- "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
- "doctrine/couchdb": "Allow sending log messages to a CouchDB server",
- "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
- "ext-mongo": "Allow sending log messages to a MongoDB server",
- "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
- "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
- "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
- "php-console/php-console": "Allow sending log messages to Google Chrome",
- "rollbar/rollbar": "Allow sending log messages to Rollbar",
- "ruflin/elastica": "Allow sending log messages to an Elastic Search server",
- "sentry/sentry": "Allow sending log messages to a Sentry server"
+ "php": ">=7.4.0"
},
"type": "library",
"extra": {
@@ -1615,7 +1754,7 @@
},
"autoload": {
"psr-4": {
- "Monolog\\": "src/Monolog"
+ "Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1624,55 +1763,51 @@
],
"authors": [
{
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "Sends your logs to files, sockets, inboxes, databases and various web services",
- "homepage": "http://github.com/Seldaek/monolog",
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
"keywords": [
- "log",
- "logging",
- "psr-3"
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
],
- "time": "2018-11-05T09:00:11+00:00"
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
+ },
+ "time": "2021-11-05T16:47:00+00:00"
},
{
- "name": "ocramius/package-versions",
- "version": "1.4.0",
+ "name": "psr/event-dispatcher",
+ "version": "1.0.0",
"source": {
"type": "git",
- "url": "https://github.com/Ocramius/PackageVersions.git",
- "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb"
+ "url": "https://github.com/php-fig/event-dispatcher.git",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
- "reference": "a4d4b60d0e60da2487bd21a2c6ac089f85570dbb",
+ "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
+ "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
- "composer-plugin-api": "^1.0.0",
- "php": "^7.1.0"
- },
- "require-dev": {
- "composer/composer": "^1.6.3",
- "doctrine/coding-standard": "^5.0.1",
- "ext-zip": "*",
- "infection/infection": "^0.7.1",
- "phpunit/phpunit": "^7.0.0"
+ "php": ">=7.2.0"
},
- "type": "composer-plugin",
+ "type": "library",
"extra": {
- "class": "PackageVersions\\Installer",
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
- "PackageVersions\\": "src/PackageVersions"
+ "Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1681,59 +1816,48 @@
],
"authors": [
{
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com"
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
}
],
- "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
- "time": "2019-02-21T12:16:21+00:00"
+ "description": "Standard interfaces for event handling.",
+ "keywords": [
+ "events",
+ "psr",
+ "psr-14"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/event-dispatcher/issues",
+ "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
+ },
+ "time": "2019-01-08T18:20:26+00:00"
},
{
- "name": "ocramius/proxy-manager",
- "version": "2.2.2",
+ "name": "psr/log",
+ "version": "3.0.0",
"source": {
"type": "git",
- "url": "https://github.com/Ocramius/ProxyManager.git",
- "reference": "14b137b06b0f911944132df9d51e445a35920ab1"
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/14b137b06b0f911944132df9d51e445a35920ab1",
- "reference": "14b137b06b0f911944132df9d51e445a35920ab1",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
+ "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"shasum": ""
},
"require": {
- "ocramius/package-versions": "^1.1.3",
- "php": "^7.2.0",
- "zendframework/zend-code": "^3.3.0"
- },
- "require-dev": {
- "couscous/couscous": "^1.6.1",
- "ext-phar": "*",
- "humbug/humbug": "1.0.0-RC.0@RC",
- "nikic/php-parser": "^3.1.1",
- "padraic/phpunit-accelerator": "dev-master@DEV",
- "phpbench/phpbench": "^0.12.2",
- "phpstan/phpstan": "dev-master#856eb10a81c1d27c701a83f167dc870fd8f4236a as 0.9.999",
- "phpstan/phpstan-phpunit": "dev-master#5629c0a1f4a9c417cb1077cf6693ad9753895761",
- "phpunit/phpunit": "^6.4.3",
- "squizlabs/php_codesniffer": "^2.9.1"
- },
- "suggest": {
- "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
- "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)",
- "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)",
- "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)"
+ "php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0.x-dev"
+ "dev-master": "3.x-dev"
}
},
"autoload": {
- "psr-0": {
- "ProxyManager\\": "src"
+ "psr-4": {
+ "Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1742,191 +1866,230 @@
],
"authors": [
{
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.io/"
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
}
],
- "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies",
- "homepage": "https://github.com/Ocramius/ProxyManager",
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
"keywords": [
- "aop",
- "lazy loading",
- "proxy",
- "proxy pattern",
- "service proxies"
+ "log",
+ "psr",
+ "psr-3"
],
- "time": "2018-09-27T13:45:01+00:00"
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/3.0.0"
+ },
+ "time": "2021-07-14T16:46:02+00:00"
},
{
- "name": "paragonie/random_compat",
- "version": "v9.99.99",
+ "name": "ramsey/collection",
+ "version": "2.0.0",
"source": {
"type": "git",
- "url": "https://github.com/paragonie/random_compat.git",
- "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
+ "url": "https://github.com/ramsey/collection.git",
+ "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
- "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
+ "reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
"shasum": ""
},
"require": {
- "php": "^7"
+ "php": "^8.1"
},
"require-dev": {
- "phpunit/phpunit": "4.*|5.*",
- "vimeo/psalm": "^1"
- },
- "suggest": {
- "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
- },
- "type": "library",
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Paragon Initiative Enterprises",
- "email": "security@paragonie.com",
- "homepage": "https://paragonie.com"
- }
- ],
- "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
- "keywords": [
- "csprng",
- "polyfill",
- "pseudorandom",
- "random"
- ],
- "time": "2018-07-02T15:55:56+00:00"
- },
- {
- "name": "phpcollection/phpcollection",
- "version": "0.5.0",
- "source": {
- "type": "git",
- "url": "https://github.com/schmittjoh/php-collection.git",
- "reference": "f2bcff45c0da7c27991bbc1f90f47c4b7fb434a6"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/php-collection/zipball/f2bcff45c0da7c27991bbc1f90f47c4b7fb434a6",
- "reference": "f2bcff45c0da7c27991bbc1f90f47c4b7fb434a6",
- "shasum": ""
- },
- "require": {
- "phpoption/phpoption": "1.*"
+ "captainhook/plugin-composer": "^5.3",
+ "ergebnis/composer-normalize": "^2.28.3",
+ "fakerphp/faker": "^1.21",
+ "hamcrest/hamcrest-php": "^2.0",
+ "jangregor/phpstan-prophecy": "^1.0",
+ "mockery/mockery": "^1.5",
+ "php-parallel-lint/php-console-highlighter": "^1.0",
+ "php-parallel-lint/php-parallel-lint": "^1.3",
+ "phpcsstandards/phpcsutils": "^1.0.0-rc1",
+ "phpspec/prophecy-phpunit": "^2.0",
+ "phpstan/extension-installer": "^1.2",
+ "phpstan/phpstan": "^1.9",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^9.5",
+ "psalm/plugin-mockery": "^1.1",
+ "psalm/plugin-phpunit": "^0.18.4",
+ "ramsey/coding-standard": "^2.0.3",
+ "ramsey/conventional-commits": "^1.3",
+ "vimeo/psalm": "^5.4"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "0.4-dev"
+ "captainhook": {
+ "force-install": true
+ },
+ "ramsey/conventional-commits": {
+ "configFile": "conventional-commits.json"
}
},
"autoload": {
- "psr-0": {
- "PhpCollection": "src/"
+ "psr-4": {
+ "Ramsey\\Collection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "Apache2"
+ "MIT"
],
"authors": [
{
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
+ "name": "Ben Ramsey",
+ "email": "ben@benramsey.com",
+ "homepage": "https://benramsey.com"
}
],
- "description": "General-Purpose Collection Library for PHP",
+ "description": "A PHP library for representing and manipulating collections.",
"keywords": [
+ "array",
"collection",
- "list",
+ "hash",
"map",
- "sequence",
+ "queue",
"set"
],
- "time": "2015-05-17T12:39:23+00:00"
+ "support": {
+ "issues": "https://github.com/ramsey/collection/issues",
+ "source": "https://github.com/ramsey/collection/tree/2.0.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ramsey",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/ramsey/collection",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-31T21:50:55+00:00"
},
{
- "name": "phpoption/phpoption",
- "version": "1.5.0",
+ "name": "ramsey/uuid",
+ "version": "4.7.6",
"source": {
"type": "git",
- "url": "https://github.com/schmittjoh/php-option.git",
- "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed"
+ "url": "https://github.com/ramsey/uuid.git",
+ "reference": "91039bc1faa45ba123c4328958e620d382ec7088"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/94e644f7d2051a5f0fcf77d81605f152eecff0ed",
- "reference": "94e644f7d2051a5f0fcf77d81605f152eecff0ed",
+ "url": "https://api.github.com/repos/ramsey/uuid/zipball/91039bc1faa45ba123c4328958e620d382ec7088",
+ "reference": "91039bc1faa45ba123c4328958e620d382ec7088",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12",
+ "ext-json": "*",
+ "php": "^8.0",
+ "ramsey/collection": "^1.2 || ^2.0"
+ },
+ "replace": {
+ "rhumsaa/uuid": "self.version"
},
"require-dev": {
- "phpunit/phpunit": "4.7.*"
+ "captainhook/captainhook": "^5.10",
+ "captainhook/plugin-composer": "^5.3",
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "doctrine/annotations": "^1.8",
+ "ergebnis/composer-normalize": "^2.15",
+ "mockery/mockery": "^1.3",
+ "paragonie/random-lib": "^2",
+ "php-mock/php-mock": "^2.2",
+ "php-mock/php-mock-mockery": "^1.3",
+ "php-parallel-lint/php-parallel-lint": "^1.1",
+ "phpbench/phpbench": "^1.0",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^8.5 || ^9",
+ "ramsey/composer-repl": "^1.4",
+ "slevomat/coding-standard": "^8.4",
+ "squizlabs/php_codesniffer": "^3.5",
+ "vimeo/psalm": "^4.9"
+ },
+ "suggest": {
+ "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.",
+ "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.",
+ "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.",
+ "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
+ "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type."
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "1.3-dev"
+ "captainhook": {
+ "force-install": true
}
},
"autoload": {
- "psr-0": {
- "PhpOption\\": "src/"
+ "files": [
+ "src/functions.php"
+ ],
+ "psr-4": {
+ "Ramsey\\Uuid\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "Apache2"
+ "MIT"
],
- "authors": [
+ "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).",
+ "keywords": [
+ "guid",
+ "identifier",
+ "uuid"
+ ],
+ "support": {
+ "issues": "https://github.com/ramsey/uuid/issues",
+ "source": "https://github.com/ramsey/uuid/tree/4.7.6"
+ },
+ "funding": [
{
- "name": "Johannes M. Schmitt",
- "email": "schmittjoh@gmail.com"
+ "url": "https://github.com/ramsey",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid",
+ "type": "tidelift"
}
],
- "description": "Option Type for PHP",
- "keywords": [
- "language",
- "option",
- "php",
- "type"
- ],
- "time": "2015-07-25T16:39:46+00:00"
+ "time": "2024-04-27T21:32:50+00:00"
},
{
- "name": "psr/cache",
- "version": "1.0.1",
+ "name": "react/promise",
+ "version": "v2.11.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/cache.git",
- "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ "url": "https://github.com/reactphp/promise.git",
+ "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
- "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "url": "https://api.github.com/repos/reactphp/promise/zipball/1a8460931ea36dc5c76838fec5734d55c88c6831",
+ "reference": "1a8460931ea36dc5c76838fec5734d55c88c6831",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=5.4.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "require-dev": {
+ "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36"
},
+ "type": "library",
"autoload": {
+ "files": [
+ "src/functions_include.php"
+ ],
"psr-4": {
- "Psr\\Cache\\": "src/"
+ "React\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -1935,45 +2098,100 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Jan Sorgalla",
+ "email": "jsorgalla@gmail.com",
+ "homepage": "https://sorgalla.com/"
+ },
+ {
+ "name": "Christian LΓΌck",
+ "email": "christian@clue.engineering",
+ "homepage": "https://clue.engineering/"
+ },
+ {
+ "name": "Cees-Jan Kiewiet",
+ "email": "reactphp@ceesjankiewiet.nl",
+ "homepage": "https://wyrihaximus.net/"
+ },
+ {
+ "name": "Chris Boden",
+ "email": "cboden@gmail.com",
+ "homepage": "https://cboden.dev/"
}
],
- "description": "Common interface for caching libraries",
+ "description": "A lightweight implementation of CommonJS Promises/A for PHP",
"keywords": [
- "cache",
- "psr",
- "psr-6"
+ "promise",
+ "promises"
],
- "time": "2016-08-06T20:24:11+00:00"
+ "support": {
+ "issues": "https://github.com/reactphp/promise/issues",
+ "source": "https://github.com/reactphp/promise/tree/v2.11.0"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/reactphp",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2023-11-16T16:16:50+00:00"
},
{
- "name": "psr/container",
- "version": "1.0.0",
+ "name": "symfony/cache",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ "url": "https://github.com/symfony/cache.git",
+ "reference": "8ac37acee794372f9732fe8a61a8221f6762148e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "url": "https://api.github.com/repos/symfony/cache/zipball/8ac37acee794372f9732fe8a61a8221f6762148e",
+ "reference": "8ac37acee794372f9732fe8a61a8221f6762148e",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=8.2",
+ "psr/cache": "^2.0|^3.0",
+ "psr/log": "^1.1|^2|^3",
+ "symfony/cache-contracts": "^2.5|^3",
+ "symfony/deprecation-contracts": "^2.5|^3.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/var-exporter": "^6.4|^7.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "conflict": {
+ "doctrine/dbal": "<3.6",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/http-kernel": "<6.4",
+ "symfony/var-dumper": "<6.4"
},
+ "provide": {
+ "psr/cache-implementation": "2.0|3.0",
+ "psr/simple-cache-implementation": "1.0|2.0|3.0",
+ "symfony/cache-implementation": "1.1|2.0|3.0"
+ },
+ "require-dev": {
+ "cache/integration-tests": "dev-master",
+ "doctrine/dbal": "^3.6|^4",
+ "predis/predis": "^1.1|^2.0",
+ "psr/simple-cache": "^1.0|^2.0|^3.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/filesystem": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0"
+ },
+ "type": "library",
"autoload": {
"psr-4": {
- "Psr\\Container\\": "src/"
- }
+ "Symfony\\Component\\Cache\\": ""
+ },
+ "classmap": [
+ "Traits/ValueWrapper.php"
+ ],
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -1981,47 +2199,70 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common Container Interface (PHP FIG PSR-11)",
- "homepage": "https://github.com/php-fig/container",
+ "description": "Provides extended PSR-6, PSR-16 (and tags) implementations",
+ "homepage": "https://symfony.com",
"keywords": [
- "PSR-11",
- "container",
- "container-interface",
- "container-interop",
- "psr"
+ "caching",
+ "psr6"
],
- "time": "2017-02-14T16:28:37+00:00"
+ "support": {
+ "source": "https://github.com/symfony/cache/tree/v7.1.3"
+ },
+ "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-07-17T06:10:24+00:00"
},
{
- "name": "psr/http-message",
- "version": "1.0.1",
+ "name": "symfony/cache-contracts",
+ "version": "v3.5.0",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/http-message.git",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ "url": "https://github.com/symfony/cache-contracts.git",
+ "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
- "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/df6a1a44c890faded49a5fca33c2d5c5fd3c2197",
+ "reference": "df6a1a44c890faded49a5fca33c2d5c5fd3c2197",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=8.1",
+ "psr/cache": "^3.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-main": "3.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "Psr\\Http\\Message\\": "src/"
+ "Symfony\\Contracts\\Cache\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2030,49 +2271,76 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common interface for HTTP messages",
- "homepage": "https://github.com/php-fig/http-message",
+ "description": "Generic abstractions related to caching",
+ "homepage": "https://symfony.com",
"keywords": [
- "http",
- "http-message",
- "psr",
- "psr-7",
- "request",
- "response"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/cache-contracts/tree/v3.5.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": "2016-08-06T14:39:51+00:00"
+ "time": "2024-04-18T09:32:20+00:00"
},
{
- "name": "psr/log",
- "version": "1.1.0",
+ "name": "symfony/clock",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/log.git",
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
+ "url": "https://github.com/symfony/clock.git",
+ "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
- "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
+ "url": "https://api.github.com/repos/symfony/clock/zipball/3dfc8b084853586de51dd1441c6242c76a28cbe7",
+ "reference": "3dfc8b084853586de51dd1441c6242c76a28cbe7",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=8.2",
+ "psr/clock": "^1.0",
+ "symfony/polyfill-php83": "^1.28"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "provide": {
+ "psr/clock-implementation": "1.0"
},
+ "type": "library",
"autoload": {
+ "files": [
+ "Resources/now.php"
+ ],
"psr-4": {
- "Psr\\Log\\": "Psr/Log/"
- }
+ "Symfony\\Component\\Clock\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2080,46 +2348,79 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common interface for logging libraries",
- "homepage": "https://github.com/php-fig/log",
+ "description": "Decouples applications from the system clock",
+ "homepage": "https://symfony.com",
"keywords": [
- "log",
- "psr",
- "psr-3"
+ "clock",
+ "psr20",
+ "time"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/clock/tree/v7.1.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": "2018-11-20T15:27:04+00:00"
+ "time": "2024-05-31T14:57:53+00:00"
},
{
- "name": "psr/simple-cache",
- "version": "1.0.1",
+ "name": "symfony/config",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/php-fig/simple-cache.git",
- "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ "url": "https://github.com/symfony/config.git",
+ "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
- "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "url": "https://api.github.com/repos/symfony/config/zipball/2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2",
+ "reference": "2210fc99fa42a259eb6c89d1f724ce0c4d62d5d2",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/filesystem": "^7.1",
+ "symfony/polyfill-ctype": "~1.8"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
+ "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": {
- "Psr\\SimpleCache\\": "src/"
- }
+ "Symfony\\Component\\Config\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2127,45 +2428,85 @@
],
"authors": [
{
- "name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Common interfaces for simple caching",
- "keywords": [
- "cache",
- "caching",
- "psr",
- "psr-16",
- "simple-cache"
+ "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.1.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": "2017-10-23T01:57:42+00:00"
+ "time": "2024-05-31T14:57:53+00:00"
},
{
- "name": "ralouphie/getallheaders",
- "version": "2.0.5",
+ "name": "symfony/console",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/ralouphie/getallheaders.git",
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
+ "url": "https://github.com/symfony/console.git",
+ "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
- "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
+ "url": "https://api.github.com/repos/symfony/console/zipball/cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
+ "reference": "cb1dcb30ebc7005c29864ee78adb47b5fb7c3cd9",
"shasum": ""
},
"require": {
- "php": ">=5.3"
+ "php": ">=8.2",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/string": "^6.4|^7.0"
+ },
+ "conflict": {
+ "symfony/dependency-injection": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/process": "<6.4"
+ },
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
},
"require-dev": {
- "phpunit/phpunit": "~3.7.0",
- "satooshi/php-coveralls": ">=1.0"
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/lock": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0"
},
"type": "library",
"autoload": {
- "files": [
- "src/getallheaders.php"
+ "psr-4": {
+ "Symfony\\Component\\Console\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2174,66 +2515,85 @@
],
"authors": [
{
- "name": "Ralph Khattar",
- "email": "ralph.khattar@gmail.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Eases the creation of beautiful and testable command line interfaces",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command-line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v7.1.3"
+ },
+ "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"
}
],
- "description": "A polyfill for getallheaders.",
- "time": "2016-02-11T07:05:27+00:00"
+ "time": "2024-07-26T12:41:01+00:00"
},
{
- "name": "ramsey/uuid",
- "version": "3.8.0",
+ "name": "symfony/dependency-injection",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/ramsey/uuid.git",
- "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3"
+ "url": "https://github.com/symfony/dependency-injection.git",
+ "reference": "8126f0be4ff984e4db0140e60917900a53facb49"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/ramsey/uuid/zipball/d09ea80159c1929d75b3f9c60504d613aeb4a1e3",
- "reference": "d09ea80159c1929d75b3f9c60504d613aeb4a1e3",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/8126f0be4ff984e4db0140e60917900a53facb49",
+ "reference": "8126f0be4ff984e4db0140e60917900a53facb49",
"shasum": ""
},
"require": {
- "paragonie/random_compat": "^1.0|^2.0|9.99.99",
- "php": "^5.4 || ^7.0",
- "symfony/polyfill-ctype": "^1.8"
+ "php": ">=8.2",
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/service-contracts": "^3.5",
+ "symfony/var-exporter": "^6.4|^7.0"
},
- "replace": {
- "rhumsaa/uuid": "self.version"
+ "conflict": {
+ "ext-psr": "<1.1|>=2",
+ "symfony/config": "<6.4",
+ "symfony/finder": "<6.4",
+ "symfony/yaml": "<6.4"
},
- "require-dev": {
- "codeception/aspect-mock": "^1.0 | ~2.0.0",
- "doctrine/annotations": "~1.2.0",
- "goaop/framework": "1.0.0-alpha.2 | ^1.0 | ~2.1.0",
- "ircmaxell/random-lib": "^1.1",
- "jakub-onderka/php-parallel-lint": "^0.9.0",
- "mockery/mockery": "^0.9.9",
- "moontoast/math": "^1.1",
- "php-mock/php-mock-phpunit": "^0.3|^1.1",
- "phpunit/phpunit": "^4.7|^5.0|^6.5",
- "squizlabs/php_codesniffer": "^2.3"
+ "provide": {
+ "psr/container-implementation": "1.1|2.0",
+ "symfony/service-implementation": "1.1|2.0|3.0"
},
- "suggest": {
- "ext-ctype": "Provides support for PHP Ctype functions",
- "ext-libsodium": "Provides the PECL libsodium extension for use with the SodiumRandomGenerator",
- "ext-uuid": "Provides the PECL UUID extension for use with the PeclUuidTimeGenerator and PeclUuidRandomGenerator",
- "ircmaxell/random-lib": "Provides RandomLib for use with the RandomLibAdapter",
- "moontoast/math": "Provides support for converting UUID to 128-bit integer (in string form).",
- "ramsey/uuid-console": "A console application for generating UUIDs with ramsey/uuid",
- "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type."
+ "require-dev": {
+ "symfony/config": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
- }
- },
"autoload": {
"psr-4": {
- "Ramsey\\Uuid\\": "src/"
- }
+ "Symfony\\Component\\DependencyInjection\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2241,58 +2601,65 @@
],
"authors": [
{
- "name": "Marijn Huizendveld",
- "email": "marijn.huizendveld@gmail.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Allows you to standardize and centralize the way objects are constructed in your application",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/dependency-injection/tree/v7.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
},
{
- "name": "Thibaud Fabre",
- "email": "thibaud@aztech.io"
+ "url": "https://github.com/fabpot",
+ "type": "github"
},
{
- "name": "Ben Ramsey",
- "email": "ben@benramsey.com",
- "homepage": "https://benramsey.com"
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "description": "Formerly rhumsaa/uuid. A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).",
- "homepage": "https://github.com/ramsey/uuid",
- "keywords": [
- "guid",
- "identifier",
- "uuid"
- ],
- "time": "2018-07-19T23:38:55+00:00"
+ "time": "2024-07-26T07:35:39+00:00"
},
{
- "name": "swiftmailer/swiftmailer",
- "version": "v5.4.12",
+ "name": "symfony/deprecation-contracts",
+ "version": "v3.5.0",
"source": {
"type": "git",
- "url": "https://github.com/swiftmailer/swiftmailer.git",
- "reference": "181b89f18a90f8925ef805f950d47a7190e9b950"
+ "url": "https://github.com/symfony/deprecation-contracts.git",
+ "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/181b89f18a90f8925ef805f950d47a7190e9b950",
- "reference": "181b89f18a90f8925ef805f950d47a7190e9b950",
+ "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
+ "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
- },
- "require-dev": {
- "mockery/mockery": "~0.9.1",
- "symfony/phpunit-bridge": "~3.2"
+ "php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "5.4-dev"
+ "dev-main": "3.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
- "lib/swift_required.php"
+ "function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2301,72 +2668,64 @@
],
"authors": [
{
- "name": "Chris Corbyn"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Swiftmailer, free feature-rich PHP mailer",
- "homepage": "https://swiftmailer.symfony.com",
- "keywords": [
- "email",
- "mail",
- "mailer"
+ "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.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": "2018-07-31T09:26:32+00:00"
+ "time": "2024-04-18T09:32:20+00:00"
},
{
- "name": "symfony/cache",
- "version": "v4.2.5",
+ "name": "symfony/dotenv",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/cache.git",
- "reference": "3172c1e81fab8a21b35732ad8545e09877bb73d9"
+ "url": "https://github.com/symfony/dotenv.git",
+ "reference": "a26be30fd61678dab694a18a85084cea7673bbf3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/cache/zipball/3172c1e81fab8a21b35732ad8545e09877bb73d9",
- "reference": "3172c1e81fab8a21b35732ad8545e09877bb73d9",
+ "url": "https://api.github.com/repos/symfony/dotenv/zipball/a26be30fd61678dab694a18a85084cea7673bbf3",
+ "reference": "a26be30fd61678dab694a18a85084cea7673bbf3",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "psr/cache": "~1.0",
- "psr/log": "~1.0",
- "psr/simple-cache": "^1.0",
- "symfony/contracts": "^1.0",
- "symfony/var-exporter": "^4.2"
+ "php": ">=8.2"
},
"conflict": {
- "doctrine/dbal": "<2.5",
- "symfony/dependency-injection": "<3.4",
- "symfony/var-dumper": "<3.4"
- },
- "provide": {
- "psr/cache-implementation": "1.0",
- "psr/simple-cache-implementation": "1.0",
- "symfony/cache-contracts-implementation": "1.0"
+ "symfony/console": "<6.4",
+ "symfony/process": "<6.4"
},
"require-dev": {
- "cache/integration-tests": "dev-master",
- "doctrine/cache": "~1.6",
- "doctrine/dbal": "~2.5",
- "predis/predis": "~1.1",
- "symfony/config": "~4.2",
- "symfony/dependency-injection": "~3.4|~4.1",
- "symfony/var-dumper": "^4.1.1"
+ "symfony/console": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Cache\\": ""
+ "Symfony\\Component\\Dotenv\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2378,62 +2737,75 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Cache component with PSR-6, PSR-16, and tags",
+ "description": "Registers environment variables from a .env file",
"homepage": "https://symfony.com",
"keywords": [
- "caching",
- "psr6"
+ "dotenv",
+ "env",
+ "environment"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/dotenv/tree/v7.1.3"
+ },
+ "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": "2019-04-01T07:32:59+00:00"
+ "time": "2024-07-09T19:36:07+00:00"
},
{
- "name": "symfony/config",
- "version": "v4.2.5",
+ "name": "symfony/error-handler",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/config.git",
- "reference": "0e745ead307d5dcd4e163e94a47ec04b1428943f"
+ "url": "https://github.com/symfony/error-handler.git",
+ "reference": "432bb369952795c61ca1def65e078c4a80dad13c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/0e745ead307d5dcd4e163e94a47ec04b1428943f",
- "reference": "0e745ead307d5dcd4e163e94a47ec04b1428943f",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/432bb369952795c61ca1def65e078c4a80dad13c",
+ "reference": "432bb369952795c61ca1def65e078c4a80dad13c",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/filesystem": "~3.4|~4.0",
- "symfony/polyfill-ctype": "~1.8"
+ "php": ">=8.2",
+ "psr/log": "^1|^2|^3",
+ "symfony/var-dumper": "^6.4|^7.0"
},
"conflict": {
- "symfony/finder": "<3.4"
+ "symfony/deprecation-contracts": "<2.5",
+ "symfony/http-kernel": "<6.4"
},
"require-dev": {
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/event-dispatcher": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/yaml": "To use the yaml reference dumper"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/serializer": "^6.4|^7.0"
},
+ "bin": [
+ "Resources/bin/patch-type-declarations"
+ ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Config\\": ""
+ "Symfony\\Component\\ErrorHandler\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2453,59 +2825,67 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Config Component",
+ "description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com",
- "time": "2019-04-01T14:03:25+00:00"
+ "support": {
+ "source": "https://github.com/symfony/error-handler/tree/v7.1.3"
+ },
+ "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-07-26T13:02:51+00:00"
},
{
- "name": "symfony/console",
- "version": "v4.2.5",
+ "name": "symfony/event-dispatcher",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/console.git",
- "reference": "24206aff3efe6962593297e57ef697ebb220e384"
+ "url": "https://github.com/symfony/event-dispatcher.git",
+ "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/24206aff3efe6962593297e57ef697ebb220e384",
- "reference": "24206aff3efe6962593297e57ef697ebb220e384",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
+ "reference": "9fa7f7a21beb22a39a8f3f28618b29e50d7a55a7",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0",
- "symfony/polyfill-mbstring": "~1.0"
+ "php": ">=8.2",
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
},
"conflict": {
- "symfony/dependency-injection": "<3.4",
- "symfony/process": "<3.3"
+ "symfony/dependency-injection": "<6.4",
+ "symfony/service-contracts": "<2.5"
},
"provide": {
- "psr/log-implementation": "1.0"
+ "psr/event-dispatcher-implementation": "1.0",
+ "symfony/event-dispatcher-implementation": "2.0|3.0"
},
"require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/event-dispatcher": "~3.4|~4.0",
- "symfony/lock": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0"
- },
- "suggest": {
- "psr/log": "For using the console logger",
- "symfony/event-dispatcher": "",
- "symfony/lock": "",
- "symfony/process": ""
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Console\\": ""
+ "Symfony\\Component\\EventDispatcher\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2517,58 +2897,140 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.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-05-31T14:57:53+00:00"
+ },
+ {
+ "name": "symfony/event-dispatcher-contracts",
+ "version": "v3.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/event-dispatcher-contracts.git",
+ "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50",
+ "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=8.1",
+ "psr/event-dispatcher": "^1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\EventDispatcher\\": ""
+ }
+ },
+ "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 Console Component",
+ "description": "Generic abstractions related to dispatching event",
"homepage": "https://symfony.com",
- "time": "2019-04-01T07:32:59+00:00"
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.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-04-18T09:32:20+00:00"
},
{
- "name": "symfony/contracts",
- "version": "v1.0.2",
+ "name": "symfony/filesystem",
+ "version": "v7.1.2",
"source": {
"type": "git",
- "url": "https://github.com/symfony/contracts.git",
- "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf"
+ "url": "https://github.com/symfony/filesystem.git",
+ "reference": "92a91985250c251de9b947a14bb2c9390b1a562c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/contracts/zipball/1aa7ab2429c3d594dd70689604b5cf7421254cdf",
- "reference": "1aa7ab2429c3d594dd70689604b5cf7421254cdf",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/92a91985250c251de9b947a14bb2c9390b1a562c",
+ "reference": "92a91985250c251de9b947a14bb2c9390b1a562c",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "php": ">=8.2",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.8"
},
"require-dev": {
- "psr/cache": "^1.0",
- "psr/container": "^1.0"
- },
- "suggest": {
- "psr/cache": "When using the Cache contracts",
- "psr/container": "When using the Service contracts",
- "symfony/cache-contracts-implementation": "",
- "symfony/service-contracts-implementation": "",
- "symfony/translation-contracts-implementation": ""
+ "symfony/process": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Contracts\\": ""
+ "Symfony\\Component\\Filesystem\\": ""
},
"exclude-from-classmap": [
- "**/Tests/"
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -2577,59 +3039,59 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "A set of abstractions extracted out of the Symfony components",
+ "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
- "keywords": [
- "abstractions",
- "contracts",
- "decoupling",
- "interfaces",
- "interoperability",
- "standards"
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v7.1.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": "2018-12-05T08:06:11+00:00"
+ "time": "2024-06-28T10:03:55+00:00"
},
{
- "name": "symfony/debug",
- "version": "v4.2.5",
+ "name": "symfony/finder",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/debug.git",
- "reference": "43ce8ab34c734dcc8a4af576cb86711daab964c5"
+ "url": "https://github.com/symfony/finder.git",
+ "reference": "717c6329886f32dc65e27461f80f2a465412fdca"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/43ce8ab34c734dcc8a4af576cb86711daab964c5",
- "reference": "43ce8ab34c734dcc8a4af576cb86711daab964c5",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/717c6329886f32dc65e27461f80f2a465412fdca",
+ "reference": "717c6329886f32dc65e27461f80f2a465412fdca",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "psr/log": "~1.0"
- },
- "conflict": {
- "symfony/http-kernel": "<3.4"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/http-kernel": "~3.4|~4.0"
+ "symfony/filesystem": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Debug\\": ""
+ "Symfony\\Component\\Finder\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2649,60 +3111,134 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Debug Component",
+ "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
- "time": "2019-03-10T17:09:50+00:00"
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v7.1.3"
+ },
+ "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-07-24T07:08:44+00:00"
},
{
- "name": "symfony/dependency-injection",
- "version": "v4.2.5",
+ "name": "symfony/framework-bundle",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/dependency-injection.git",
- "reference": "1806e43ff6bff57398d33b326cd753a12d9f434f"
+ "url": "https://github.com/symfony/framework-bundle.git",
+ "reference": "a32ec544bd501eb4619eb977860ad3076ee55061"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/1806e43ff6bff57398d33b326cd753a12d9f434f",
- "reference": "1806e43ff6bff57398d33b326cd753a12d9f434f",
+ "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/a32ec544bd501eb4619eb977860ad3076ee55061",
+ "reference": "a32ec544bd501eb4619eb977860ad3076ee55061",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "psr/container": "^1.0",
- "symfony/contracts": "^1.0"
+ "composer-runtime-api": ">=2.1",
+ "ext-xml": "*",
+ "php": ">=8.2",
+ "symfony/cache": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^7.1",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/filesystem": "^7.1",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/routing": "^6.4|^7.0"
},
"conflict": {
- "symfony/config": "<4.2",
- "symfony/finder": "<3.4",
- "symfony/proxy-manager-bridge": "<3.4",
- "symfony/yaml": "<3.4"
- },
- "provide": {
- "psr/container-implementation": "1.0",
- "symfony/service-contracts-implementation": "1.0"
+ "doctrine/persistence": "<1.3",
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/asset": "<6.4",
+ "symfony/asset-mapper": "<6.4",
+ "symfony/clock": "<6.4",
+ "symfony/console": "<6.4",
+ "symfony/dom-crawler": "<6.4",
+ "symfony/dotenv": "<6.4",
+ "symfony/form": "<6.4",
+ "symfony/http-client": "<6.4",
+ "symfony/lock": "<6.4",
+ "symfony/mailer": "<6.4",
+ "symfony/messenger": "<6.4",
+ "symfony/mime": "<6.4",
+ "symfony/property-access": "<6.4",
+ "symfony/property-info": "<6.4",
+ "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4",
+ "symfony/security-core": "<6.4",
+ "symfony/security-csrf": "<6.4",
+ "symfony/serializer": "<6.4",
+ "symfony/stopwatch": "<6.4",
+ "symfony/translation": "<6.4",
+ "symfony/twig-bridge": "<6.4",
+ "symfony/twig-bundle": "<6.4",
+ "symfony/validator": "<6.4",
+ "symfony/web-profiler-bundle": "<6.4",
+ "symfony/workflow": "<6.4"
},
"require-dev": {
- "symfony/config": "~4.2",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/config": "",
- "symfony/expression-language": "For using expressions in service container configuration",
- "symfony/finder": "For using double-star glob patterns or when GLOB_BRACE portability is required",
- "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them",
- "symfony/yaml": ""
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "doctrine/persistence": "^1.3|^2|^3",
+ "dragonmantank/cron-expression": "^3.1",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "seld/jsonlint": "^1.10",
+ "symfony/asset": "^6.4|^7.0",
+ "symfony/asset-mapper": "^6.4|^7.0",
+ "symfony/browser-kit": "^6.4|^7.0",
+ "symfony/clock": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/css-selector": "^6.4|^7.0",
+ "symfony/dom-crawler": "^6.4|^7.0",
+ "symfony/dotenv": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/form": "^6.4|^7.0",
+ "symfony/html-sanitizer": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/lock": "^6.4|^7.0",
+ "symfony/mailer": "^6.4|^7.0",
+ "symfony/messenger": "^6.4|^7.0",
+ "symfony/mime": "^6.4|^7.0",
+ "symfony/notifier": "^6.4|^7.0",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/property-info": "^6.4|^7.0",
+ "symfony/rate-limiter": "^6.4|^7.0",
+ "symfony/scheduler": "^6.4.4|^7.0.4",
+ "symfony/security-bundle": "^6.4|^7.0",
+ "symfony/semaphore": "^6.4|^7.0",
+ "symfony/serializer": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/string": "^6.4|^7.0",
+ "symfony/translation": "^6.4|^7.0",
+ "symfony/twig-bundle": "^6.4|^7.0",
+ "symfony/type-info": "^7.1",
+ "symfony/uid": "^6.4|^7.0",
+ "symfony/validator": "^6.4|^7.0",
+ "symfony/web-link": "^6.4|^7.0",
+ "symfony/workflow": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0",
+ "twig/twig": "^3.0.4"
},
+ "type": "symfony-bundle",
"autoload": {
"psr-4": {
- "Symfony\\Component\\DependencyInjection\\": ""
+ "Symfony\\Bundle\\FrameworkBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2722,39 +3258,64 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony DependencyInjection Component",
+ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework",
"homepage": "https://symfony.com",
- "time": "2019-03-30T15:58:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/framework-bundle/tree/v7.1.3"
+ },
+ "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-07-26T13:24:34+00:00"
},
{
- "name": "symfony/dotenv",
- "version": "v4.2.5",
+ "name": "symfony/http-foundation",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/dotenv.git",
- "reference": "b541d63b83532be55a020db8ed2e50598385a583"
+ "url": "https://github.com/symfony/http-foundation.git",
+ "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dotenv/zipball/b541d63b83532be55a020db8ed2e50598385a583",
- "reference": "b541d63b83532be55a020db8ed2e50598385a583",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
+ "reference": "f602d5c17d1fa02f8019ace2687d9d136b7f4a1a",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "php": ">=8.2",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php83": "^1.27"
+ },
+ "conflict": {
+ "doctrine/dbal": "<3.6",
+ "symfony/cache": "<6.4"
},
"require-dev": {
- "symfony/process": "~3.4|~4.0"
+ "doctrine/dbal": "^3.6|^4",
+ "predis/predis": "^1.1|^2.0",
+ "symfony/cache": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/mime": "^6.4|^7.0",
+ "symfony/rate-limiter": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\Dotenv\\": ""
+ "Symfony\\Component\\HttpFoundation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2774,56 +3335,101 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Registers environment variables from a .env file",
+ "description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
- "keywords": [
- "dotenv",
- "env",
- "environment"
+ "support": {
+ "source": "https://github.com/symfony/http-foundation/tree/v7.1.3"
+ },
+ "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": "2019-04-01T07:32:59+00:00"
+ "time": "2024-07-26T12:41:01+00:00"
},
{
- "name": "symfony/event-dispatcher",
- "version": "v4.2.5",
+ "name": "symfony/http-kernel",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544"
+ "url": "https://github.com/symfony/http-kernel.git",
+ "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544",
- "reference": "ca5af306fbc37f3cf597e91bc9cfa0c7d3f33544",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/db9702f3a04cc471ec8c70e881825db26ac5f186",
+ "reference": "db9702f3a04cc471ec8c70e881825db26ac5f186",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0"
+ "php": ">=8.2",
+ "psr/log": "^1|^2|^3",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/polyfill-ctype": "^1.8"
},
"conflict": {
- "symfony/dependency-injection": "<3.4"
+ "symfony/browser-kit": "<6.4",
+ "symfony/cache": "<6.4",
+ "symfony/config": "<6.4",
+ "symfony/console": "<6.4",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/doctrine-bridge": "<6.4",
+ "symfony/form": "<6.4",
+ "symfony/http-client": "<6.4",
+ "symfony/http-client-contracts": "<2.5",
+ "symfony/mailer": "<6.4",
+ "symfony/messenger": "<6.4",
+ "symfony/translation": "<6.4",
+ "symfony/translation-contracts": "<2.5",
+ "symfony/twig-bridge": "<6.4",
+ "symfony/validator": "<6.4",
+ "symfony/var-dumper": "<6.4",
+ "twig/twig": "<3.0.4"
},
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/stopwatch": "~3.4|~4.0"
+ "provide": {
+ "psr/log-implementation": "1.0|2.0|3.0"
},
- "suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
+ "require-dev": {
+ "psr/cache": "^1.0|^2.0|^3.0",
+ "symfony/browser-kit": "^6.4|^7.0",
+ "symfony/clock": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/css-selector": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/dom-crawler": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/http-client-contracts": "^2.5|^3",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/property-access": "^7.1",
+ "symfony/routing": "^6.4|^7.0",
+ "symfony/serializer": "^7.1",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/translation": "^6.4|^7.0",
+ "symfony/translation-contracts": "^2.5|^3",
+ "symfony/uid": "^6.4|^7.0",
+ "symfony/validator": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0",
+ "symfony/var-exporter": "^6.4|^7.0",
+ "twig/twig": "^3.0.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\EventDispatcher\\": ""
+ "Symfony\\Component\\HttpKernel\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2843,37 +3449,73 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony EventDispatcher Component",
+ "description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
- "time": "2019-03-30T15:58:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/http-kernel/tree/v7.1.3"
+ },
+ "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-07-26T14:58:15+00:00"
},
{
- "name": "symfony/filesystem",
- "version": "v4.2.5",
+ "name": "symfony/messenger",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/filesystem.git",
- "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601"
+ "url": "https://github.com/symfony/messenger.git",
+ "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/e16b9e471703b2c60b95f14d31c1239f68f11601",
- "reference": "e16b9e471703b2c60b95f14d31c1239f68f11601",
+ "url": "https://api.github.com/repos/symfony/messenger/zipball/604e182a7758ceea35921a8ad5dd492a6e13bae4",
+ "reference": "604e182a7758ceea35921a8ad5dd492a6e13bae4",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/polyfill-ctype": "~1.8"
+ "php": ">=8.2",
+ "psr/log": "^1|^2|^3",
+ "symfony/clock": "^6.4|^7.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "conflict": {
+ "symfony/console": "<6.4",
+ "symfony/event-dispatcher": "<6.4",
+ "symfony/event-dispatcher-contracts": "<2.5",
+ "symfony/framework-bundle": "<6.4",
+ "symfony/http-kernel": "<6.4",
+ "symfony/serializer": "<6.4"
+ },
+ "require-dev": {
+ "psr/cache": "^1.0|^2.0|^3.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/property-access": "^6.4|^7.0",
+ "symfony/rate-limiter": "^6.4|^7.0",
+ "symfony/routing": "^6.4|^7.0",
+ "symfony/serializer": "^6.4|^7.0",
+ "symfony/service-contracts": "^2.5|^3",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/validator": "^6.4|^7.0"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Filesystem\\": ""
+ "Symfony\\Component\\Messenger\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -2885,48 +3527,72 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Samuel Roze",
+ "email": "samuel.roze@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Filesystem Component",
+ "description": "Helps applications send and receive messages to/from other applications or via message queues",
"homepage": "https://symfony.com",
- "time": "2019-02-07T11:40:08+00:00"
+ "support": {
+ "source": "https://github.com/symfony/messenger/tree/v7.1.3"
+ },
+ "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-07-09T19:36:07+00:00"
},
{
- "name": "symfony/finder",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-ctype",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/finder.git",
- "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a"
+ "url": "https://github.com/symfony/polyfill-ctype.git",
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/267b7002c1b70ea80db0833c3afe05f0fbde580a",
- "reference": "267b7002c1b70ea80db0833c3afe05f0fbde580a",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
+ "reference": "0424dff1c58f028c451efff2045f5d92410bd540",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-ctype": "*"
+ },
+ "suggest": {
+ "ext-ctype": "For best performance"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Finder\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Polyfill\\Ctype\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -2934,118 +3600,75 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Gert de Pagter",
+ "email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Finder Component",
+ "description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
- "time": "2019-02-23T15:42:05+00:00"
+ "keywords": [
+ "compatibility",
+ "ctype",
+ "polyfill",
+ "portable"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.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-05-31T15:07:36+00:00"
},
{
- "name": "symfony/framework-bundle",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-intl-grapheme",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/framework-bundle.git",
- "reference": "2cd66337a7effcdaaa23b4ac4541a5cffbbb7a61"
+ "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+ "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/2cd66337a7effcdaaa23b4ac4541a5cffbbb7a61",
- "reference": "2cd66337a7effcdaaa23b4ac4541a5cffbbb7a61",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a",
+ "reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a",
"shasum": ""
},
"require": {
- "ext-xml": "*",
- "php": "^7.1.3",
- "symfony/cache": "~4.2",
- "symfony/config": "~4.2",
- "symfony/contracts": "^1.0.2",
- "symfony/dependency-injection": "^4.2.5",
- "symfony/event-dispatcher": "^4.1",
- "symfony/filesystem": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/http-foundation": "^4.2.5",
- "symfony/http-kernel": "^4.2",
- "symfony/polyfill-mbstring": "~1.0",
- "symfony/routing": "^4.1"
- },
- "conflict": {
- "phpdocumentor/reflection-docblock": "<3.0",
- "phpdocumentor/type-resolver": "<0.2.1",
- "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
- "symfony/asset": "<3.4",
- "symfony/console": "<3.4",
- "symfony/dotenv": "<4.2",
- "symfony/form": "<4.2",
- "symfony/messenger": "<4.2",
- "symfony/property-info": "<3.4",
- "symfony/serializer": "<4.2",
- "symfony/stopwatch": "<3.4",
- "symfony/translation": "<4.2",
- "symfony/twig-bridge": "<4.1.1",
- "symfony/validator": "<4.1",
- "symfony/workflow": "<4.1"
- },
- "require-dev": {
- "doctrine/annotations": "~1.0",
- "doctrine/cache": "~1.0",
- "fig/link-util": "^1.0",
- "phpdocumentor/reflection-docblock": "^3.0|^4.0",
- "symfony/asset": "~3.4|~4.0",
- "symfony/browser-kit": "~3.4|~4.0",
- "symfony/console": "~3.4|~4.0",
- "symfony/css-selector": "~3.4|~4.0",
- "symfony/dom-crawler": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/form": "^4.2.3",
- "symfony/lock": "~3.4|~4.0",
- "symfony/messenger": "^4.2",
- "symfony/polyfill-intl-icu": "~1.0",
- "symfony/process": "~3.4|~4.0",
- "symfony/property-info": "~3.4|~4.0",
- "symfony/security": "~3.4|~4.0",
- "symfony/security-core": "~3.4|~4.0",
- "symfony/security-csrf": "~3.4|~4.0",
- "symfony/serializer": "^4.2",
- "symfony/stopwatch": "~3.4|~4.0",
- "symfony/templating": "~3.4|~4.0",
- "symfony/translation": "~4.2",
- "symfony/validator": "^4.1",
- "symfony/var-dumper": "~3.4|~4.0",
- "symfony/web-link": "~3.4|~4.0",
- "symfony/workflow": "^4.1",
- "symfony/yaml": "~3.4|~4.0",
- "twig/twig": "~1.34|~2.4"
+ "php": ">=7.1"
},
"suggest": {
- "ext-apcu": "For best performance of the system caches",
- "symfony/console": "For using the console commands",
- "symfony/form": "For using forms",
- "symfony/property-info": "For using the property_info service",
- "symfony/serializer": "For using the serializer service",
- "symfony/validator": "For using validation",
- "symfony/web-link": "For using web links, features such as preloading, prefetching or prerendering",
- "symfony/yaml": "For using the debug:config and lint:yaml commands"
+ "ext-intl": "For best performance"
},
- "type": "symfony-bundle",
+ "type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Bundle\\FrameworkBundle\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3053,52 +3676,79 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony FrameworkBundle",
+ "description": "Symfony polyfill for intl's grapheme_* functions",
"homepage": "https://symfony.com",
- "time": "2019-04-01T07:32:59+00:00"
+ "keywords": [
+ "compatibility",
+ "grapheme",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.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-05-31T15:07:36+00:00"
},
{
- "name": "symfony/http-foundation",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-foundation.git",
- "reference": "5b7ab6beaa5b053b8d3c9b13367ada9b292e12e1"
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/5b7ab6beaa5b053b8d3c9b13367ada9b292e12e1",
- "reference": "5b7ab6beaa5b053b8d3c9b13367ada9b292e12e1",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
+ "reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/polyfill-mbstring": "~1.1"
+ "php": ">=7.1"
},
- "require-dev": {
- "predis/predis": "~1.0",
- "symfony/expression-language": "~3.4|~4.0"
+ "suggest": {
+ "ext-intl": "For best performance"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\HttpFoundation\\": ""
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3107,88 +3757,80 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony HttpFoundation Component",
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
"homepage": "https://symfony.com",
- "time": "2019-03-30T15:58:42+00:00"
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.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-05-31T15:07:36+00:00"
},
{
- "name": "symfony/http-kernel",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/http-kernel.git",
- "reference": "e8b940bbeebf0f96789b5d17d9d77f8b2613960b"
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e8b940bbeebf0f96789b5d17d9d77f8b2613960b",
- "reference": "e8b940bbeebf0f96789b5d17d9d77f8b2613960b",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
+ "reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "psr/log": "~1.0",
- "symfony/contracts": "^1.0.2",
- "symfony/debug": "~3.4|~4.0",
- "symfony/event-dispatcher": "~4.1",
- "symfony/http-foundation": "^4.1.1",
- "symfony/polyfill-ctype": "~1.8"
- },
- "conflict": {
- "symfony/config": "<3.4",
- "symfony/dependency-injection": "<4.2",
- "symfony/translation": "<4.2",
- "symfony/var-dumper": "<4.1.1",
- "twig/twig": "<1.34|<2.4,>=2"
+ "php": ">=7.1"
},
"provide": {
- "psr/log-implementation": "1.0"
- },
- "require-dev": {
- "psr/cache": "~1.0",
- "symfony/browser-kit": "~3.4|~4.0",
- "symfony/config": "~3.4|~4.0",
- "symfony/console": "~3.4|~4.0",
- "symfony/css-selector": "~3.4|~4.0",
- "symfony/dependency-injection": "^4.2",
- "symfony/dom-crawler": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0",
- "symfony/routing": "~3.4|~4.0",
- "symfony/stopwatch": "~3.4|~4.0",
- "symfony/templating": "~3.4|~4.0",
- "symfony/translation": "~4.2",
- "symfony/var-dumper": "^4.1.1"
+ "ext-mbstring": "*"
},
"suggest": {
- "symfony/browser-kit": "",
- "symfony/config": "",
- "symfony/console": "",
- "symfony/dependency-injection": "",
- "symfony/var-dumper": ""
+ "ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\HttpKernel\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3196,130 +3838,148 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony HttpKernel Component",
+ "description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
- "time": "2019-04-02T19:03:51+00:00"
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.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-06-19T12:30:46+00:00"
},
{
- "name": "symfony/messenger",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-php72",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/messenger.git",
- "reference": "a84da6594ea9935a06546fb0e3ff6607b70b2932"
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "10112722600777e02d2745716b70c5db4ca70442"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/messenger/zipball/a84da6594ea9935a06546fb0e3ff6607b70b2932",
- "reference": "a84da6594ea9935a06546fb0e3ff6607b70b2932",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442",
+ "reference": "10112722600777e02d2745716b70c5db4ca70442",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/console": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4.19|^4.1.8",
- "symfony/http-kernel": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0",
- "symfony/property-access": "~3.4|~4.0",
- "symfony/serializer": "~3.4|~4.0",
- "symfony/stopwatch": "~3.4|~4.0",
- "symfony/validator": "~3.4|~4.0",
- "symfony/var-dumper": "~3.4|~4.0"
- },
- "suggest": {
- "enqueue/messenger-adapter": "For using the php-enqueue library as a transport."
+ "php": ">=7.1"
},
"type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Messenger\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Symfony\\Polyfill\\Php72\\": ""
+ }
},
"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 backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.30.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
},
{
- "name": "Samuel Roze",
- "email": "samuel.roze@gmail.com"
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "description": "Symfony Messenger Component",
- "homepage": "https://symfony.com",
- "time": "2019-03-12T17:23:22+00:00"
+ "time": "2024-06-19T12:30:46+00:00"
},
{
- "name": "symfony/monolog-bridge",
- "version": "v4.2.5",
+ "name": "symfony/polyfill-php80",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/monolog-bridge.git",
- "reference": "472c74b350542e51373dcb159c0dcc234dc74e38"
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/472c74b350542e51373dcb159c0dcc234dc74e38",
- "reference": "472c74b350542e51373dcb159c0dcc234dc74e38",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
+ "reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
"shasum": ""
},
"require": {
- "monolog/monolog": "~1.19",
- "php": "^7.1.3",
- "symfony/contracts": "^1.0",
- "symfony/http-kernel": "~3.4|~4.0"
- },
- "conflict": {
- "symfony/console": "<3.4",
- "symfony/http-foundation": "<3.4"
- },
- "require-dev": {
- "symfony/console": "~3.4|~4.0",
- "symfony/event-dispatcher": "~3.4|~4.0",
- "symfony/security-core": "~3.4|~4.0",
- "symfony/var-dumper": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/console": "For the possibility to show log messages in console commands depending on verbosity settings.",
- "symfony/event-dispatcher": "Needed when using log messages in console commands.",
- "symfony/http-kernel": "For using the debugging handlers together with the response life cycle of the HTTP kernel.",
- "symfony/var-dumper": "For using the debugging handlers like the console handler or the log server handler."
+ "php": ">=7.1"
},
- "type": "symfony-bridge",
+ "type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Bridge\\Monolog\\": ""
+ "Symfony\\Polyfill\\Php80\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3328,57 +3988,78 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Monolog Bridge",
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
- "time": "2019-02-28T17:49:31+00:00"
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.30.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-05-31T15:07:36+00:00"
},
{
- "name": "symfony/monolog-bundle",
- "version": "v3.3.1",
+ "name": "symfony/polyfill-php83",
+ "version": "v1.30.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/monolog-bundle.git",
- "reference": "572e143afc03419a75ab002c80a2fd99299195ff"
+ "url": "https://github.com/symfony/polyfill-php83.git",
+ "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/572e143afc03419a75ab002c80a2fd99299195ff",
- "reference": "572e143afc03419a75ab002c80a2fd99299195ff",
+ "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
+ "reference": "dbdcdf1a4dcc2743591f1079d0c35ab1e2dcbbc9",
"shasum": ""
},
"require": {
- "monolog/monolog": "~1.22",
- "php": ">=5.6",
- "symfony/config": "~2.7|~3.3|~4.0",
- "symfony/dependency-injection": "~2.7|~3.4.10|^4.0.10",
- "symfony/http-kernel": "~2.7|~3.3|~4.0",
- "symfony/monolog-bridge": "~2.7|~3.3|~4.0"
- },
- "require-dev": {
- "symfony/console": "~2.7|~3.3|~4.0",
- "symfony/phpunit-bridge": "^3.3|^4.0",
- "symfony/yaml": "~2.7|~3.3|~4.0"
+ "php": ">=7.1"
},
- "type": "symfony-bundle",
+ "type": "library",
"extra": {
- "branch-alias": {
- "dev-master": "3.x-dev"
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
"psr-4": {
- "Symfony\\Bundle\\MonologBundle\\": ""
+ "Symfony\\Polyfill\\Php83\\": ""
},
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3387,54 +4068,79 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony MonologBundle",
- "homepage": "http://symfony.com",
+ "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
"keywords": [
- "log",
- "logging"
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php83/tree/v1.30.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": "2018-11-04T09:58:13+00:00"
+ "time": "2024-06-19T12:35:24+00:00"
},
{
- "name": "symfony/polyfill-ctype",
- "version": "v1.11.0",
+ "name": "symfony/routing",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "82ebae02209c21113908c229e9883c419720738a"
+ "url": "https://github.com/symfony/routing.git",
+ "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
- "reference": "82ebae02209c21113908c229e9883c419720738a",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
+ "reference": "8a908a3f22d5a1b5d297578c2ceb41b02fa916d0",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3"
},
- "suggest": {
- "ext-ctype": "For best performance"
+ "conflict": {
+ "symfony/config": "<6.4",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/yaml": "<6.4"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.11-dev"
- }
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Ctype\\": ""
+ "Symfony\\Component\\Routing\\": ""
},
- "files": [
- "bootstrap.php"
+ "exclude-from-classmap": [
+ "/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3443,56 +4149,79 @@
],
"authors": [
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
- "name": "Gert de Pagter",
- "email": "backendtea@gmail.com"
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony polyfill for ctype functions",
+ "description": "Maps an HTTP request to a set of configuration variables",
"homepage": "https://symfony.com",
"keywords": [
- "compatibility",
- "ctype",
- "polyfill",
- "portable"
+ "router",
+ "routing",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/routing/tree/v7.1.3"
+ },
+ "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": "2019-02-06T07:57:58+00:00"
+ "time": "2024-07-17T06:10:24+00:00"
},
{
- "name": "symfony/polyfill-mbstring",
- "version": "v1.11.0",
+ "name": "symfony/service-contracts",
+ "version": "v3.5.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "fe5e94c604826c35a32fa832f35bd036b6799609"
+ "url": "https://github.com/symfony/service-contracts.git",
+ "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fe5e94c604826c35a32fa832f35bd036b6799609",
- "reference": "fe5e94c604826c35a32fa832f35bd036b6799609",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
+ "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=8.1",
+ "psr/container": "^1.1|^2.0",
+ "symfony/deprecation-contracts": "^2.5|^3"
},
- "suggest": {
- "ext-mbstring": "For best performance"
+ "conflict": {
+ "ext-psr": "<1.1|>=2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.11-dev"
+ "dev-main": "3.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Polyfill\\Mbstring\\": ""
+ "Symfony\\Contracts\\Service\\": ""
},
- "files": [
- "bootstrap.php"
+ "exclude-from-classmap": [
+ "/Test/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3501,51 +4230,82 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to writing services",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/v3.5.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
}
],
- "description": "Symfony polyfill for the Mbstring extension",
- "homepage": "https://symfony.com",
- "keywords": [
- "compatibility",
- "mbstring",
- "polyfill",
- "portable",
- "shim"
- ],
- "time": "2019-02-06T07:57:58+00:00"
+ "time": "2024-04-18T09:32:20+00:00"
},
{
- "name": "symfony/process",
- "version": "v4.2.5",
+ "name": "symfony/string",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/process.git",
- "reference": "1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6"
+ "url": "https://github.com/symfony/string.git",
+ "reference": "ea272a882be7f20cad58d5d78c215001617b7f07"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6",
- "reference": "1e6cbb41dadcaf29e0db034d6ad0d039a9df06e6",
+ "url": "https://api.github.com/repos/symfony/string/zipball/ea272a882be7f20cad58d5d78c215001617b7f07",
+ "reference": "ea272a882be7f20cad58d5d78c215001617b7f07",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "php": ">=8.2",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-normalizer": "~1.0",
+ "symfony/polyfill-mbstring": "~1.0"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "conflict": {
+ "symfony/translation-contracts": "<2.5"
+ },
+ "require-dev": {
+ "symfony/emoji": "^7.1",
+ "symfony/error-handler": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
+ "symfony/translation-contracts": "^2.5|^3.0",
+ "symfony/var-exporter": "^6.4|^7.0"
},
+ "type": "library",
"autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
"psr-4": {
- "Symfony\\Component\\Process\\": ""
+ "Symfony\\Component\\String\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3557,68 +4317,76 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Process Component",
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
"homepage": "https://symfony.com",
- "time": "2019-03-10T20:07:02+00:00"
+ "keywords": [
+ "grapheme",
+ "i18n",
+ "string",
+ "unicode",
+ "utf-8",
+ "utf8"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v7.1.3"
+ },
+ "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-07-22T10:25:37+00:00"
},
{
- "name": "symfony/routing",
- "version": "v4.2.5",
+ "name": "symfony/translation-contracts",
+ "version": "v3.5.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/routing.git",
- "reference": "319f600c1ea0f981f6bdc2f042cfc1690957c0e0"
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/319f600c1ea0f981f6bdc2f042cfc1690957c0e0",
- "reference": "319f600c1ea0f981f6bdc2f042cfc1690957c0e0",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a",
+ "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
- },
- "conflict": {
- "symfony/config": "<4.2",
- "symfony/dependency-injection": "<3.4",
- "symfony/yaml": "<3.4"
- },
- "require-dev": {
- "doctrine/annotations": "~1.0",
- "psr/log": "~1.0",
- "symfony/config": "~4.2",
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/http-foundation": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "doctrine/annotations": "For using the annotation loader",
- "symfony/config": "For using the all-in-one router or any loader",
- "symfony/expression-language": "For using expression matching",
- "symfony/http-foundation": "For using a Symfony Request object",
- "symfony/yaml": "For using the YAML loader"
+ "php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-main": "3.5-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Component\\Routing\\": ""
+ "Symfony\\Contracts\\Translation\\": ""
},
"exclude-from-classmap": [
- "/Tests/"
+ "/Test/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3627,68 +4395,112 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Routing Component",
+ "description": "Generic abstractions related to translation",
"homepage": "https://symfony.com",
"keywords": [
- "router",
- "routing",
- "uri",
- "url"
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.5.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": "2019-03-30T15:58:42+00:00"
+ "time": "2024-04-18T09:32:20+00:00"
},
{
- "name": "symfony/security-core",
- "version": "v4.2.5",
+ "name": "symfony/twig-bridge",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/security-core.git",
- "reference": "d4d72ea26792370db1079fe9ecec707694482f1e"
+ "url": "https://github.com/symfony/twig-bridge.git",
+ "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-core/zipball/d4d72ea26792370db1079fe9ecec707694482f1e",
- "reference": "d4d72ea26792370db1079fe9ecec707694482f1e",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/96e6e12a63db80bcedefc012042d2cb2d1a015f8",
+ "reference": "96e6e12a63db80bcedefc012042d2cb2d1a015f8",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0"
- },
- "require-dev": {
- "psr/container": "^1.0",
- "psr/log": "~1.0",
- "symfony/event-dispatcher": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/http-foundation": "~3.4|~4.0",
- "symfony/ldap": "~3.4|~4.0",
- "symfony/validator": "~3.4|~4.0"
+ "php": ">=8.2",
+ "symfony/translation-contracts": "^2.5|^3",
+ "twig/twig": "^3.9"
},
- "suggest": {
- "psr/container-implementation": "To instantiate the Security class",
- "symfony/event-dispatcher": "",
- "symfony/expression-language": "For using the expression voter",
- "symfony/http-foundation": "",
- "symfony/ldap": "For using LDAP integration",
- "symfony/validator": "For using the user password constraint"
+ "conflict": {
+ "phpdocumentor/reflection-docblock": "<3.2.2",
+ "phpdocumentor/type-resolver": "<1.4.0",
+ "symfony/console": "<6.4",
+ "symfony/form": "<6.4",
+ "symfony/http-foundation": "<6.4",
+ "symfony/http-kernel": "<6.4",
+ "symfony/mime": "<6.4",
+ "symfony/serializer": "<6.4",
+ "symfony/translation": "<6.4",
+ "symfony/workflow": "<6.4"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "require-dev": {
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "league/html-to-markdown": "^5.0",
+ "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
+ "symfony/asset": "^6.4|^7.0",
+ "symfony/asset-mapper": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/emoji": "^7.1",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/form": "^6.4|^7.0",
+ "symfony/html-sanitizer": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
+ "symfony/mime": "^6.4|^7.0",
+ "symfony/polyfill-intl-icu": "~1.0",
+ "symfony/property-info": "^6.4|^7.0",
+ "symfony/routing": "^6.4|^7.0",
+ "symfony/security-acl": "^2.8|^3.0",
+ "symfony/security-core": "^6.4|^7.0",
+ "symfony/security-csrf": "^6.4|^7.0",
+ "symfony/security-http": "^6.4|^7.0",
+ "symfony/serializer": "^6.4.3|^7.0.3",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/translation": "^6.4|^7.0",
+ "symfony/web-link": "^6.4|^7.0",
+ "symfony/workflow": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0",
+ "twig/cssinliner-extra": "^2.12|^3",
+ "twig/inky-extra": "^2.12|^3",
+ "twig/markdown-extra": "^2.12|^3"
},
+ "type": "symfony-bridge",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Security\\Core\\": ""
+ "Symfony\\Bridge\\Twig\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3708,43 +4520,71 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Security Component - Core Library",
+ "description": "Provides integration for Twig with various Symfony components",
"homepage": "https://symfony.com",
- "time": "2019-03-19T21:07:50+00:00"
+ "support": {
+ "source": "https://github.com/symfony/twig-bridge/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
- "name": "symfony/templating",
- "version": "v4.2.5",
+ "name": "symfony/twig-bundle",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/templating.git",
- "reference": "1bb2d2eda3136fff122b8810ac1357440411abeb"
+ "url": "https://github.com/symfony/twig-bundle.git",
+ "reference": "d48c2f08c2f315e749f0e18fc4945b7be8afe1e5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/templating/zipball/1bb2d2eda3136fff122b8810ac1357440411abeb",
- "reference": "1bb2d2eda3136fff122b8810ac1357440411abeb",
+ "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/d48c2f08c2f315e749f0e18fc4945b7be8afe1e5",
+ "reference": "d48c2f08c2f315e749f0e18fc4945b7be8afe1e5",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/polyfill-ctype": "~1.8"
- },
- "require-dev": {
- "psr/log": "~1.0"
+ "composer-runtime-api": ">=2.1",
+ "php": ">=8.2",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/twig-bridge": "^6.4|^7.0",
+ "twig/twig": "^3.0.4"
},
- "suggest": {
- "psr/log-implementation": "For using debug logging in loaders"
+ "conflict": {
+ "symfony/framework-bundle": "<6.4",
+ "symfony/translation": "<6.4"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "require-dev": {
+ "symfony/asset": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/form": "^6.4|^7.0",
+ "symfony/framework-bundle": "^6.4|^7.0",
+ "symfony/routing": "^6.4|^7.0",
+ "symfony/stopwatch": "^6.4|^7.0",
+ "symfony/translation": "^6.4|^7.0",
+ "symfony/web-link": "^6.4|^7.0",
+ "symfony/yaml": "^6.4|^7.0"
},
+ "type": "symfony-bundle",
"autoload": {
"psr-4": {
- "Symfony\\Component\\Templating\\": ""
+ "Symfony\\Bundle\\TwigBundle\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3764,82 +4604,87 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Templating Component",
+ "description": "Provides a tight integration of Twig into the Symfony full-stack framework",
"homepage": "https://symfony.com",
- "time": "2019-02-23T15:17:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/twig-bundle/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
- "name": "symfony/twig-bridge",
- "version": "v4.2.5",
+ "name": "symfony/validator",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/twig-bridge.git",
- "reference": "ae8c3faafec299e8f4e500c0b96cb0e52cfcee90"
+ "url": "https://github.com/symfony/validator.git",
+ "reference": "ba711a6cfc008544dad059abb3c1d997f1472237"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/ae8c3faafec299e8f4e500c0b96cb0e52cfcee90",
- "reference": "ae8c3faafec299e8f4e500c0b96cb0e52cfcee90",
+ "url": "https://api.github.com/repos/symfony/validator/zipball/ba711a6cfc008544dad059abb3c1d997f1472237",
+ "reference": "ba711a6cfc008544dad059abb3c1d997f1472237",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0.2",
- "twig/twig": "^1.38.1|^2.7.1"
+ "php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-ctype": "~1.8",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php83": "^1.27",
+ "symfony/translation-contracts": "^2.5|^3"
},
"conflict": {
- "symfony/console": "<3.4",
- "symfony/form": "<4.2.4",
- "symfony/translation": "<4.2"
+ "doctrine/lexer": "<1.1",
+ "symfony/dependency-injection": "<6.4",
+ "symfony/doctrine-bridge": "<7.0",
+ "symfony/expression-language": "<6.4",
+ "symfony/http-kernel": "<6.4",
+ "symfony/intl": "<6.4",
+ "symfony/property-info": "<6.4",
+ "symfony/translation": "<6.4.3|>=7.0,<7.0.3",
+ "symfony/yaml": "<6.4"
},
"require-dev": {
- "symfony/asset": "~3.4|~4.0",
- "symfony/console": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/form": "^4.2.4",
- "symfony/http-foundation": "~3.4|~4.0",
- "symfony/http-kernel": "~3.4|~4.0",
- "symfony/polyfill-intl-icu": "~1.0",
- "symfony/routing": "~3.4|~4.0",
- "symfony/security": "~3.4|~4.0",
- "symfony/security-acl": "~2.8|~3.0",
- "symfony/stopwatch": "~3.4|~4.0",
- "symfony/templating": "~3.4|~4.0",
- "symfony/translation": "~4.2",
- "symfony/var-dumper": "~3.4|~4.0",
- "symfony/web-link": "~3.4|~4.0",
- "symfony/workflow": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/asset": "For using the AssetExtension",
- "symfony/expression-language": "For using the ExpressionExtension",
- "symfony/finder": "",
- "symfony/form": "For using the FormExtension",
- "symfony/http-kernel": "For using the HttpKernelExtension",
- "symfony/routing": "For using the RoutingExtension",
- "symfony/security": "For using the SecurityExtension",
- "symfony/stopwatch": "For using the StopwatchExtension",
- "symfony/templating": "For using the TwigEngine",
- "symfony/translation": "For using the TranslationExtension",
- "symfony/var-dumper": "For using the DumpExtension",
- "symfony/web-link": "For using the WebLinkExtension",
- "symfony/yaml": "For using the YamlExtension"
- },
- "type": "symfony-bridge",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "egulias/email-validator": "^2.1.10|^3|^4",
+ "symfony/cache": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/expression-language": "^6.4|^7.0",
+ "symfony/finder": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/intl": "^6.4|^7.0",
+ "symfony/mime": "^6.4|^7.0",
+ "symfony/property-access": "^6.4|^7.0",
+ "symfony/property-info": "^6.4|^7.0",
+ "symfony/translation": "^6.4.3|^7.0.3",
+ "symfony/type-info": "^7.1",
+ "symfony/yaml": "^6.4|^7.0"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "Symfony\\Bridge\\Twig\\": ""
+ "Symfony\\Component\\Validator\\": ""
},
"exclude-from-classmap": [
- "/Tests/"
+ "/Tests/",
+ "/Resources/bin/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -3856,63 +4701,66 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Twig Bridge",
+ "description": "Provides tools to validate values",
"homepage": "https://symfony.com",
- "time": "2019-04-01T08:18:15+00:00"
+ "support": {
+ "source": "https://github.com/symfony/validator/tree/v7.1.3"
+ },
+ "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-07-26T12:41:01+00:00"
},
{
- "name": "symfony/twig-bundle",
- "version": "v4.2.5",
+ "name": "symfony/var-dumper",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/twig-bundle.git",
- "reference": "6c6e3be7020563c36a34139bef94fed0735cdf9e"
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/6c6e3be7020563c36a34139bef94fed0735cdf9e",
- "reference": "6c6e3be7020563c36a34139bef94fed0735cdf9e",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/86af4617cca75a6e28598f49ae0690f3b9d4591f",
+ "reference": "86af4617cca75a6e28598f49ae0690f3b9d4591f",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/config": "~4.2",
- "symfony/http-foundation": "~4.1",
- "symfony/http-kernel": "~4.1",
- "symfony/polyfill-ctype": "~1.8",
- "symfony/twig-bridge": "^4.2",
- "twig/twig": "~1.34|~2.4"
+ "php": ">=8.2",
+ "symfony/polyfill-mbstring": "~1.0"
},
"conflict": {
- "symfony/dependency-injection": "<4.1",
- "symfony/framework-bundle": "<4.1",
- "symfony/translation": "<4.2"
+ "symfony/console": "<6.4"
},
"require-dev": {
- "doctrine/annotations": "~1.0",
- "doctrine/cache": "~1.0",
- "symfony/asset": "~3.4|~4.0",
- "symfony/dependency-injection": "^4.2.5",
- "symfony/expression-language": "~3.4|~4.0",
- "symfony/finder": "~3.4|~4.0",
- "symfony/form": "~3.4|~4.0",
- "symfony/framework-bundle": "~4.1",
- "symfony/routing": "~3.4|~4.0",
- "symfony/stopwatch": "~3.4|~4.0",
- "symfony/templating": "~3.4|~4.0",
- "symfony/translation": "^4.2",
- "symfony/web-link": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "type": "symfony-bundle",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "ext-iconv": "*",
+ "symfony/console": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0",
+ "symfony/uid": "^6.4|^7.0",
+ "twig/twig": "^3.0.4"
},
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
"autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
"psr-4": {
- "Symfony\\Bundle\\TwigBundle\\": ""
+ "Symfony\\Component\\VarDumper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -3924,44 +4772,62 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony TwigBundle",
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
"homepage": "https://symfony.com",
- "time": "2019-03-04T11:47:55+00:00"
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v7.1.3"
+ },
+ "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-07-26T12:41:01+00:00"
},
{
"name": "symfony/var-exporter",
- "version": "v4.2.5",
+ "version": "v7.1.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
- "reference": "d8bf4424c232b55f4c1816037d3077a89258557e"
+ "reference": "b80a669a2264609f07f1667f891dbfca25eba44c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d8bf4424c232b55f4c1816037d3077a89258557e",
- "reference": "d8bf4424c232b55f4c1816037d3077a89258557e",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/b80a669a2264609f07f1667f891dbfca25eba44c",
+ "reference": "b80a669a2264609f07f1667f891dbfca25eba44c",
"shasum": ""
},
"require": {
- "php": "^7.1.3"
+ "php": ">=8.2"
},
"require-dev": {
- "symfony/var-dumper": "^4.1.1"
+ "symfony/property-access": "^6.4|^7.0",
+ "symfony/serializer": "^6.4|^7.0",
+ "symfony/var-dumper": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\VarExporter\\": ""
@@ -3984,7 +4850,7 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "A blend of var_export() + serialize() to turn any serializable data structure to plain PHP code",
+ "description": "Allows exporting any serializable PHP data structure to plain PHP code",
"homepage": "https://symfony.com",
"keywords": [
"clone",
@@ -3992,43 +4858,57 @@
"export",
"hydrate",
"instantiate",
+ "lazy-loading",
+ "proxy",
"serialize"
],
- "time": "2019-01-16T20:35:37+00:00"
+ "support": {
+ "source": "https://github.com/symfony/var-exporter/tree/v7.1.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-06-28T08:00:31+00:00"
},
{
"name": "symfony/yaml",
- "version": "v4.2.5",
+ "version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1"
+ "reference": "fa34c77015aa6720469db7003567b9f772492bf2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/6712daf03ee25b53abb14e7e8e0ede1a770efdb1",
- "reference": "6712daf03ee25b53abb14e7e8e0ede1a770efdb1",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/fa34c77015aa6720469db7003567b9f772492bf2",
+ "reference": "fa34c77015aa6720469db7003567b9f772492bf2",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/polyfill-ctype": "~1.8"
+ "php": ">=8.2",
+ "symfony/polyfill-ctype": "^1.8"
},
"conflict": {
- "symfony/console": "<3.4"
+ "symfony/console": "<6.4"
},
"require-dev": {
- "symfony/console": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/console": "For validating YAML files using the lint command"
+ "symfony/console": "^6.4|^7.0"
},
+ "bin": [
+ "Resources/bin/yaml-lint"
+ ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
@@ -4051,44 +4931,60 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Yaml Component",
+ "description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
- "time": "2019-03-30T15:58:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/yaml/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
"name": "twig/twig",
- "version": "v2.7.4",
+ "version": "v3.10.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "ed9c49220e09bfaeb1ba4d48077c08a7b09908dd"
+ "reference": "67f29781ffafa520b0bbfbd8384674b42db04572"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/ed9c49220e09bfaeb1ba4d48077c08a7b09908dd",
- "reference": "ed9c49220e09bfaeb1ba4d48077c08a7b09908dd",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572",
+ "reference": "67f29781ffafa520b0bbfbd8384674b42db04572",
"shasum": ""
},
"require": {
- "php": "^7.0",
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8",
- "symfony/polyfill-mbstring": "^1.3"
+ "symfony/polyfill-mbstring": "^1.3",
+ "symfony/polyfill-php80": "^1.22"
},
"require-dev": {
- "psr/container": "^1.0",
- "symfony/debug": "^2.7",
- "symfony/phpunit-bridge": "^3.4.19|^4.1.8"
+ "psr/container": "^1.0|^2.0",
+ "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.7-dev"
- }
- },
"autoload": {
- "psr-0": {
- "Twig_": "lib/"
- },
+ "files": [
+ "src/Resources/core.php",
+ "src/Resources/debug.php",
+ "src/Resources/escaper.php",
+ "src/Resources/string_loader.php"
+ ],
"psr-4": {
"Twig\\": "src/"
}
@@ -4104,15 +5000,14 @@
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
+ {
+ "name": "Twig Team",
+ "role": "Contributors"
+ },
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
- },
- {
- "name": "Twig Team",
- "homepage": "https://twig.symfony.com/contributors",
- "role": "Contributors"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
@@ -4120,242 +5015,279 @@
"keywords": [
"templating"
],
- "time": "2019-03-23T14:28:58+00:00"
- },
- {
- "name": "willdurand/jsonp-callback-validator",
- "version": "v1.1.0",
- "source": {
- "type": "git",
- "url": "https://github.com/willdurand/JsonpCallbackValidator.git",
- "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/willdurand/JsonpCallbackValidator/zipball/1a7d388bb521959e612ef50c5c7b1691b097e909",
- "reference": "1a7d388bb521959e612ef50c5c7b1691b097e909",
- "shasum": ""
- },
- "require": {
- "php": ">=5.3.0"
- },
- "require-dev": {
- "phpunit/phpunit": "~3.7"
- },
- "type": "library",
- "autoload": {
- "psr-0": {
- "JsonpCallbackValidator": "src/"
- }
+ "support": {
+ "issues": "https://github.com/twigphp/Twig/issues",
+ "source": "https://github.com/twigphp/Twig/tree/v3.10.3"
},
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
+ "funding": [
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
{
- "name": "William Durand",
- "email": "william.durand1@gmail.com",
- "homepage": "http://www.willdurand.fr"
+ "url": "https://tidelift.com/funding/github/packagist/twig/twig",
+ "type": "tidelift"
}
],
- "description": "JSONP callback validator.",
- "time": "2014-01-20T22:35:06+00:00"
+ "time": "2024-05-16T10:04:27+00:00"
},
{
- "name": "willdurand/negotiation",
- "version": "v2.3.1",
+ "name": "webimpress/safe-writer",
+ "version": "2.2.0",
"source": {
"type": "git",
- "url": "https://github.com/willdurand/Negotiation.git",
- "reference": "03436ededa67c6e83b9b12defac15384cb399dc9"
+ "url": "https://github.com/webimpress/safe-writer.git",
+ "reference": "9d37cc8bee20f7cb2f58f6e23e05097eab5072e6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/03436ededa67c6e83b9b12defac15384cb399dc9",
- "reference": "03436ededa67c6e83b9b12defac15384cb399dc9",
+ "url": "https://api.github.com/repos/webimpress/safe-writer/zipball/9d37cc8bee20f7cb2f58f6e23e05097eab5072e6",
+ "reference": "9d37cc8bee20f7cb2f58f6e23e05097eab5072e6",
"shasum": ""
},
"require": {
- "php": ">=5.4.0"
+ "php": "^7.3 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.5"
+ "phpunit/phpunit": "^9.5.4",
+ "vimeo/psalm": "^4.7",
+ "webimpress/coding-standard": "^1.2.2"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.3-dev"
+ "dev-master": "2.2.x-dev",
+ "dev-develop": "2.3.x-dev",
+ "dev-release-1.0": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
- "Negotiation\\": "src/Negotiation"
+ "Webimpress\\SafeWriter\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-2-Clause"
+ ],
+ "description": "Tool to write files safely, to avoid race conditions",
+ "keywords": [
+ "concurrent write",
+ "file writer",
+ "race condition",
+ "safe writer",
+ "webimpress"
],
- "authors": [
+ "support": {
+ "issues": "https://github.com/webimpress/safe-writer/issues",
+ "source": "https://github.com/webimpress/safe-writer/tree/2.2.0"
+ },
+ "funding": [
{
- "name": "William Durand",
- "email": "will+git@drnd.me"
+ "url": "https://github.com/michalbundyra",
+ "type": "github"
}
],
- "description": "Content Negotiation tools for PHP provided as a standalone library.",
- "homepage": "http://williamdurand.fr/Negotiation/",
- "keywords": [
- "accept",
- "content",
- "format",
- "header",
- "negotiation"
- ],
- "time": "2017-05-14T17:21:12+00:00"
- },
+ "time": "2021-04-19T16:34:45+00:00"
+ }
+ ],
+ "packages-dev": [
{
- "name": "zendframework/zend-code",
- "version": "3.3.1",
+ "name": "amphp/amp",
+ "version": "v2.6.4",
"source": {
"type": "git",
- "url": "https://github.com/zendframework/zend-code.git",
- "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb"
+ "url": "https://github.com/amphp/amp.git",
+ "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-code/zipball/c21db169075c6ec4b342149f446e7b7b724f95eb",
- "reference": "c21db169075c6ec4b342149f446e7b7b724f95eb",
+ "url": "https://api.github.com/repos/amphp/amp/zipball/ded3d9be08f526089eb7ee8d9f16a9768f9dec2d",
+ "reference": "ded3d9be08f526089eb7ee8d9f16a9768f9dec2d",
"shasum": ""
},
"require": {
- "php": "^7.1",
- "zendframework/zend-eventmanager": "^2.6 || ^3.0"
+ "php": ">=7.1"
},
"require-dev": {
- "doctrine/annotations": "~1.0",
- "ext-phar": "*",
- "phpunit/phpunit": "^6.2.3",
- "zendframework/zend-coding-standard": "^1.0.0",
- "zendframework/zend-stdlib": "^2.7 || ^3.0"
- },
- "suggest": {
- "doctrine/annotations": "Doctrine\\Common\\Annotations >=1.0 for annotation features",
- "zendframework/zend-stdlib": "Zend\\Stdlib component"
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1",
+ "ext-json": "*",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^7 | ^8 | ^9",
+ "react/promise": "^2",
+ "vimeo/psalm": "^3.12"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.3.x-dev",
- "dev-develop": "3.4.x-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
+ "files": [
+ "lib/functions.php",
+ "lib/Internal/functions.php"
+ ],
"psr-4": {
- "Zend\\Code\\": "src/"
+ "Amp\\": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Daniel Lowrey",
+ "email": "rdlowrey@php.net"
+ },
+ {
+ "name": "Aaron Piotrowski",
+ "email": "aaron@trowski.com"
+ },
+ {
+ "name": "Bob Weinand",
+ "email": "bobwei9@hotmail.com"
+ },
+ {
+ "name": "Niklas Keller",
+ "email": "me@kelunik.com"
+ }
],
- "description": "provides facilities to generate arbitrary code using an object oriented interface",
- "homepage": "https://github.com/zendframework/zend-code",
+ "description": "A non-blocking concurrency framework for PHP applications.",
+ "homepage": "https://amphp.org/amp",
"keywords": [
- "code",
- "zf2"
+ "async",
+ "asynchronous",
+ "awaitable",
+ "concurrency",
+ "event",
+ "event-loop",
+ "future",
+ "non-blocking",
+ "promise"
],
- "time": "2018-08-13T20:36:59+00:00"
+ "support": {
+ "irc": "irc://irc.freenode.org/amphp",
+ "issues": "https://github.com/amphp/amp/issues",
+ "source": "https://github.com/amphp/amp/tree/v2.6.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-21T18:52:26+00:00"
},
{
- "name": "zendframework/zend-eventmanager",
- "version": "3.2.1",
+ "name": "amphp/byte-stream",
+ "version": "v1.8.2",
"source": {
"type": "git",
- "url": "https://github.com/zendframework/zend-eventmanager.git",
- "reference": "a5e2583a211f73604691586b8406ff7296a946dd"
+ "url": "https://github.com/amphp/byte-stream.git",
+ "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/a5e2583a211f73604691586b8406ff7296a946dd",
- "reference": "a5e2583a211f73604691586b8406ff7296a946dd",
+ "url": "https://api.github.com/repos/amphp/byte-stream/zipball/4f0e968ba3798a423730f567b1b50d3441c16ddc",
+ "reference": "4f0e968ba3798a423730f567b1b50d3441c16ddc",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "amphp/amp": "^2",
+ "php": ">=7.1"
},
"require-dev": {
- "athletic/athletic": "^0.1",
- "container-interop/container-interop": "^1.1.0",
- "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2",
- "zendframework/zend-coding-standard": "~1.0.0",
- "zendframework/zend-stdlib": "^2.7.3 || ^3.0"
- },
- "suggest": {
- "container-interop/container-interop": "^1.1.0, to use the lazy listeners feature",
- "zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature"
+ "amphp/php-cs-fixer-config": "dev-master",
+ "amphp/phpunit-util": "^1.4",
+ "friendsofphp/php-cs-fixer": "^2.3",
+ "jetbrains/phpstorm-stubs": "^2019.3",
+ "phpunit/phpunit": "^6 || ^7 || ^8",
+ "psalm/phar": "^3.11.4"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev",
- "dev-develop": "3.3-dev"
- }
- },
"autoload": {
+ "files": [
+ "lib/functions.php"
+ ],
"psr-4": {
- "Zend\\EventManager\\": "src/"
+ "Amp\\ByteStream\\": "lib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
- "description": "Trigger and listen to events within a PHP application",
- "homepage": "https://github.com/zendframework/zend-eventmanager",
+ "authors": [
+ {
+ "name": "Aaron Piotrowski",
+ "email": "aaron@trowski.com"
+ },
+ {
+ "name": "Niklas Keller",
+ "email": "me@kelunik.com"
+ }
+ ],
+ "description": "A stream abstraction to make working with non-blocking I/O simple.",
+ "homepage": "https://amphp.org/byte-stream",
"keywords": [
- "event",
- "eventmanager",
- "events",
- "zf2"
+ "amp",
+ "amphp",
+ "async",
+ "io",
+ "non-blocking",
+ "stream"
],
- "time": "2018-04-25T15:33:34+00:00"
- }
- ],
- "packages-dev": [
+ "support": {
+ "issues": "https://github.com/amphp/byte-stream/issues",
+ "source": "https://github.com/amphp/byte-stream/tree/v1.8.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/amphp",
+ "type": "github"
+ }
+ ],
+ "time": "2024-04-13T18:00:56+00:00"
+ },
{
"name": "behat/behat",
- "version": "v3.5.0",
+ "version": "v3.14.0",
"source": {
"type": "git",
"url": "https://github.com/Behat/Behat.git",
- "reference": "e4bce688be0c2029dc1700e46058d86428c63cab"
+ "reference": "2a3832d9cb853a794af3a576f9e524ae460f3340"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Behat/Behat/zipball/e4bce688be0c2029dc1700e46058d86428c63cab",
- "reference": "e4bce688be0c2029dc1700e46058d86428c63cab",
+ "url": "https://api.github.com/repos/Behat/Behat/zipball/2a3832d9cb853a794af3a576f9e524ae460f3340",
+ "reference": "2a3832d9cb853a794af3a576f9e524ae460f3340",
"shasum": ""
},
"require": {
- "behat/gherkin": "^4.5.1",
+ "behat/gherkin": "^4.9.0",
"behat/transliterator": "^1.2",
- "container-interop/container-interop": "^1.2",
"ext-mbstring": "*",
- "php": ">=5.3.3",
- "psr/container": "^1.0",
- "symfony/class-loader": "~2.1||~3.0",
- "symfony/config": "~2.3||~3.0||~4.0",
- "symfony/console": "~2.7.40||^2.8.33||~3.3.15||^3.4.3||^4.0.3",
- "symfony/dependency-injection": "~2.1||~3.0||~4.0",
- "symfony/event-dispatcher": "~2.1||~3.0||~4.0",
- "symfony/translation": "~2.3||~3.0||~4.0",
- "symfony/yaml": "~2.1||~3.0||~4.0"
+ "php": "^7.2 || ^8.0",
+ "psr/container": "^1.0 || ^2.0",
+ "symfony/config": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/console": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/translation": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/yaml": "^4.4 || ^5.0 || ^6.0 || ^7.0"
},
"require-dev": {
"herrera-io/box": "~1.6.1",
- "phpunit/phpunit": "^4.8.36|^6.3",
- "symfony/process": "~2.5|~3.0|~4.0"
+ "phpspec/prophecy": "^1.15",
+ "phpunit/phpunit": "^8.5 || ^9.0",
+ "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "vimeo/psalm": "^4.8"
+ },
+ "suggest": {
+ "ext-dom": "Needed to output test results in JUnit format."
},
"bin": [
"bin/behat"
@@ -4363,13 +5295,15 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.5.x-dev"
+ "dev-master": "3.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Behat\\Behat": "src/",
- "Behat\\Testwork": "src/"
+ "psr-4": {
+ "Behat\\Hook\\": "src/Behat/Hook/",
+ "Behat\\Step\\": "src/Behat/Step/",
+ "Behat\\Behat\\": "src/Behat/Behat/",
+ "Behat\\Testwork\\": "src/Behat/Testwork/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4383,7 +5317,7 @@
"homepage": "http://everzet.com"
}
],
- "description": "Scenario-oriented BDD framework for PHP 5.3",
+ "description": "Scenario-oriented BDD framework for PHP",
"homepage": "http://behat.org/",
"keywords": [
"Agile",
@@ -4399,29 +5333,33 @@
"symfony",
"testing"
],
- "time": "2018-08-10T18:56:51+00:00"
+ "support": {
+ "issues": "https://github.com/Behat/Behat/issues",
+ "source": "https://github.com/Behat/Behat/tree/v3.14.0"
+ },
+ "time": "2023-12-09T13:55:02+00:00"
},
{
"name": "behat/gherkin",
- "version": "v4.6.0",
+ "version": "v4.9.0",
"source": {
"type": "git",
"url": "https://github.com/Behat/Gherkin.git",
- "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07"
+ "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Behat/Gherkin/zipball/ab0a02ea14893860bca00f225f5621d351a3ad07",
- "reference": "ab0a02ea14893860bca00f225f5621d351a3ad07",
+ "url": "https://api.github.com/repos/Behat/Gherkin/zipball/0bc8d1e30e96183e4f36db9dc79caead300beff4",
+ "reference": "0bc8d1e30e96183e4f36db9dc79caead300beff4",
"shasum": ""
},
"require": {
- "php": ">=5.3.1"
+ "php": "~7.2|~8.0"
},
"require-dev": {
- "phpunit/phpunit": "~4.5|~5",
- "symfony/phpunit-bridge": "~2.7|~3|~4",
- "symfony/yaml": "~2.3|~3|~4"
+ "cucumber/cucumber": "dev-gherkin-22.0.0",
+ "phpunit/phpunit": "~8|~9",
+ "symfony/yaml": "~3|~4|~5"
},
"suggest": {
"symfony/yaml": "If you want to parse features, represented in YAML files"
@@ -4429,7 +5367,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.4-dev"
+ "dev-master": "4.x-dev"
}
},
"autoload": {
@@ -4448,7 +5386,7 @@
"homepage": "http://everzet.com"
}
],
- "description": "Gherkin DSL parser for PHP 5.3",
+ "description": "Gherkin DSL parser for PHP",
"homepage": "http://behat.org/",
"keywords": [
"BDD",
@@ -4458,39 +5396,47 @@
"gherkin",
"parser"
],
- "time": "2019-01-16T14:22:17+00:00"
+ "support": {
+ "issues": "https://github.com/Behat/Gherkin/issues",
+ "source": "https://github.com/Behat/Gherkin/tree/v4.9.0"
+ },
+ "time": "2021-10-12T13:05:09+00:00"
},
{
"name": "behat/mink",
- "version": "v1.7.1",
+ "version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/minkphp/Mink.git",
- "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9"
+ "reference": "d8527fdf8785aad38455fb426af457ab9937aece"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/minkphp/Mink/zipball/e6930b9c74693dff7f4e58577e1b1743399f3ff9",
- "reference": "e6930b9c74693dff7f4e58577e1b1743399f3ff9",
+ "url": "https://api.github.com/repos/minkphp/Mink/zipball/d8527fdf8785aad38455fb426af457ab9937aece",
+ "reference": "d8527fdf8785aad38455fb426af457ab9937aece",
"shasum": ""
},
"require": {
- "php": ">=5.3.1",
- "symfony/css-selector": "~2.1|~3.0"
+ "php": ">=7.2",
+ "symfony/css-selector": "^4.4 || ^5.0 || ^6.0 || ^7.0"
},
"require-dev": {
- "symfony/phpunit-bridge": "~2.7|~3.0"
+ "phpstan/phpstan": "^1.10",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^8.5.22 || ^9.5.11",
+ "symfony/error-handler": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0"
},
"suggest": {
- "behat/mink-browserkit-driver": "extremely fast headless driver for Symfony\\Kernel-based apps (Sf2, Silex)",
- "behat/mink-goutte-driver": "fast headless driver for any app without JS emulation",
+ "behat/mink-browserkit-driver": "fast headless driver for any app without JS emulation",
"behat/mink-selenium2-driver": "slow, but JS-enabled driver for any app (requires Selenium2)",
- "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)"
+ "behat/mink-zombie-driver": "fast and JS-enabled headless driver for any app (requires node.js)",
+ "dmore/chrome-mink-driver": "fast and JS-enabled driver for any app (requires chromium or google chrome)"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.7.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
@@ -4510,42 +5456,54 @@
}
],
"description": "Browser controller/emulator abstraction for PHP",
- "homepage": "http://mink.behat.org/",
+ "homepage": "https://mink.behat.org/",
"keywords": [
"browser",
"testing",
"web"
],
- "time": "2016-03-05T08:26:18+00:00"
+ "support": {
+ "issues": "https://github.com/minkphp/Mink/issues",
+ "source": "https://github.com/minkphp/Mink/tree/v1.11.0"
+ },
+ "time": "2023-12-09T11:23:23+00:00"
},
{
"name": "behat/mink-browserkit-driver",
- "version": "1.3.3",
+ "version": "v2.2.0",
"source": {
"type": "git",
"url": "https://github.com/minkphp/MinkBrowserKitDriver.git",
- "reference": "1b9a7ce903cfdaaec5fb32bfdbb26118343662eb"
+ "reference": "16d53476e42827ed3aafbfa4fde17a1743eafd50"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/1b9a7ce903cfdaaec5fb32bfdbb26118343662eb",
- "reference": "1b9a7ce903cfdaaec5fb32bfdbb26118343662eb",
+ "url": "https://api.github.com/repos/minkphp/MinkBrowserKitDriver/zipball/16d53476e42827ed3aafbfa4fde17a1743eafd50",
+ "reference": "16d53476e42827ed3aafbfa4fde17a1743eafd50",
"shasum": ""
},
"require": {
- "behat/mink": "^1.7.1@dev",
- "php": ">=5.3.6",
- "symfony/browser-kit": "~2.3|~3.0|~4.0",
- "symfony/dom-crawler": "~2.3|~3.0|~4.0"
+ "behat/mink": "^1.11.0@dev",
+ "ext-dom": "*",
+ "php": ">=7.2",
+ "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0 || ^7.0"
},
"require-dev": {
"mink/driver-testsuite": "dev-master",
- "symfony/http-kernel": "~2.3|~3.0|~4.0"
+ "phpstan/phpstan": "^1.10",
+ "phpstan/phpstan-phpunit": "^1.3",
+ "phpunit/phpunit": "^8.5 || ^9.5",
+ "symfony/error-handler": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/http-client": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/mime": "^4.4 || ^5.0 || ^6.0 || ^7.0",
+ "yoast/phpunit-polyfills": "^1.0"
},
"type": "mink-driver",
"extra": {
"branch-alias": {
- "dev-master": "1.3.x-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
@@ -4565,48 +5523,154 @@
}
],
"description": "Symfony2 BrowserKit driver for Mink framework",
- "homepage": "http://mink.behat.org/",
+ "homepage": "https://mink.behat.org/",
"keywords": [
"Mink",
"Symfony2",
"browser",
"testing"
],
- "time": "2018-05-02T09:25:31+00:00"
+ "support": {
+ "issues": "https://github.com/minkphp/MinkBrowserKitDriver/issues",
+ "source": "https://github.com/minkphp/MinkBrowserKitDriver/tree/v2.2.0"
+ },
+ "time": "2023-12-09T11:30:50+00:00"
},
{
- "name": "behat/mink-extension",
- "version": "2.3.1",
+ "name": "behat/transliterator",
+ "version": "v1.5.0",
"source": {
"type": "git",
- "url": "https://github.com/Behat/MinkExtension.git",
- "reference": "80f7849ba53867181b7e412df9210e12fba50177"
+ "url": "https://github.com/Behat/Transliterator.git",
+ "reference": "baac5873bac3749887d28ab68e2f74db3a4408af"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Behat/MinkExtension/zipball/80f7849ba53867181b7e412df9210e12fba50177",
- "reference": "80f7849ba53867181b7e412df9210e12fba50177",
+ "url": "https://api.github.com/repos/Behat/Transliterator/zipball/baac5873bac3749887d28ab68e2f74db3a4408af",
+ "reference": "baac5873bac3749887d28ab68e2f74db3a4408af",
"shasum": ""
},
"require": {
- "behat/behat": "^3.0.5",
- "behat/mink": "^1.5",
- "php": ">=5.3.2",
- "symfony/config": "^2.7|^3.0|^4.0"
+ "php": ">=7.2"
},
"require-dev": {
- "behat/mink-goutte-driver": "^1.1",
- "phpspec/phpspec": "^2.0"
+ "chuyskywalker/rolling-curl": "^3.1",
+ "php-yaoi/php-yaoi": "^1.0",
+ "phpunit/phpunit": "^8.5.25 || ^9.5.19"
},
- "type": "behat-extension",
+ "type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.1.x-dev"
+ "dev-master": "1.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Behat\\MinkExtension": "src/"
+ "psr-4": {
+ "Behat\\Transliterator\\": "src/Behat/Transliterator"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Artistic-1.0"
+ ],
+ "description": "String transliterator",
+ "keywords": [
+ "i18n",
+ "slug",
+ "transliterator"
+ ],
+ "support": {
+ "issues": "https://github.com/Behat/Transliterator/issues",
+ "source": "https://github.com/Behat/Transliterator/tree/v1.5.0"
+ },
+ "time": "2022-03-30T09:27:43+00:00"
+ },
+ {
+ "name": "codelytv/coding-style",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/CodelyTV/php-coding_style-codely.git",
+ "reference": "41d7e6b651619467b05018666606a1ef0958263e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/CodelyTV/php-coding_style-codely/zipball/41d7e6b651619467b05018666606a1ef0958263e",
+ "reference": "41d7e6b651619467b05018666606a1ef0958263e",
+ "shasum": ""
+ },
+ "require": {
+ "symplify/easy-coding-standard": "^12.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "CodelyTv\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "AGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Codely",
+ "homepage": "https://codely.com"
+ }
+ ],
+ "description": "PHP Coding Style rules we use in Codely",
+ "keywords": [
+ "Code style",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/CodelyTV/php-coding_style-codely/issues",
+ "source": "https://github.com/CodelyTV/php-coding_style-codely/tree/1.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://bit.ly/CodelyTvPro",
+ "type": "custom"
+ }
+ ],
+ "time": "2024-08-05T14:17:14+00:00"
+ },
+ {
+ "name": "composer/package-versions-deprecated",
+ "version": "1.11.99.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/package-versions-deprecated.git",
+ "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b4f54f74ef3453349c24a845d22392cd31e65f1d",
+ "reference": "b4f54f74ef3453349c24a845d22392cd31e65f1d",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.1.0 || ^2.0",
+ "php": "^7 || ^8"
+ },
+ "replace": {
+ "ocramius/package-versions": "1.11.99"
+ },
+ "require-dev": {
+ "composer/composer": "^1.9.3 || ^2.0@dev",
+ "ext-zip": "^1.13",
+ "phpunit/phpunit": "^6.5 || ^7"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "PackageVersions\\Installer",
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PackageVersions\\": "src/PackageVersions"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -4615,88 +5679,218 @@
],
"authors": [
{
- "name": "Christophe Coevoet",
- "email": "stof@notk.org"
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com"
},
{
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com"
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be"
}
],
- "description": "Mink extension for Behat",
- "homepage": "http://extensions.behat.org/mink",
+ "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
+ "support": {
+ "issues": "https://github.com/composer/package-versions-deprecated/issues",
+ "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.5"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-01-17T14:14:24+00:00"
+ },
+ {
+ "name": "composer/pcre",
+ "version": "3.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/pcre.git",
+ "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/ea4ab6f9580a4fd221e0418f2c357cdd39102a90",
+ "reference": "ea4ab6f9580a4fd221e0418f2c357cdd39102a90",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.4 || ^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<1.11.8"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^1.11.8",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "phpunit/phpunit": "^8 || ^9"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.x-dev"
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Pcre\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
"keywords": [
- "browser",
- "gui",
- "test",
- "web"
+ "PCRE",
+ "preg",
+ "regex",
+ "regular expression"
+ ],
+ "support": {
+ "issues": "https://github.com/composer/pcre/issues",
+ "source": "https://github.com/composer/pcre/tree/3.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
],
- "time": "2018-02-06T15:36:30+00:00"
+ "time": "2024-07-25T09:36:02+00:00"
},
{
- "name": "behat/transliterator",
- "version": "v1.2.0",
+ "name": "composer/semver",
+ "version": "3.4.2",
"source": {
"type": "git",
- "url": "https://github.com/Behat/Transliterator.git",
- "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c"
+ "url": "https://github.com/composer/semver.git",
+ "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Behat/Transliterator/zipball/826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
- "reference": "826ce7e9c2a6664c0d1f381cbb38b1fb80a7ee2c",
+ "url": "https://api.github.com/repos/composer/semver/zipball/c51258e759afdb17f1fd1fe83bc12baaef6309d6",
+ "reference": "c51258e759afdb17f1fd1fe83bc12baaef6309d6",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
- "chuyskywalker/rolling-curl": "^3.1",
- "php-yaoi/php-yaoi": "^1.0"
+ "phpstan/phpstan": "^1.4",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.2-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Behat\\Transliterator": "src/"
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "support": {
+ "irc": "ircs://irc.libera.chat:6697/composer",
+ "issues": "https://github.com/composer/semver/issues",
+ "source": "https://github.com/composer/semver/tree/3.4.2"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
}
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Artistic-1.0"
- ],
- "description": "String transliterator",
- "keywords": [
- "i18n",
- "slug",
- "transliterator"
],
- "time": "2017-04-04T11:38:05+00:00"
+ "time": "2024-07-12T11:35:52+00:00"
},
{
"name": "composer/xdebug-handler",
- "version": "1.3.2",
+ "version": "3.0.5",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "d17708133b6c276d6e42ef887a877866b909d892"
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/d17708133b6c276d6e42ef887a877866b909d892",
- "reference": "d17708133b6c276d6e42ef887a877866b909d892",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef",
+ "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef",
"shasum": ""
},
"require": {
- "php": "^5.3.2 || ^7.0",
- "psr/log": "^1.0"
+ "composer/pcre": "^1 || ^2 || ^3",
+ "php": "^7.2.5 || ^8.0",
+ "psr/log": "^1 || ^2 || ^3"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5"
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-strict-rules": "^1.1",
+ "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
},
"type": "library",
"autoload": {
@@ -4714,132 +5908,106 @@
"email": "john-stevenson@blueyonder.co.uk"
}
],
- "description": "Restarts a process without xdebug.",
+ "description": "Restarts a process without Xdebug.",
"keywords": [
"Xdebug",
"performance"
],
- "time": "2019-01-28T20:25:53+00:00"
- },
- {
- "name": "container-interop/container-interop",
- "version": "1.2.0",
- "source": {
- "type": "git",
- "url": "https://github.com/container-interop/container-interop.git",
- "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
- "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
- "shasum": ""
- },
- "require": {
- "psr/container": "^1.0"
+ "support": {
+ "irc": "ircs://irc.libera.chat:6697/composer",
+ "issues": "https://github.com/composer/xdebug-handler/issues",
+ "source": "https://github.com/composer/xdebug-handler/tree/3.0.5"
},
- "type": "library",
- "autoload": {
- "psr-4": {
- "Interop\\Container\\": "src/Interop/Container/"
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
}
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
],
- "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
- "homepage": "https://github.com/container-interop/container-interop",
- "time": "2017-02-14T19:40:03+00:00"
+ "time": "2024-05-06T16:37:16+00:00"
},
{
- "name": "friends-of-behat/symfony-extension",
- "version": "v2.0.8",
+ "name": "dnoegel/php-xdg-base-dir",
+ "version": "v0.1.1",
"source": {
"type": "git",
- "url": "https://github.com/FriendsOfBehat/SymfonyExtension.git",
- "reference": "47ecdcc9a022775cbb612345b43962a9963cfb65"
+ "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfBehat/SymfonyExtension/zipball/47ecdcc9a022775cbb612345b43962a9963cfb65",
- "reference": "47ecdcc9a022775cbb612345b43962a9963cfb65",
+ "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+ "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
"shasum": ""
},
"require": {
- "behat/behat": "^3.4",
- "php": "^7.1",
- "symfony/dependency-injection": "^3.4|^4.1",
- "symfony/http-kernel": "^3.4|^4.1",
- "symfony/proxy-manager-bridge": "^3.4|^4.1"
+ "php": ">=5.3.2"
},
"require-dev": {
- "behat/mink": "^1.7",
- "behat/mink-browserkit-driver": "^1.3",
- "behat/mink-extension": "^2.2",
- "behat/mink-selenium2-driver": "^1.3",
- "friends-of-behat/service-container-extension": "^1.0",
- "phpstan/phpstan-shim": "^0.11",
- "sylius-labs/coding-standard": "^3.0",
- "symfony/framework-bundle": "^3.4|^4.1",
- "symfony/yaml": "^3.4|^4.1"
- },
- "suggest": {
- "behat/mink-browserkit-driver": "^1.3"
- },
- "type": "symfony-bundle",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
+ "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
},
+ "type": "library",
"autoload": {
"psr-4": {
- "FriendsOfBehat\\SymfonyExtension\\": "src/"
+ "XdgBaseDir\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
- {
- "name": "Kamil Kokot",
- "email": "kamil@kokot.me",
- "homepage": "http://kamil.kokot.me"
- }
- ],
- "description": "Integrates Behat with Symfony.",
- "time": "2019-03-21T16:26:33+00:00"
+ "description": "implementation of xdg base directory specification for php",
+ "support": {
+ "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
+ "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
+ },
+ "time": "2019-12-04T15:06:13+00:00"
},
{
- "name": "fzaninotto/faker",
- "version": "v1.8.0",
+ "name": "fakerphp/faker",
+ "version": "v1.23.1",
"source": {
"type": "git",
- "url": "https://github.com/fzaninotto/Faker.git",
- "reference": "f72816b43e74063c8b10357394b6bba8cb1c10de"
+ "url": "https://github.com/FakerPHP/Faker.git",
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/f72816b43e74063c8b10357394b6bba8cb1c10de",
- "reference": "f72816b43e74063c8b10357394b6bba8cb1c10de",
+ "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/bfb4fe148adbf78eff521199619b93a52ae3554b",
+ "reference": "bfb4fe148adbf78eff521199619b93a52ae3554b",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": "^7.4 || ^8.0",
+ "psr/container": "^1.0 || ^2.0",
+ "symfony/deprecation-contracts": "^2.2 || ^3.0"
+ },
+ "conflict": {
+ "fzaninotto/faker": "*"
},
"require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "doctrine/persistence": "^1.3 || ^2.0",
"ext-intl": "*",
- "phpunit/phpunit": "^4.8.35 || ^5.7",
- "squizlabs/php_codesniffer": "^1.5"
+ "phpunit/phpunit": "^9.5.26",
+ "symfony/phpunit-bridge": "^5.4.16"
},
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.8-dev"
- }
+ "suggest": {
+ "doctrine/orm": "Required to use Faker\\ORM\\Doctrine",
+ "ext-curl": "Required by Faker\\Provider\\Image to download images.",
+ "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.",
+ "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.",
+ "ext-mbstring": "Required for multibyte Unicode string functionality."
},
+ "type": "library",
"autoload": {
"psr-4": {
"Faker\\": "src/Faker/"
@@ -4860,76 +6028,78 @@
"faker",
"fixtures"
],
- "time": "2018-07-12T10:23:15+00:00"
+ "support": {
+ "issues": "https://github.com/FakerPHP/Faker/issues",
+ "source": "https://github.com/FakerPHP/Faker/tree/v1.23.1"
+ },
+ "time": "2024-01-02T13:46:09+00:00"
},
{
- "name": "hamcrest/hamcrest-php",
- "version": "v2.0.0",
+ "name": "felixfbecker/advanced-json-rpc",
+ "version": "v3.2.1",
"source": {
"type": "git",
- "url": "https://github.com/hamcrest/hamcrest-php.git",
- "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad"
+ "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad",
- "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad",
+ "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+ "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447",
"shasum": ""
},
"require": {
- "php": "^5.3|^7.0"
- },
- "replace": {
- "cordoval/hamcrest-php": "*",
- "davedevelopment/hamcrest-php": "*",
- "kodova/hamcrest-php": "*"
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "php": "^7.1 || ^8.0",
+ "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
},
"require-dev": {
- "phpunit/php-file-iterator": "1.3.3",
- "phpunit/phpunit": "~4.0",
- "satooshi/php-coveralls": "^1.0"
+ "phpunit/phpunit": "^7.0 || ^8.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "2.0-dev"
- }
- },
"autoload": {
- "classmap": [
- "hamcrest"
- ]
+ "psr-4": {
+ "AdvancedJsonRpc\\": "lib/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD"
+ "ISC"
],
- "description": "This is the PHP port of Hamcrest Matchers",
- "keywords": [
- "test"
+ "authors": [
+ {
+ "name": "Felix Becker",
+ "email": "felix.b@outlook.com"
+ }
],
- "time": "2016-01-20T08:20:44+00:00"
+ "description": "A more advanced JSONRPC implementation",
+ "support": {
+ "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues",
+ "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1"
+ },
+ "time": "2021-06-11T22:34:44+00:00"
},
{
- "name": "jean85/pretty-package-versions",
- "version": "1.2",
+ "name": "felixfbecker/language-server-protocol",
+ "version": "v1.5.2",
"source": {
"type": "git",
- "url": "https://github.com/Jean85/pretty-package-versions.git",
- "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48"
+ "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/75c7effcf3f77501d0e0caa75111aff4daa0dd48",
- "reference": "75c7effcf3f77501d0e0caa75111aff4daa0dd48",
+ "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842",
+ "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842",
"shasum": ""
},
"require": {
- "ocramius/package-versions": "^1.2.0",
- "php": "^7.0"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "phpstan/phpstan": "*",
+ "squizlabs/php_codesniffer": "^3.1",
+ "vimeo/psalm": "^4.0"
},
"type": "library",
"extra": {
@@ -4939,741 +6109,684 @@
},
"autoload": {
"psr-4": {
- "Jean85\\": "src/"
+ "LanguageServerProtocol\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "ISC"
],
"authors": [
{
- "name": "Alessandro Lai",
- "email": "alessandro.lai85@gmail.com"
+ "name": "Felix Becker",
+ "email": "felix.b@outlook.com"
}
],
- "description": "A wrapper for ocramius/package-versions to get pretty versions strings",
+ "description": "PHP classes for the Language Server Protocol",
"keywords": [
- "composer",
- "package",
- "release",
- "versions"
+ "language",
+ "microsoft",
+ "php",
+ "server"
],
- "time": "2018-06-13T13:22:40+00:00"
+ "support": {
+ "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
+ "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2"
+ },
+ "time": "2022-03-02T22:36:06+00:00"
},
{
- "name": "mockery/mockery",
- "version": "1.2.2",
+ "name": "fidry/cpu-core-counter",
+ "version": "1.1.0",
"source": {
"type": "git",
- "url": "https://github.com/mockery/mockery.git",
- "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2"
+ "url": "https://github.com/theofidry/cpu-core-counter.git",
+ "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mockery/mockery/zipball/0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2",
- "reference": "0eb0b48c3f07b3b89f5169ce005b7d05b18cf1d2",
+ "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42",
+ "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42",
"shasum": ""
},
"require": {
- "hamcrest/hamcrest-php": "~2.0",
- "lib-pcre": ">=7.0",
- "php": ">=5.6.0"
+ "php": "^7.2 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "~5.7.10|~6.5|~7.0|~8.0"
+ "fidry/makefile": "^0.2.0",
+ "fidry/php-cs-fixer-config": "^1.1.2",
+ "phpstan/extension-installer": "^1.2.0",
+ "phpstan/phpstan": "^1.9.2",
+ "phpstan/phpstan-deprecation-rules": "^1.0.0",
+ "phpstan/phpstan-phpunit": "^1.2.2",
+ "phpstan/phpstan-strict-rules": "^1.4.4",
+ "phpunit/phpunit": "^8.5.31 || ^9.5.26",
+ "webmozarts/strict-phpunit": "^7.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
"autoload": {
- "psr-0": {
- "Mockery": "library/"
+ "psr-4": {
+ "Fidry\\CpuCoreCounter\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "PΓ‘draic Brady",
- "email": "padraic.brady@gmail.com",
- "homepage": "http://blog.astrumfutura.com"
- },
- {
- "name": "Dave Marshall",
- "email": "dave.marshall@atstsolutions.co.uk",
- "homepage": "http://davedevelopment.co.uk"
+ "name": "ThΓ©o FIDRY",
+ "email": "theo.fidry@gmail.com"
}
],
- "description": "Mockery is a simple yet flexible PHP mock object framework",
- "homepage": "https://github.com/mockery/mockery",
+ "description": "Tiny utility to get the number of CPU cores.",
"keywords": [
- "BDD",
- "TDD",
- "library",
- "mock",
- "mock objects",
- "mockery",
- "stub",
- "test",
- "test double",
- "testing"
+ "CPU",
+ "core"
],
- "time": "2019-02-13T09:37:52+00:00"
- },
- {
- "name": "myclabs/deep-copy",
- "version": "1.9.0",
- "source": {
- "type": "git",
- "url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "78af75148f9fdd34ea727c8b529a9b4a8f7b740c"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/78af75148f9fdd34ea727c8b529a9b4a8f7b740c",
- "reference": "78af75148f9fdd34ea727c8b529a9b4a8f7b740c",
- "shasum": ""
- },
- "require": {
- "php": "^7.2"
- },
- "replace": {
- "myclabs/deep-copy": "self.version"
- },
- "require-dev": {
- "doctrine/collections": "^1.0",
- "doctrine/common": "^2.6",
- "phpstan/phpstan": "^0.9.2",
- "phpstan/phpstan-phpunit": "^0.9.4",
- "phpunit/phpunit": "^7.1"
- },
- "type": "library",
- "autoload": {
- "psr-4": {
- "DeepCopy\\": "src/DeepCopy/"
- },
- "files": [
- "src/DeepCopy/deep_copy.php"
- ]
+ "support": {
+ "issues": "https://github.com/theofidry/cpu-core-counter/issues",
+ "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0"
},
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "description": "Create deep copies (clones) of your objects",
- "keywords": [
- "clone",
- "copy",
- "duplicate",
- "object",
- "object graph"
+ "funding": [
+ {
+ "url": "https://github.com/theofidry",
+ "type": "github"
+ }
],
- "time": "2018-10-30T00:14:44+00:00"
+ "time": "2024-02-07T09:43:46+00:00"
},
{
- "name": "nette/bootstrap",
- "version": "v3.0.0",
+ "name": "friends-of-behat/mink-extension",
+ "version": "v2.7.5",
"source": {
"type": "git",
- "url": "https://github.com/nette/bootstrap.git",
- "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3"
+ "url": "https://github.com/FriendsOfBehat/MinkExtension.git",
+ "reference": "854336030e11983f580f49faad1b49a1238f9846"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/bootstrap/zipball/e1075af05c211915e03e0c86542f3ba5433df4a3",
- "reference": "e1075af05c211915e03e0c86542f3ba5433df4a3",
+ "url": "https://api.github.com/repos/FriendsOfBehat/MinkExtension/zipball/854336030e11983f580f49faad1b49a1238f9846",
+ "reference": "854336030e11983f580f49faad1b49a1238f9846",
"shasum": ""
},
"require": {
- "nette/di": "^3.0",
- "nette/utils": "^3.0",
- "php": ">=7.1"
+ "behat/behat": "^3.0.5",
+ "behat/mink": "^1.5",
+ "php": ">=7.4",
+ "symfony/config": "^4.4 || ^5.0 || ^6.0 || ^7.0"
},
- "require-dev": {
- "latte/latte": "^2.2",
- "nette/application": "^3.0",
- "nette/caching": "^3.0",
- "nette/database": "^3.0",
- "nette/forms": "^3.0",
- "nette/http": "^3.0",
- "nette/mail": "^3.0",
- "nette/robot-loader": "^3.0",
- "nette/safe-stream": "^2.2",
- "nette/security": "^3.0",
- "nette/tester": "^2.0",
- "tracy/tracy": "^2.6"
+ "replace": {
+ "behat/mink-extension": "self.version"
},
- "suggest": {
- "nette/robot-loader": "to use Configurator::createRobotLoader()",
- "tracy/tracy": "to use Configurator::enableTracy()"
+ "require-dev": {
+ "behat/mink-goutte-driver": "^1.1 || ^2.0",
+ "phpspec/phpspec": "^6.0 || ^7.0 || 7.1.x-dev"
},
- "type": "library",
+ "type": "behat-extension",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.1.x-dev"
}
},
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-0": {
+ "Behat\\MinkExtension": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "MIT"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com"
},
{
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Christophe Coevoet",
+ "email": "stof@notk.org"
}
],
- "description": "π
± Nette Bootstrap: the simple way to configure and bootstrap your Nette application.",
- "homepage": "https://nette.org",
+ "description": "Mink extension for Behat",
+ "homepage": "http://extensions.behat.org/mink",
"keywords": [
- "bootstrapping",
- "configurator",
- "nette"
+ "browser",
+ "gui",
+ "test",
+ "web"
],
- "time": "2019-03-26T12:59:07+00:00"
+ "support": {
+ "issues": "https://github.com/FriendsOfBehat/MinkExtension/issues",
+ "source": "https://github.com/FriendsOfBehat/MinkExtension/tree/v2.7.5"
+ },
+ "time": "2024-01-11T09:12:02+00:00"
},
{
- "name": "nette/di",
- "version": "v3.0.0",
+ "name": "friends-of-behat/symfony-extension",
+ "version": "v2.6.0",
"source": {
"type": "git",
- "url": "https://github.com/nette/di.git",
- "reference": "19d83539245aaacb59470828919182411061841f"
+ "url": "https://github.com/FriendsOfBehat/SymfonyExtension.git",
+ "reference": "dfb1c9c96cc0fb7c8e1caa060695426a12e1efbd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/di/zipball/19d83539245aaacb59470828919182411061841f",
- "reference": "19d83539245aaacb59470828919182411061841f",
+ "url": "https://api.github.com/repos/FriendsOfBehat/SymfonyExtension/zipball/dfb1c9c96cc0fb7c8e1caa060695426a12e1efbd",
+ "reference": "dfb1c9c96cc0fb7c8e1caa060695426a12e1efbd",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "nette/neon": "^3.0",
- "nette/php-generator": "^3.2.2",
- "nette/robot-loader": "^3.2",
- "nette/schema": "^1.0",
- "nette/utils": "^3.0",
- "php": ">=7.1"
- },
- "conflict": {
- "nette/bootstrap": "<3.0"
+ "behat/behat": "^3.6.1",
+ "php": "^8.1",
+ "symfony/dependency-injection": "^6.2 || ^7.0",
+ "symfony/http-kernel": "^6.2 || ^7.0"
},
"require-dev": {
- "nette/tester": "^2.2",
- "tracy/tracy": "^2.3"
+ "behat/mink": "^1.9",
+ "behat/mink-browserkit-driver": "^2.0",
+ "behat/mink-selenium2-driver": "^1.3",
+ "friends-of-behat/mink-extension": "^2.5",
+ "friends-of-behat/page-object-extension": "^0.3.2",
+ "friends-of-behat/service-container-extension": "^1.1",
+ "sylius-labs/coding-standard": ">=4.1.1, <=4.2.1",
+ "symfony/browser-kit": "^6.2 || ^7.0",
+ "symfony/framework-bundle": "^6.2 || ^7.0",
+ "symfony/process": "^6.2 || ^7.0",
+ "symfony/yaml": "^6.2 || ^7.0",
+ "vimeo/psalm": "4.30.0"
},
- "type": "library",
+ "suggest": {
+ "behat/mink": "^1.9",
+ "behat/mink-browserkit-driver": "^2.0",
+ "friends-of-behat/mink-extension": "^2.5"
+ },
+ "type": "symfony-bundle",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.2-dev"
}
},
"autoload": {
- "classmap": [
- "src/"
- ],
- "files": [
- "src/compatibility.php"
- ]
+ "psr-4": {
+ "FriendsOfBehat\\SymfonyExtension\\": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "MIT"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Kamil Kokot",
+ "email": "kamil@kokot.me",
+ "homepage": "https://kamilkokot.com"
}
],
- "description": "π Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.",
- "homepage": "https://nette.org",
- "keywords": [
- "compiled",
- "di",
- "dic",
- "factory",
- "ioc",
- "nette",
- "static"
- ],
- "time": "2019-04-03T19:35:46+00:00"
+ "description": "Integrates Behat with Symfony.",
+ "support": {
+ "issues": "https://github.com/FriendsOfBehat/SymfonyExtension/issues",
+ "source": "https://github.com/FriendsOfBehat/SymfonyExtension/tree/v2.6.0"
+ },
+ "time": "2024-07-03T15:49:43+00:00"
},
{
- "name": "nette/finder",
- "version": "v2.5.0",
+ "name": "hamcrest/hamcrest-php",
+ "version": "v2.0.1",
"source": {
"type": "git",
- "url": "https://github.com/nette/finder.git",
- "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2"
+ "url": "https://github.com/hamcrest/hamcrest-php.git",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/finder/zipball/6be1b83ea68ac558aff189d640abe242e0306fe2",
- "reference": "6be1b83ea68ac558aff189d640abe242e0306fe2",
+ "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+ "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
"shasum": ""
},
"require": {
- "nette/utils": "^2.4 || ~3.0.0",
- "php": ">=7.1"
+ "php": "^5.3|^7.0|^8.0"
},
- "conflict": {
- "nette/nette": "<2.2"
+ "replace": {
+ "cordoval/hamcrest-php": "*",
+ "davedevelopment/hamcrest-php": "*",
+ "kodova/hamcrest-php": "*"
},
"require-dev": {
- "nette/tester": "^2.0",
- "tracy/tracy": "^2.3"
+ "phpunit/php-file-iterator": "^1.4 || ^2.0",
+ "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.5-dev"
+ "dev-master": "2.1-dev"
}
},
"autoload": {
"classmap": [
- "src/"
+ "hamcrest"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
- ],
- "authors": [
- {
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
- }
+ "BSD-3-Clause"
],
- "description": "? Nette Finder: find files and directories with an intuitive API.",
- "homepage": "https://nette.org",
+ "description": "This is the PHP port of Hamcrest Matchers",
"keywords": [
- "filesystem",
- "glob",
- "iterator",
- "nette"
+ "test"
],
- "time": "2019-02-28T18:13:25+00:00"
+ "support": {
+ "issues": "https://github.com/hamcrest/hamcrest-php/issues",
+ "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+ },
+ "time": "2020-07-09T08:09:16+00:00"
},
{
- "name": "nette/neon",
- "version": "v3.0.0",
+ "name": "masterminds/html5",
+ "version": "2.9.0",
"source": {
"type": "git",
- "url": "https://github.com/nette/neon.git",
- "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb"
+ "url": "https://github.com/Masterminds/html5-php.git",
+ "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/neon/zipball/cbff32059cbdd8720deccf9e9eace6ee516f02eb",
- "reference": "cbff32059cbdd8720deccf9e9eace6ee516f02eb",
+ "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
+ "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6",
"shasum": ""
},
"require": {
- "ext-iconv": "*",
- "ext-json": "*",
- "php": ">=7.0"
+ "ext-dom": "*",
+ "php": ">=5.3.0"
},
"require-dev": {
- "nette/tester": "^2.0",
- "tracy/tracy": "^2.3"
+ "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "2.7-dev"
}
},
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-4": {
+ "Masterminds\\": "src"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "MIT"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
+ "name": "Matt Butcher",
+ "email": "technosophos@gmail.com"
+ },
+ {
+ "name": "Matt Farina",
+ "email": "matt@mattfarina.com"
},
{
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Asmir Mustafic",
+ "email": "goetas@gmail.com"
}
],
- "description": "πΈ Nette NEON: encodes and decodes NEON file format.",
- "homepage": "http://ne-on.org",
+ "description": "An HTML5 parser and serializer.",
+ "homepage": "http://masterminds.github.io/html5-php",
"keywords": [
- "export",
- "import",
- "neon",
- "nette",
- "yaml"
+ "HTML5",
+ "dom",
+ "html",
+ "parser",
+ "querypath",
+ "serializer",
+ "xml"
],
- "time": "2019-02-05T21:30:40+00:00"
+ "support": {
+ "issues": "https://github.com/Masterminds/html5-php/issues",
+ "source": "https://github.com/Masterminds/html5-php/tree/2.9.0"
+ },
+ "time": "2024-03-31T07:05:07+00:00"
},
{
- "name": "nette/php-generator",
- "version": "v3.2.2",
+ "name": "mockery/mockery",
+ "version": "1.6.12",
"source": {
"type": "git",
- "url": "https://github.com/nette/php-generator.git",
- "reference": "acff8b136fad84b860a626d133e791f95781f9f5"
+ "url": "https://github.com/mockery/mockery.git",
+ "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/php-generator/zipball/acff8b136fad84b860a626d133e791f95781f9f5",
- "reference": "acff8b136fad84b860a626d133e791f95781f9f5",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699",
+ "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699",
"shasum": ""
},
"require": {
- "nette/utils": "^2.4.2 || ~3.0.0",
- "php": ">=7.1"
+ "hamcrest/hamcrest-php": "^2.0.1",
+ "lib-pcre": ">=7.0",
+ "php": ">=7.3"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<8.0"
},
"require-dev": {
- "nette/tester": "^2.0",
- "tracy/tracy": "^2.3"
+ "phpunit/phpunit": "^8.5 || ^9.6.17",
+ "symplify/easy-coding-standard": "^12.1.14"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
"autoload": {
- "classmap": [
- "src/"
- ]
+ "files": [
+ "library/helpers.php",
+ "library/Mockery.php"
+ ],
+ "psr-4": {
+ "Mockery\\": "library/Mockery"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
+ "name": "PΓ‘draic Brady",
+ "email": "padraic.brady@gmail.com",
+ "homepage": "https://github.com/padraic",
+ "role": "Author"
+ },
+ {
+ "name": "Dave Marshall",
+ "email": "dave.marshall@atstsolutions.co.uk",
+ "homepage": "https://davedevelopment.co.uk",
+ "role": "Developer"
},
{
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Nathanael Esayeas",
+ "email": "nathanael.esayeas@protonmail.com",
+ "homepage": "https://github.com/ghostwriter",
+ "role": "Lead Developer"
}
],
- "description": "π Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.3 features.",
- "homepage": "https://nette.org",
+ "description": "Mockery is a simple yet flexible PHP mock object framework",
+ "homepage": "https://github.com/mockery/mockery",
"keywords": [
- "code",
- "nette",
- "php",
- "scaffolding"
+ "BDD",
+ "TDD",
+ "library",
+ "mock",
+ "mock objects",
+ "mockery",
+ "stub",
+ "test",
+ "test double",
+ "testing"
],
- "time": "2019-03-15T03:41:13+00:00"
+ "support": {
+ "docs": "https://docs.mockery.io/",
+ "issues": "https://github.com/mockery/mockery/issues",
+ "rss": "https://github.com/mockery/mockery/releases.atom",
+ "security": "https://github.com/mockery/mockery/security/advisories",
+ "source": "https://github.com/mockery/mockery"
+ },
+ "time": "2024-05-16T03:13:13+00:00"
},
{
- "name": "nette/robot-loader",
- "version": "v3.2.0",
+ "name": "myclabs/deep-copy",
+ "version": "1.12.0",
"source": {
"type": "git",
- "url": "https://github.com/nette/robot-loader.git",
- "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c"
+ "url": "https://github.com/myclabs/DeepCopy.git",
+ "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/robot-loader/zipball/0712a0e39ae7956d6a94c0ab6ad41aa842544b5c",
- "reference": "0712a0e39ae7956d6a94c0ab6ad41aa842544b5c",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
+ "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "nette/finder": "^2.5",
- "nette/utils": "^3.0",
- "php": ">=7.1"
+ "php": "^7.1 || ^8.0"
+ },
+ "conflict": {
+ "doctrine/collections": "<1.6.8",
+ "doctrine/common": "<2.13.3 || >=3 <3.2.2"
},
"require-dev": {
- "nette/tester": "^2.0",
- "tracy/tracy": "^2.3"
+ "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",
- "extra": {
- "branch-alias": {
- "dev-master": "3.2-dev"
- }
- },
"autoload": {
- "classmap": [
- "src/"
- ]
+ "files": [
+ "src/DeepCopy/deep_copy.php"
+ ],
+ "psr-4": {
+ "DeepCopy\\": "src/DeepCopy/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "MIT"
],
- "authors": [
- {
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
+ "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.0"
+ },
+ "funding": [
{
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+ "type": "tidelift"
}
],
- "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"
- ],
- "time": "2019-03-08T21:57:24+00:00"
+ "time": "2024-06-12T14:39:25+00:00"
},
{
- "name": "nette/schema",
- "version": "v1.0.0",
+ "name": "netresearch/jsonmapper",
+ "version": "v4.4.1",
"source": {
"type": "git",
- "url": "https://github.com/nette/schema.git",
- "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d"
+ "url": "https://github.com/cweiske/jsonmapper.git",
+ "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/schema/zipball/6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d",
- "reference": "6241d8d4da39e825dd6cb5bfbe4242912f4d7e4d",
+ "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/132c75c7dd83e45353ebb9c6c9f591952995bbf0",
+ "reference": "132c75c7dd83e45353ebb9c6c9f591952995bbf0",
"shasum": ""
},
"require": {
- "nette/utils": "^3.0.1",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
"php": ">=7.1"
},
"require-dev": {
- "nette/tester": "^2.2",
- "tracy/tracy": "^2.3"
+ "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0 || ~10.0",
+ "squizlabs/php_codesniffer": "~3.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0-dev"
- }
- },
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-0": {
+ "JsonMapper": "src/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "OSL-3.0"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Christian Weiske",
+ "email": "cweiske@cweiske.de",
+ "homepage": "http://github.com/cweiske/jsonmapper/",
+ "role": "Developer"
}
],
- "description": "π Nette Schema: validating data structures against a given Schema.",
- "homepage": "https://nette.org",
- "keywords": [
- "config",
- "nette"
- ],
- "time": "2019-04-03T15:53:25+00:00"
+ "description": "Map nested JSON structures onto PHP classes",
+ "support": {
+ "email": "cweiske@cweiske.de",
+ "issues": "https://github.com/cweiske/jsonmapper/issues",
+ "source": "https://github.com/cweiske/jsonmapper/tree/v4.4.1"
+ },
+ "time": "2024-01-31T06:18:54+00:00"
},
{
- "name": "nette/utils",
- "version": "v3.0.1",
+ "name": "nikic/php-parser",
+ "version": "v4.19.1",
"source": {
"type": "git",
- "url": "https://github.com/nette/utils.git",
- "reference": "bd961f49b211997202bda1d0fbc410905be370d4"
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nette/utils/zipball/bd961f49b211997202bda1d0fbc410905be370d4",
- "reference": "bd961f49b211997202bda1d0fbc410905be370d4",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b",
+ "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b",
"shasum": ""
},
"require": {
+ "ext-tokenizer": "*",
"php": ">=7.1"
},
"require-dev": {
- "nette/tester": "~2.0",
- "tracy/tracy": "^2.3"
- },
- "suggest": {
- "ext-gd": "to use Image",
- "ext-iconv": "to use Strings::webalize() and toAscii()",
- "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-xml": "to use Strings::length() etc. when mbstring is not available"
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
},
+ "bin": [
+ "bin/php-parse"
+ ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0-dev"
+ "dev-master": "4.9-dev"
}
},
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause",
- "GPL-2.0",
- "GPL-3.0"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "David Grudl",
- "homepage": "https://davidgrudl.com"
- },
- {
- "name": "Nette Community",
- "homepage": "https://nette.org/contributors"
+ "name": "Nikita Popov"
}
],
- "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",
+ "description": "A PHP parser written in PHP",
"keywords": [
- "array",
- "core",
- "datetime",
- "images",
- "json",
- "nette",
- "paginator",
- "password",
- "slugify",
- "string",
- "unicode",
- "utf-8",
- "utility",
- "validation"
+ "parser",
+ "php"
],
- "time": "2019-03-22T01:00:30+00:00"
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1"
+ },
+ "time": "2024-03-17T08:10:35+00:00"
},
{
- "name": "nikic/php-parser",
- "version": "v4.2.1",
+ "name": "pdepend/pdepend",
+ "version": "2.16.2",
"source": {
"type": "git",
- "url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0"
+ "url": "https://github.com/pdepend/pdepend.git",
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/5221f49a608808c1e4d436df32884cbc1b821ac0",
- "reference": "5221f49a608808c1e4d436df32884cbc1b821ac0",
+ "url": "https://api.github.com/repos/pdepend/pdepend/zipball/f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
+ "reference": "f942b208dc2a0868454d01b29f0c75bbcfc6ed58",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "php": ">=7.0"
+ "php": ">=5.3.7",
+ "symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
+ "symfony/polyfill-mbstring": "^1.19"
},
"require-dev": {
- "phpunit/phpunit": "^6.5 || ^7.0"
+ "easy-doc/easy-doc": "0.0.0|^1.2.3",
+ "gregwar/rst": "^1.0",
+ "squizlabs/php_codesniffer": "^2.0.0"
},
"bin": [
- "bin/php-parse"
+ "src/bin/pdepend"
],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-master": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "PhpParser\\": "lib/PhpParser"
+ "PDepend\\": "src/main/php/PDepend"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
- "authors": [
+ "description": "Official version of pdepend to be handled with Composer",
+ "keywords": [
+ "PHP Depend",
+ "PHP_Depend",
+ "dev",
+ "pdepend"
+ ],
+ "support": {
+ "issues": "https://github.com/pdepend/pdepend/issues",
+ "source": "https://github.com/pdepend/pdepend/tree/2.16.2"
+ },
+ "funding": [
{
- "name": "Nikita Popov"
+ "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend",
+ "type": "tidelift"
}
],
- "description": "A PHP parser written in PHP",
- "keywords": [
- "parser",
- "php"
- ],
- "time": "2019-02-16T20:54:15+00:00"
+ "time": "2023-12-17T18:09:59+00:00"
},
{
"name": "phar-io/manifest",
- "version": "1.0.1",
+ "version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0"
+ "reference": "54750ef60c58e43759730615a392c31c80e23176"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0",
- "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176",
+ "reference": "54750ef60c58e43759730615a392c31c80e23176",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-libxml": "*",
"ext-phar": "*",
- "phar-io/version": "^1.0.1",
- "php": "^5.6 || ^7.0"
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -5703,24 +6816,34 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "time": "2017-03-05T18:14:27+00:00"
+ "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": "1.0.1",
+ "version": "3.2.1",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
- "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df"
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df",
- "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+ "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
@@ -5750,39 +6873,95 @@
}
],
"description": "Library for handling version information and constraints",
- "time": "2017-03-05T17:38:23+00:00"
+ "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": "phpdocumentor/reflection-common",
- "version": "1.0.1",
+ "name": "phpat/phpat",
+ "version": "0.10.18",
"source": {
"type": "git",
- "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
- "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6"
+ "url": "https://github.com/carlosas/phpat.git",
+ "reference": "4c29e330fb306876bca3174aa4b097d0d8611964"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
- "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6",
+ "url": "https://api.github.com/repos/carlosas/phpat/zipball/4c29e330fb306876bca3174aa4b097d0d8611964",
+ "reference": "4c29e330fb306876bca3174aa4b097d0d8611964",
"shasum": ""
},
"require": {
- "php": ">=5.5"
+ "php": "^7.4 || ^8.0",
+ "phpstan/phpstan": "^1.3"
},
"require-dev": {
- "phpunit/phpunit": "^4.6"
+ "friendsofphp/php-cs-fixer": "3.46",
+ "kubawerlos/php-cs-fixer-custom-fixers": "3.18",
+ "phpunit/phpunit": "^9.0 || ^10.0",
+ "vimeo/psalm": "^5.0"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "files": [
+ "helpers.php"
+ ],
+ "psr-4": {
+ "PHPat\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Carlos Alandete Sastre",
+ "email": "carlos.alandete@gmail.com"
+ }
+ ],
+ "description": "PHP Architecture Tester",
+ "support": {
+ "issues": "https://github.com/carlosas/phpat/issues",
+ "source": "https://github.com/carlosas/phpat/tree/0.10.18"
+ },
+ "time": "2024-07-05T14:56:19+00:00"
+ },
+ {
+ "name": "phpdocumentor/reflection-common",
+ "version": "2.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-2.x": "2.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src"
- ]
+ "phpDocumentor\\Reflection\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -5804,44 +6983,53 @@
"reflection",
"static analysis"
],
- "time": "2017-09-11T18:02:19+00:00"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
+ },
+ "time": "2020-06-27T09:03:43+00:00"
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "4.3.0",
+ "version": "5.4.1",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "94fd0001232e47129dd3504189fa1c7225010d08"
+ "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08",
- "reference": "94fd0001232e47129dd3504189fa1c7225010d08",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
+ "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c",
"shasum": ""
},
"require": {
- "php": "^7.0",
- "phpdocumentor/reflection-common": "^1.0.0",
- "phpdocumentor/type-resolver": "^0.4.0",
- "webmozart/assert": "^1.0"
+ "doctrine/deprecations": "^1.1",
+ "ext-filter": "*",
+ "php": "^7.4 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.2",
+ "phpdocumentor/type-resolver": "^1.7",
+ "phpstan/phpdoc-parser": "^1.7",
+ "webmozart/assert": "^1.9.1"
},
"require-dev": {
- "doctrine/instantiator": "~1.0.5",
- "mockery/mockery": "^1.0",
- "phpunit/phpunit": "^6.4"
+ "mockery/mockery": "~1.3.5",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-mockery": "^1.1",
+ "phpstan/phpstan-webmozart-assert": "^1.2",
+ "phpunit/phpunit": "^9.5",
+ "vimeo/psalm": "^5.13"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.x-dev"
+ "dev-master": "5.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -5852,44 +7040,58 @@
{
"name": "Mike van Riel",
"email": "me@mikevanriel.com"
+ },
+ {
+ "name": "Jaap van Otterdijk",
+ "email": "opensource@ijaap.nl"
}
],
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
- "time": "2017-11-30T07:14:17+00:00"
+ "support": {
+ "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1"
+ },
+ "time": "2024-05-21T05:55:05+00:00"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "0.4.0",
+ "version": "1.8.2",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7"
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7",
- "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+ "reference": "153ae662783729388a584b4361f2545e4d841e3c",
"shasum": ""
},
"require": {
- "php": "^5.5 || ^7.0",
- "phpdocumentor/reflection-common": "^1.0"
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.3 || ^8.0",
+ "phpdocumentor/reflection-common": "^2.0",
+ "phpstan/phpdoc-parser": "^1.13"
},
"require-dev": {
- "mockery/mockery": "^0.9.4",
- "phpunit/phpunit": "^5.2||^4.8.24"
+ "ext-tokenizer": "*",
+ "phpbench/phpbench": "^1.2",
+ "phpstan/extension-installer": "^1.1",
+ "phpstan/phpstan": "^1.8",
+ "phpstan/phpstan-phpunit": "^1.1",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^0.13.9",
+ "vimeo/psalm": "^4.25"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-1.x": "1.x-dev"
}
},
"autoload": {
"psr-4": {
- "phpDocumentor\\Reflection\\": [
- "src/"
- ]
+ "phpDocumentor\\Reflection\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -5902,180 +7104,129 @@
"email": "me@mikevanriel.com"
}
],
- "time": "2017-07-14T14:27:02+00:00"
+ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
+ "support": {
+ "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
+ },
+ "time": "2024-02-23T11:10:43+00:00"
},
{
- "name": "phpspec/prophecy",
- "version": "1.8.0",
+ "name": "phpmd/phpmd",
+ "version": "2.15.0",
"source": {
"type": "git",
- "url": "https://github.com/phpspec/prophecy.git",
- "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06"
+ "url": "https://github.com/phpmd/phpmd.git",
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
- "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06",
+ "url": "https://api.github.com/repos/phpmd/phpmd/zipball/74a1f56e33afad4128b886e334093e98e1b5e7c0",
+ "reference": "74a1f56e33afad4128b886e334093e98e1b5e7c0",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.2",
- "php": "^5.3|^7.0",
- "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0",
- "sebastian/comparator": "^1.1|^2.0|^3.0",
- "sebastian/recursion-context": "^1.0|^2.0|^3.0"
+ "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0",
+ "ext-xml": "*",
+ "pdepend/pdepend": "^2.16.1",
+ "php": ">=5.3.9"
},
"require-dev": {
- "phpspec/phpspec": "^2.5|^3.2",
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+ "easy-doc/easy-doc": "0.0.0 || ^1.3.2",
+ "ext-json": "*",
+ "ext-simplexml": "*",
+ "gregwar/rst": "^1.0",
+ "mikey179/vfsstream": "^1.6.8",
+ "squizlabs/php_codesniffer": "^2.9.2 || ^3.7.2"
},
+ "bin": [
+ "src/bin/phpmd"
+ ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.8.x-dev"
- }
- },
"autoload": {
"psr-0": {
- "Prophecy\\": "src/"
+ "PHPMD\\": "src/main/php"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Konstantin Kudryashov",
- "email": "ever.zet@gmail.com",
- "homepage": "http://everzet.com"
+ "name": "Manuel Pichler",
+ "email": "github@manuel-pichler.de",
+ "homepage": "https://github.com/manuelpichler",
+ "role": "Project Founder"
+ },
+ {
+ "name": "Marc WΓΌrth",
+ "email": "ravage@bluewin.ch",
+ "homepage": "https://github.com/ravage84",
+ "role": "Project Maintainer"
},
{
- "name": "Marcello Duarte",
- "email": "marcello.duarte@gmail.com"
+ "name": "Other contributors",
+ "homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
+ "role": "Contributors"
}
],
- "description": "Highly opinionated mocking framework for PHP 5.3+",
- "homepage": "https://github.com/phpspec/prophecy",
+ "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
+ "homepage": "https://phpmd.org/",
"keywords": [
- "Double",
- "Dummy",
- "fake",
- "mock",
- "spy",
- "stub"
+ "dev",
+ "mess detection",
+ "mess detector",
+ "pdepend",
+ "phpmd",
+ "pmd"
],
- "time": "2018-08-05T17:53:17+00:00"
- },
- {
- "name": "phpstan/phpdoc-parser",
- "version": "0.3.1",
- "source": {
- "type": "git",
- "url": "https://github.com/phpstan/phpdoc-parser.git",
- "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/2cc49f47c69b023eaf05b48e6529389893b13d74",
- "reference": "2cc49f47c69b023eaf05b48e6529389893b13d74",
- "shasum": ""
- },
- "require": {
- "php": "~7.1"
- },
- "require-dev": {
- "consistence/coding-standard": "^2.0.0",
- "jakub-onderka/php-parallel-lint": "^0.9.2",
- "phing/phing": "^2.16.0",
- "phpstan/phpstan": "^0.10",
- "phpunit/phpunit": "^6.3",
- "slevomat/coding-standard": "^3.3.0",
- "symfony/process": "^3.4 || ^4.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "0.3-dev"
- }
+ "support": {
+ "irc": "irc://irc.freenode.org/phpmd",
+ "issues": "https://github.com/phpmd/phpmd/issues",
+ "source": "https://github.com/phpmd/phpmd/tree/2.15.0"
},
- "autoload": {
- "psr-4": {
- "PHPStan\\PhpDocParser\\": [
- "src/"
- ]
+ "funding": [
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd",
+ "type": "tidelift"
}
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
],
- "description": "PHPDoc parser with support for nullable, intersection and generic types",
- "time": "2019-01-14T12:26:23+00:00"
+ "time": "2023-12-11T08:22:20+00:00"
},
{
- "name": "phpstan/phpstan",
- "version": "0.10.8",
+ "name": "phpstan/phpdoc-parser",
+ "version": "1.29.1",
"source": {
"type": "git",
- "url": "https://github.com/phpstan/phpstan.git",
- "reference": "4f828460a0276180da76c670a0a6e592e7c38b71"
+ "url": "https://github.com/phpstan/phpdoc-parser.git",
+ "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4f828460a0276180da76c670a0a6e592e7c38b71",
- "reference": "4f828460a0276180da76c670a0a6e592e7c38b71",
+ "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4",
+ "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4",
"shasum": ""
},
"require": {
- "composer/xdebug-handler": "^1.3.0",
- "jean85/pretty-package-versions": "^1.0.3",
- "nette/bootstrap": "^2.4 || ^3.0",
- "nette/di": "^2.4.7 || ^3.0",
- "nette/robot-loader": "^3.0.1",
- "nette/utils": "^2.4.5 || ^3.0",
- "nikic/php-parser": "^4.0.2",
- "php": "~7.1",
- "phpstan/phpdoc-parser": "^0.3",
- "symfony/console": "~3.2 || ~4.0",
- "symfony/finder": "~3.2 || ~4.0"
- },
- "conflict": {
- "symfony/console": "3.4.16 || 4.1.5"
+ "php": "^7.2 || ^8.0"
},
"require-dev": {
- "brianium/paratest": "^2.0",
- "consistence/coding-standard": "^3.5",
- "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
- "ext-gd": "*",
- "ext-intl": "*",
- "ext-mysqli": "*",
- "ext-zip": "*",
- "jakub-onderka/php-parallel-lint": "^1.0",
- "localheinz/composer-normalize": "~0.9.0",
- "phing/phing": "^2.16.0",
- "phpstan/phpstan-deprecation-rules": "^0.10.2",
- "phpstan/phpstan-php-parser": "^0.10",
- "phpstan/phpstan-phpunit": "^0.10",
- "phpstan/phpstan-strict-rules": "^0.10",
- "phpunit/phpunit": "^7.0",
- "slevomat/coding-standard": "^4.7.2",
- "squizlabs/php_codesniffer": "^3.3.2"
+ "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"
},
- "bin": [
- "bin/phpstan"
- ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "0.10-dev"
- }
- },
"autoload": {
"psr-4": {
- "PHPStan\\": [
- "src/",
- "build/PHPStan"
+ "PHPStan\\PhpDocParser\\": [
+ "src/"
]
}
},
@@ -6083,94 +7234,111 @@
"license": [
"MIT"
],
- "description": "PHPStan - PHP Static Analysis Tool",
- "time": "2019-01-08T09:51:19+00:00"
+ "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.29.1"
+ },
+ "time": "2024-05-31T08:52:43+00:00"
},
{
- "name": "phpstan/phpstan-mockery",
- "version": "0.10.2",
+ "name": "phpstan/phpstan",
+ "version": "1.11.9",
"source": {
"type": "git",
- "url": "https://github.com/phpstan/phpstan-mockery.git",
- "reference": "14d568b6b56c957c9ae5330603303a367b21f0e9"
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "e370bcddadaede0c1716338b262346f40d296f82"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan-mockery/zipball/14d568b6b56c957c9ae5330603303a367b21f0e9",
- "reference": "14d568b6b56c957c9ae5330603303a367b21f0e9",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e370bcddadaede0c1716338b262346f40d296f82",
+ "reference": "e370bcddadaede0c1716338b262346f40d296f82",
"shasum": ""
},
"require": {
- "nikic/php-parser": "^4.0",
- "php": "~7.1",
- "phpstan/phpdoc-parser": "^0.3",
- "phpstan/phpstan": "^0.10.3"
+ "php": "^7.2|^8.0"
},
- "require-dev": {
- "consistence/coding-standard": "^3.0.1",
- "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4",
- "jakub-onderka/php-parallel-lint": "^1.0",
- "mockery/mockery": "^1.1",
- "phing/phing": "^2.16.0",
- "phpstan/phpstan-phpunit": "^0.10",
- "phpstan/phpstan-strict-rules": "^0.10",
- "phpunit/phpunit": "^7.2",
- "slevomat/coding-standard": "^4.6.3"
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
},
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "0.10-dev"
- }
- },
"autoload": {
- "psr-4": {
- "PHPStan\\": "src/"
- }
+ "files": [
+ "bootstrap.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "PHPStan Mockery extension",
- "time": "2018-09-09T15:22:28+00:00"
+ "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": "2024-08-01T16:25:18+00:00"
},
{
"name": "phpunit/php-code-coverage",
- "version": "5.3.2",
+ "version": "9.2.31",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "c89677919c5dd6d3b3852f230a663118762218ac"
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac",
- "reference": "c89677919c5dd6d3b3852f230a663118762218ac",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965",
+ "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965",
"shasum": ""
},
"require": {
"ext-dom": "*",
+ "ext-libxml": "*",
"ext-xmlwriter": "*",
- "php": "^7.0",
- "phpunit/php-file-iterator": "^1.4.2",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^2.0.1",
- "sebastian/code-unit-reverse-lookup": "^1.0.1",
- "sebastian/environment": "^3.0",
- "sebastian/version": "^2.0.1",
- "theseer/tokenizer": "^1.1"
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3",
+ "phpunit/php-file-iterator": "^3.0.3",
+ "phpunit/php-text-template": "^2.0.2",
+ "sebastian/code-unit-reverse-lookup": "^2.0.2",
+ "sebastian/complexity": "^2.0",
+ "sebastian/environment": "^5.1.2",
+ "sebastian/lines-of-code": "^1.0.3",
+ "sebastian/version": "^3.0.1",
+ "theseer/tokenizer": "^1.2.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^9.3"
},
"suggest": {
- "ext-xdebug": "^2.5.5"
+ "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-master": "5.3.x-dev"
+ "dev-master": "9.2-dev"
}
},
"autoload": {
@@ -6196,29 +7364,43 @@
"testing",
"xunit"
],
- "time": "2018-04-06T15:36:58+00:00"
+ "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/9.2.31"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:37:42+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "1.4.5",
+ "version": "3.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4"
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4",
- "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+ "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.4.x-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
@@ -6233,7 +7415,7 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
@@ -6243,26 +7425,48 @@
"filesystem",
"iterator"
],
- "time": "2017-11-27T13:52:08+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-02T12:48:52+00:00"
},
{
- "name": "phpunit/php-text-template",
- "version": "1.2.1",
+ "name": "phpunit/php-invoker",
+ "version": "3.1.1",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/php-text-template.git",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ "url": "https://github.com/sebastianbergmann/php-invoker.git",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
- "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+ "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "ext-pcntl": "*",
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-pcntl": "*"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.1-dev"
+ }
+ },
"autoload": {
"classmap": [
"src/"
@@ -6279,37 +7483,47 @@
"role": "lead"
}
],
- "description": "Simple template engine.",
- "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "description": "Invoke callables with a timeout",
+ "homepage": "https://github.com/sebastianbergmann/php-invoker/",
"keywords": [
- "template"
+ "process"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+ "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2015-06-21T13:50:34+00:00"
+ "time": "2020-09-28T05:58:55+00:00"
},
{
- "name": "phpunit/php-timer",
- "version": "1.0.9",
+ "name": "phpunit/php-text-template",
+ "version": "2.0.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f"
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
- "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+ "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -6324,42 +7538,51 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sb@sebastian-bergmann.de",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
- "description": "Utility class for timing",
- "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
"keywords": [
- "timer"
+ "template"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2017-02-26T11:10:40+00:00"
+ "time": "2020-10-26T05:33:50+00:00"
},
{
- "name": "phpunit/php-token-stream",
- "version": "2.0.2",
+ "name": "phpunit/php-timer",
+ "version": "5.0.3",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "791198a2c6254db10131eecfe8c06670700904db"
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db",
- "reference": "791198a2c6254db10131eecfe8c06670700904db",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+ "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
"shasum": ""
},
"require": {
- "ext-tokenizer": "*",
- "php": "^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^6.2.4"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -6374,65 +7597,73 @@
"authors": [
{
"name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Wrapper around PHP's tokenizer extension.",
- "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
"keywords": [
- "tokenizer"
+ "timer"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2017-11-27T05:48:46+00:00"
+ "time": "2020-10-26T13:16:10+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "6.5.14",
+ "version": "9.6.20",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7"
+ "reference": "49d7820565836236411f5dc002d16dd689cde42f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bac23fe7ff13dbdb461481f706f0e9fe746334b7",
- "reference": "bac23fe7ff13dbdb461481f706f0e9fe746334b7",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/49d7820565836236411f5dc002d16dd689cde42f",
+ "reference": "49d7820565836236411f5dc002d16dd689cde42f",
"shasum": ""
},
"require": {
+ "doctrine/instantiator": "^1.5.0 || ^2",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
- "myclabs/deep-copy": "^1.6.1",
- "phar-io/manifest": "^1.0.1",
- "phar-io/version": "^1.0",
- "php": "^7.0",
- "phpspec/prophecy": "^1.7",
- "phpunit/php-code-coverage": "^5.3",
- "phpunit/php-file-iterator": "^1.4.3",
- "phpunit/php-text-template": "^1.2.1",
- "phpunit/php-timer": "^1.0.9",
- "phpunit/phpunit-mock-objects": "^5.0.9",
- "sebastian/comparator": "^2.1",
- "sebastian/diff": "^2.0",
- "sebastian/environment": "^3.1",
- "sebastian/exporter": "^3.1",
- "sebastian/global-state": "^2.0",
- "sebastian/object-enumerator": "^3.0.3",
- "sebastian/resource-operations": "^1.0",
- "sebastian/version": "^2.0.1"
- },
- "conflict": {
- "phpdocumentor/reflection-docblock": "3.0.2",
- "phpunit/dbunit": "<3.0"
- },
- "require-dev": {
- "ext-pdo": "*"
+ "ext-xmlwriter": "*",
+ "myclabs/deep-copy": "^1.12.0",
+ "phar-io/manifest": "^2.0.4",
+ "phar-io/version": "^3.2.1",
+ "php": ">=7.3",
+ "phpunit/php-code-coverage": "^9.2.31",
+ "phpunit/php-file-iterator": "^3.0.6",
+ "phpunit/php-invoker": "^3.1.1",
+ "phpunit/php-text-template": "^2.0.4",
+ "phpunit/php-timer": "^5.0.3",
+ "sebastian/cli-parser": "^1.0.2",
+ "sebastian/code-unit": "^1.0.8",
+ "sebastian/comparator": "^4.0.8",
+ "sebastian/diff": "^4.0.6",
+ "sebastian/environment": "^5.1.5",
+ "sebastian/exporter": "^4.0.6",
+ "sebastian/global-state": "^5.0.7",
+ "sebastian/object-enumerator": "^4.0.4",
+ "sebastian/resource-operations": "^3.0.4",
+ "sebastian/type": "^3.2.1",
+ "sebastian/version": "^3.0.2"
},
"suggest": {
- "ext-xdebug": "*",
- "phpunit/php-invoker": "^1.1"
+ "ext-soap": "To be able to generate mocks based on WSDL files",
+ "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
},
"bin": [
"phpunit"
@@ -6440,10 +7671,13 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "6.5.x-dev"
+ "dev-master": "9.6-dev"
}
},
"autoload": {
+ "files": [
+ "src/Framework/Assert/Functions.php"
+ ],
"classmap": [
"src/"
]
@@ -6466,286 +7700,1215 @@
"testing",
"xunit"
],
- "time": "2019-02-01T05:22:47+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.20"
+ },
+ "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": "2024-07-10T11:45:39+00:00"
+ },
+ {
+ "name": "psalm/plugin-mockery",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/psalm/psalm-plugin-mockery.git",
+ "reference": "876247d15f91df08240d00dac69c5135b6689283"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/psalm/psalm-plugin-mockery/zipball/876247d15f91df08240d00dac69c5135b6689283",
+ "reference": "876247d15f91df08240d00dac69c5135b6689283",
+ "shasum": ""
+ },
+ "require": {
+ "composer/package-versions-deprecated": "^1.10",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
+ "mockery/mockery": "^1.0",
+ "php": "~7.4 || ~8.0 || ~8.1 || ~8.2",
+ "vimeo/psalm": "dev-master || ^5.0@rc || ^5.0"
+ },
+ "require-dev": {
+ "codeception/codeception": "^4.1.9",
+ "phpunit/phpunit": "^9.0",
+ "squizlabs/php_codesniffer": "^3.3.1",
+ "weirdan/codeception-psalm-module": "^0.13.1"
+ },
+ "type": "psalm-plugin",
+ "extra": {
+ "psalm": {
+ "pluginClass": "Psalm\\MockeryPlugin\\Plugin"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psalm\\MockeryPlugin\\": [
+ "."
+ ]
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matt Brown",
+ "email": "github@muglug.com"
+ }
+ ],
+ "description": "Psalm plugin for Mockery",
+ "support": {
+ "issues": "https://github.com/psalm/psalm-plugin-mockery/issues",
+ "source": "https://github.com/psalm/psalm-plugin-mockery/tree/1.1.0"
+ },
+ "time": "2022-11-25T07:16:18+00:00"
},
{
- "name": "phpunit/phpunit-mock-objects",
- "version": "5.0.10",
+ "name": "psalm/plugin-phpunit",
+ "version": "0.18.4",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
- "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f"
+ "url": "https://github.com/psalm/psalm-plugin-phpunit.git",
+ "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/cd1cf05c553ecfec36b170070573e540b67d3f1f",
- "reference": "cd1cf05c553ecfec36b170070573e540b67d3f1f",
+ "url": "https://api.github.com/repos/psalm/psalm-plugin-phpunit/zipball/e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc",
+ "reference": "e4ab3096653d9eb6f6d0ea5f4461898d59ae4dbc",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.0.5",
- "php": "^7.0",
- "phpunit/php-text-template": "^1.2.1",
- "sebastian/exporter": "^3.1"
+ "composer/package-versions-deprecated": "^1.10",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
+ "ext-simplexml": "*",
+ "php": "^7.1 || ^8.0",
+ "vimeo/psalm": "dev-master || dev-4.x || ^4.7.1 || ^5@beta || ^5.0"
},
"conflict": {
- "phpunit/phpunit": "<6.0"
+ "phpunit/phpunit": "<7.5"
+ },
+ "require-dev": {
+ "codeception/codeception": "^4.0.3",
+ "php": "^7.3 || ^8.0",
+ "phpunit/phpunit": "^7.5 || ^8.0 || ^9.0",
+ "squizlabs/php_codesniffer": "^3.3.1",
+ "weirdan/codeception-psalm-module": "^0.11.0",
+ "weirdan/prophecy-shim": "^1.0 || ^2.0"
+ },
+ "type": "psalm-plugin",
+ "extra": {
+ "psalm": {
+ "pluginClass": "Psalm\\PhpUnitPlugin\\Plugin"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psalm\\PhpUnitPlugin\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Matt Brown",
+ "email": "github@muglug.com"
+ }
+ ],
+ "description": "Psalm plugin for PHPUnit",
+ "support": {
+ "issues": "https://github.com/psalm/psalm-plugin-phpunit/issues",
+ "source": "https://github.com/psalm/psalm-plugin-phpunit/tree/0.18.4"
+ },
+ "time": "2022-12-03T07:47:07+00:00"
+ },
+ {
+ "name": "psalm/plugin-symfony",
+ "version": "v5.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/psalm/psalm-plugin-symfony.git",
+ "reference": "fb801a9b3d12ace9fb619febfaa3ae0bc1dbb196"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/psalm/psalm-plugin-symfony/zipball/fb801a9b3d12ace9fb619febfaa3ae0bc1dbb196",
+ "reference": "fb801a9b3d12ace9fb619febfaa3ae0bc1dbb196",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "php": "^8.1",
+ "symfony/framework-bundle": "^5.0 || ^6.0 || ^7.0",
+ "vimeo/psalm": "^5.16"
},
"require-dev": {
- "phpunit/phpunit": "^6.5.11"
+ "doctrine/annotations": "^1.8|^2",
+ "doctrine/orm": "^2.9",
+ "phpunit/phpunit": "~7.5 || ~9.5",
+ "symfony/cache-contracts": "^1.0 || ^2.0",
+ "symfony/console": "*",
+ "symfony/form": "^5.0 || ^6.0 || ^7.0",
+ "symfony/messenger": "^5.0 || ^6.0 || ^7.0",
+ "symfony/security-core": "*",
+ "symfony/serializer": "^5.0 || ^6.0 || ^7.0",
+ "symfony/validator": "*",
+ "twig/twig": "^2.10 || ^3.0",
+ "weirdan/codeception-psalm-module": "dev-master"
},
"suggest": {
- "ext-soap": "*"
+ "weirdan/doctrine-psalm-plugin": "If Doctrine is used, it is recommended install this plugin"
},
- "type": "library",
+ "type": "psalm-plugin",
"extra": {
- "branch-alias": {
- "dev-master": "5.0.x-dev"
+ "psalm": {
+ "pluginClass": "Psalm\\SymfonyPsalmPlugin\\Plugin"
}
},
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-4": {
+ "Psalm\\SymfonyPsalmPlugin\\": "src"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de",
- "role": "lead"
+ "name": "Farhad Safarov",
+ "email": "farhad.safarov@gmail.com"
}
],
- "description": "Mock Object library for PHPUnit",
- "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "description": "Psalm Plugin for Symfony",
+ "support": {
+ "issues": "https://github.com/psalm/psalm-plugin-symfony/issues",
+ "source": "https://github.com/psalm/psalm-plugin-symfony/tree/v5.2.5"
+ },
+ "time": "2024-07-03T11:57:02+00:00"
+ },
+ {
+ "name": "rector/rector",
+ "version": "0.18.13",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rectorphp/rector.git",
+ "reference": "f8011a76d36aa4f839f60f3b4f97707d97176618"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rectorphp/rector/zipball/f8011a76d36aa4f839f60f3b4f97707d97176618",
+ "reference": "f8011a76d36aa4f839f60f3b4f97707d97176618",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.2|^8.0",
+ "phpstan/phpstan": "^1.10.35"
+ },
+ "conflict": {
+ "rector/rector-doctrine": "*",
+ "rector/rector-downgrade-php": "*",
+ "rector/rector-phpunit": "*",
+ "rector/rector-symfony": "*"
+ },
+ "bin": [
+ "bin/rector"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "Instant Upgrade and Automated Refactoring of any PHP code",
"keywords": [
- "mock",
- "xunit"
+ "automation",
+ "dev",
+ "migration",
+ "refactoring"
],
- "abandoned": true,
- "time": "2018-08-09T05:50:03+00:00"
+ "support": {
+ "issues": "https://github.com/rectorphp/rector/issues",
+ "source": "https://github.com/rectorphp/rector/tree/0.18.13"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/tomasvotruba",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-20T16:08:01+00:00"
},
{
"name": "roave/security-advisories",
"version": "dev-master",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Roave/SecurityAdvisories.git",
+ "reference": "ff7456939acba6dd515a8a10aad66be6bc1b8dc1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/ff7456939acba6dd515a8a10aad66be6bc1b8dc1",
+ "reference": "ff7456939acba6dd515a8a10aad66be6bc1b8dc1",
+ "shasum": ""
+ },
"conflict": {
"3f/pygmentize": "<1.2",
- "adodb/adodb-php": "<5.20.12",
+ "admidio/admidio": "<4.3.10",
+ "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3",
+ "aheinze/cockpit": "<2.2",
+ "aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.04.6",
+ "aimeos/ai-admin-jsonadm": "<2020.10.13|>=2021.04.1,<2021.10.6|>=2022.04.1,<2022.10.3|>=2023.04.1,<2023.10.4|==2024.04.1",
+ "aimeos/ai-client-html": ">=2020.04.1,<2020.10.27|>=2021.04.1,<2021.10.22|>=2022.04.1,<2022.10.13|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.04.7",
+ "aimeos/ai-controller-frontend": "<2020.10.15|>=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.8|>=2023.04.1,<2023.10.9",
+ "aimeos/aimeos-core": ">=2022.04.1,<2022.10.17|>=2023.04.1,<2023.10.17|>=2024.04.1,<2024.04.7",
+ "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5",
+ "airesvsg/acf-to-rest-api": "<=3.1",
+ "akaunting/akaunting": "<2.1.13",
+ "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53",
+ "alextselegidis/easyappointments": "<1.5",
"alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1",
+ "amazing/media2click": ">=1,<1.3.3",
"amphp/artax": "<1.0.6|>=2,<2.0.6",
- "amphp/http": "<1.0.1",
- "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6",
- "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
- "aws/aws-sdk-php": ">=3,<3.2.1",
+ "amphp/http": "<=1.7.2|>=2,<=2.1",
+ "amphp/http-client": ">=4,<4.4",
+ "anchorcms/anchor-cms": "<=0.12.7",
+ "andreapollastri/cipi": "<=3.1.15",
+ "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5",
+ "apache-solr-for-typo3/solr": "<2.8.3",
+ "apereo/phpcas": "<1.6",
+ "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6|>=2.6,<2.7.10|>=3,<3.0.12|>=3.1,<3.1.3",
+ "appwrite/server-ce": "<=1.2.1",
+ "arc/web": "<3",
+ "area17/twill": "<1.2.5|>=2,<2.5.3",
+ "artesaos/seotools": "<0.17.2",
+ "asymmetricrypt/asymmetricrypt": "<9.9.99",
+ "athlon1600/php-proxy": "<=5.1",
+ "athlon1600/php-proxy-app": "<=3",
+ "austintoddj/canvas": "<=3.4.2",
+ "auth0/wordpress": "<=4.6",
+ "automad/automad": "<=2.0.0.0-alpha5",
+ "automattic/jetpack": "<9.8",
+ "awesome-support/awesome-support": "<=6.0.7",
+ "aws/aws-sdk-php": "<3.288.1",
+ "azuracast/azuracast": "<0.18.3",
+ "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2",
+ "backpack/crud": "<3.4.9",
+ "bacula-web/bacula-web": "<8.0.0.0-RC2-dev",
+ "badaso/core": "<2.7",
+ "bagisto/bagisto": "<2.1",
+ "barrelstrength/sprout-base-email": "<1.2.7",
+ "barrelstrength/sprout-forms": "<3.9",
+ "barryvdh/laravel-translation-manager": "<0.6.2",
+ "barzahlen/barzahlen-php": "<2.0.1",
+ "baserproject/basercms": "<5.0.9",
+ "bassjobsen/bootstrap-3-typeahead": ">4.0.2",
+ "bbpress/bbpress": "<2.6.5",
+ "bcosca/fatfree": "<3.7.2",
+ "bedita/bedita": "<4",
+ "bigfork/silverstripe-form-capture": ">=3,<3.1.1",
+ "billz/raspap-webgui": "<=3.1.4",
+ "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3",
+ "blueimp/jquery-file-upload": "==6.4.4",
+ "bmarshall511/wordpress_zero_spam": "<5.2.13",
+ "bolt/bolt": "<3.7.2",
+ "bolt/core": "<=4.2",
+ "born05/craft-twofactorauthentication": "<3.3.4",
+ "bottelet/flarepoint": "<2.2.1",
+ "bref/bref": "<2.1.17",
"brightlocal/phpwhois": "<=4.2.5",
+ "brotkrueml/codehighlight": "<2.7",
+ "brotkrueml/schema": "<1.13.1|>=2,<2.5.1",
+ "brotkrueml/typo3-matomo-integration": "<1.3.2",
+ "buddypress/buddypress": "<7.2.1",
"bugsnag/bugsnag-laravel": ">=2,<2.0.2",
- "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4",
+ "bytefury/crater": "<6.0.2",
+ "cachethq/cachet": "<2.5.1",
+ "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
+ "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10",
+ "cardgate/magento2": "<2.0.33",
+ "cardgate/woocommerce": "<=3.1.15",
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
+ "cart2quote/module-quotation-encoded": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
"cartalyst/sentry": "<=2.1.6",
- "codeigniter/framework": "<=3.0.6",
- "composer/composer": "<=1.0.0-alpha11",
+ "catfan/medoo": "<1.7.5",
+ "causal/oidc": "<2.1",
+ "cecil/cecil": "<7.47.1",
+ "centreon/centreon": "<22.10.15",
+ "cesnet/simplesamlphp-module-proxystatistics": "<3.1",
+ "chriskacerguis/codeigniter-restserver": "<=2.7.1",
+ "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3",
+ "ckeditor/ckeditor": "<4.24",
+ "cockpit-hq/cockpit": "<2.7|==2.7",
+ "codeception/codeception": "<3.1.3|>=4,<4.1.22",
+ "codeigniter/framework": "<3.1.9",
+ "codeigniter4/framework": "<4.4.7",
+ "codeigniter4/shield": "<1.0.0.0-beta8",
+ "codiad/codiad": "<=2.8.4",
+ "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7",
+ "concrete5/concrete5": "<=9.3.2",
+ "concrete5/core": "<8.5.8|>=9,<9.1",
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
- "contao/core": ">=2,<3.5.35",
- "contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8",
- "contao/listing-bundle": ">=4,<4.4.8",
- "contao/newsletter-bundle": ">=4,<4.1",
+ "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
+ "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.9.40|>=4.10,<4.11.7|>=4.13,<4.13.21|>=5.1,<5.1.4",
+ "contao/core": "<3.5.39",
+ "contao/core-bundle": "<4.13.40|>=5,<5.3.4",
+ "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8",
+ "contao/managed-edition": "<=1.5",
+ "corveda/phpsandbox": "<1.3.5",
+ "cosenary/instagram": "<=2.3",
+ "craftcms/cms": "<4.6.2|>=5.0.0.0-beta1,<=5.2.2",
+ "croogo/croogo": "<4",
+ "cuyz/valinor": "<0.12",
+ "czproject/git-php": "<4.0.3",
+ "dapphp/securimage": "<3.6.6",
+ "darylldoyle/safe-svg": "<1.9.10",
+ "datadog/dd-trace": ">=0.30,<0.30.2",
+ "datatables/datatables": "<1.10.10",
"david-garcia/phpwhois": "<=4.3.1",
- "doctrine/annotations": ">=1,<1.2.7",
+ "dbrisinajumi/d2files": "<1",
+ "dcat/laravel-admin": "<=2.1.3.0-beta",
+ "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3",
+ "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4",
+ "desperado/xml-bundle": "<=0.1.7",
+ "devgroup/dotplant": "<2020.09.14-dev",
+ "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
+ "doctrine/annotations": "<1.2.7",
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
- "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
- "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2",
+ "doctrine/common": "<2.4.3|>=2.5,<2.5.1",
+ "doctrine/dbal": ">=2,<2.0.8|>=2.1,<2.1.2|>=3,<3.1.4",
"doctrine/doctrine-bundle": "<1.5.2",
- "doctrine/doctrine-module": "<=0.7.1",
- "doctrine/mongodb-odm": ">=1,<1.0.2",
- "doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
- "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1",
- "dompdf/dompdf": ">=0.6,<0.6.2",
- "drupal/core": ">=7,<7.64|>=8,<8.5.13|>=8.6,<8.6.12",
- "drupal/drupal": ">=7,<7.64|>=8,<8.5.13|>=8.6,<8.6.12",
+ "doctrine/doctrine-module": "<0.7.2",
+ "doctrine/mongodb-odm": "<1.0.2",
+ "doctrine/mongodb-odm-bundle": "<3.0.1",
+ "doctrine/orm": ">=1,<1.2.4|>=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4",
+ "dolibarr/dolibarr": "<19.0.2",
+ "dompdf/dompdf": "<2.0.4",
+ "doublethreedigital/guest-entries": "<3.1.2",
+ "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.1.8|>=10.2,<10.2.2",
+ "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<8.9.16|>=9,<9.1.12|>=9.2,<9.2.4",
+ "duncanmcclean/guest-entries": "<3.1.2",
+ "dweeves/magmi": "<=0.7.24",
+ "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2",
+ "ecodev/newsletter": "<=4",
+ "ectouch/ectouch": "<=2.7.2",
+ "egroupware/egroupware": "<23.1.20240624",
+ "elefant/cms": "<2.0.7",
+ "elgg/elgg": "<3.3.24|>=4,<4.0.5",
+ "elijaa/phpmemcacheadmin": "<=1.3",
+ "encore/laravel-admin": "<=1.8.19",
+ "endroid/qr-code-bundle": "<3.4.2",
+ "enhavo/enhavo-app": "<=0.13.1",
+ "enshrined/svg-sanitize": "<0.15",
"erusev/parsedown": "<1.7.2",
- "ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1",
- "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3",
- "ezsystems/repository-forms": ">=2.3,<2.3.2.1",
+ "ether/logs": "<3.0.4",
+ "evolutioncms/evolution": "<=3.2.3",
+ "exceedone/exment": "<4.4.3|>=5,<5.0.3",
+ "exceedone/laravel-admin": "<2.2.3|==3",
+ "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev",
+ "ezsystems/ez-support-tools": ">=2.2,<2.2.3",
+ "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev",
+ "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev",
+ "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24",
+ "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26|>=3.3,<3.3.39",
+ "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1",
+ "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12",
+ "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35",
+ "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8",
+ "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev",
+ "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15",
+ "ezsystems/ezplatform-user": ">=1,<1.0.1",
+ "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31",
+ "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1",
+ "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3",
+ "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15",
"ezyang/htmlpurifier": "<4.1.1",
- "firebase/php-jwt": "<2",
+ "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2",
+ "facturascripts/facturascripts": "<=2022.08",
+ "fastly/magento2": "<1.2.26",
+ "feehi/cms": "<=2.1.1",
+ "feehi/feehicms": "<=2.1.1",
+ "fenom/fenom": "<=2.12.1",
+ "filegator/filegator": "<7.8",
+ "filp/whoops": "<2.1.13",
+ "fineuploader/php-traditional-server": "<=1.2.2",
+ "firebase/php-jwt": "<6",
+ "fisharebest/webtrees": "<=2.1.18",
+ "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2",
+ "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6",
+ "flarum/core": "<1.8.5",
+ "flarum/flarum": "<0.1.0.0-beta8",
+ "flarum/framework": "<1.8.5",
+ "flarum/mentions": "<1.6.3",
+ "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15",
+ "flarum/tags": "<=0.1.0.0-beta13",
+ "floriangaerber/magnesium": "<0.3.1",
+ "fluidtypo3/vhs": "<5.1.1",
+ "fof/byobu": ">=0.3.0.0-beta2,<1.1.7",
+ "fof/upload": "<1.2.3",
+ "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1",
"fooman/tcpdf": "<6.2.22",
+ "forkcms/forkcms": "<5.11.1",
"fossar/tcpdf-parser": "<6.2.22",
+ "francoisjacquet/rosariosis": "<=11.5.1",
+ "frappant/frp-form-answers": "<3.1.2|>=4,<4.0.2",
+ "friendsofsymfony/oauth2-php": "<1.3",
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
- "friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
+ "friendsofsymfony/user-bundle": ">=1,<1.3.5",
+ "friendsofsymfony1/swiftmailer": ">=4,<5.4.13|>=6,<6.2.5",
+ "friendsofsymfony1/symfony1": ">=1.1,<1.5.19",
+ "friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
+ "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
+ "froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3",
+ "froxlor/froxlor": "<2.1.9",
+ "frozennode/administrator": "<=5.0.12",
"fuel/core": "<1.8.1",
- "gree/jose": "<=2.2",
+ "funadmin/funadmin": "<=3.2|>=3.3.2,<=3.3.3",
+ "gaoming13/wechat-php-sdk": "<=1.10.2",
+ "genix/cms": "<=1.1.11",
+ "getformwork/formwork": "<1.13.1|==2.0.0.0-beta1",
+ "getgrav/grav": "<1.7.46",
+ "getkirby/cms": "<4.1.1",
+ "getkirby/kirby": "<=2.5.12",
+ "getkirby/panel": "<2.5.14",
+ "getkirby/starterkit": "<=3.7.0.2",
+ "gilacms/gila": "<=1.15.4",
+ "gleez/cms": "<=1.3|==2",
+ "globalpayments/php-sdk": "<2",
+ "gogentooss/samlbase": "<1.2.7",
+ "google/protobuf": "<3.15",
+ "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3",
+ "gree/jose": "<2.2.1",
"gregwar/rst": "<1.0.3",
- "guzzlehttp/guzzle": ">=6,<6.2.1|>=4.0.0-rc2,<4.2.4|>=5,<5.3.1",
- "illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10",
- "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
- "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29",
+ "grumpydictator/firefly-iii": "<6.1.17",
+ "gugoan/economizzer": "<=0.9.0.0-beta1",
+ "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5",
+ "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5",
+ "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2",
+ "harvesthq/chosen": "<1.8.7",
+ "helloxz/imgurl": "<=2.31",
+ "hhxsv5/laravel-s": "<3.7.36",
+ "hillelcoren/invoice-ninja": "<5.3.35",
+ "himiklab/yii2-jqgrid-widget": "<1.0.8",
+ "hjue/justwriting": "<=1",
+ "hov/jobfair": "<1.0.13|>=2,<2.0.2",
+ "httpsoft/http-message": "<1.0.12",
+ "hyn/multi-tenant": ">=5.6,<5.7.2",
+ "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6.0.0-beta1,<4.6.9",
+ "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2",
+ "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3",
+ "ibexa/post-install": "<=1.0.4",
+ "ibexa/solr": ">=4.5,<4.5.4",
+ "ibexa/user": ">=4,<4.4.3",
+ "icecoder/icecoder": "<=8.1",
+ "idno/known": "<=1.3.1",
+ "ilicmiljan/secure-props": ">=1.2,<1.2.2",
+ "illuminate/auth": "<5.5.10",
+ "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4",
+ "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40",
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
+ "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75",
+ "imdbphp/imdbphp": "<=5.1.1",
+ "impresscms/impresscms": "<=1.4.5",
+ "impresspages/impresspages": "<=1.0.12",
+ "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3",
+ "in2code/ipandlanguageredirect": "<5.1.2",
+ "in2code/lux": "<17.6.1|>=18,<24.0.2",
+ "innologi/typo3-appointments": "<2.0.6",
+ "intelliants/subrion": "<4.2.2",
+ "inter-mediator/inter-mediator": "==5.5",
+ "ipl/web": "<0.10.1",
+ "islandora/islandora": ">=2,<2.4.1",
"ivankristianto/phpwhois": "<=4.3",
- "james-heinrich/getid3": "<1.9.9",
+ "jackalope/jackalope-doctrine-dbal": "<1.7.4",
+ "james-heinrich/getid3": "<1.9.21",
+ "james-heinrich/phpthumb": "<1.7.12",
+ "jasig/phpcas": "<1.3.3",
+ "jcbrand/converse.js": "<3.3.3",
+ "johnbillion/wp-crontrol": "<1.16.2",
+ "joomla/application": "<1.0.13",
+ "joomla/archive": "<1.1.12|>=2,<2.0.1",
+ "joomla/filesystem": "<1.6.2|>=2,<2.0.1",
+ "joomla/filter": "<1.4.4|>=2,<2.0.1",
+ "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12",
+ "joomla/input": ">=2,<2.0.2",
+ "joomla/joomla-cms": ">=2.5,<3.9.12",
"joomla/session": "<1.3.1",
+ "joyqi/hyper-down": "<=2.4.27",
+ "jsdecena/laracom": "<2.0.9",
"jsmitty12/phpwhois": "<5.1",
+ "juzaweb/cms": "<=3.4",
+ "jweiland/events2": "<8.3.8|>=9,<9.0.6",
"kazist/phpwhois": "<=4.2.6",
+ "kelvinmo/simplexrd": "<3.1.1",
+ "kevinpapst/kimai2": "<1.16.7",
+ "khodakhah/nodcms": "<=3",
+ "kimai/kimai": "<2.16",
+ "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4",
+ "klaviyo/magento2-extension": ">=1,<3",
+ "knplabs/knp-snappy": "<=1.4.2",
+ "kohana/core": "<3.3.3",
+ "krayin/laravel-crm": "<1.2.2",
"kreait/firebase-php": ">=3.2,<3.8.1",
+ "kumbiaphp/kumbiapp": "<=1.1.1",
"la-haute-societe/tcpdf": "<6.2.22",
- "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
- "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
+ "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2",
+ "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1",
+ "laminas/laminas-http": "<2.14.2",
+ "laravel/fortify": "<1.11.1",
+ "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75",
+ "laravel/laravel": ">=5.4,<5.4.22",
+ "laravel/socialite": ">=1,<2.0.10",
+ "latte/latte": "<2.10.8",
+ "lavalite/cms": "<=9|==10.1",
+ "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5",
"league/commonmark": "<0.18.3",
- "magento/magento1ce": "<1.9.4",
- "magento/magento1ee": ">=1.9,<1.14.4",
- "magento/product-community-edition": ">=2,<2.2.7",
+ "league/flysystem": "<1.1.4|>=2,<2.1.1",
+ "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3",
+ "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3",
+ "libreform/libreform": ">=2,<=2.0.8",
+ "librenms/librenms": "<2017.08.18",
+ "liftkit/database": "<2.13.2",
+ "lightsaml/lightsaml": "<1.3.5",
+ "limesurvey/limesurvey": "<3.27.19",
+ "livehelperchat/livehelperchat": "<=3.91",
+ "livewire/livewire": ">2.2.4,<2.2.6|>=3.3.5,<3.4.9",
+ "lms/routes": "<2.1.1",
+ "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2",
+ "luyadev/yii-helpers": "<1.2.1",
+ "magento/community-edition": "<2.4.5|==2.4.5|>=2.4.5.0-patch1,<2.4.5.0-patch8|==2.4.6|>=2.4.6.0-patch1,<2.4.6.0-patch6|==2.4.7",
+ "magento/core": "<=1.9.4.5",
+ "magento/magento1ce": "<1.9.4.3-dev",
+ "magento/magento1ee": ">=1,<1.14.4.3-dev",
+ "magento/product-community-edition": "<2.4.4.0-patch9|>=2.4.5,<2.4.5.0-patch8|>=2.4.6,<2.4.6.0-patch6|>=2.4.7,<2.4.7.0-patch1",
+ "magneto/core": "<1.9.4.4-dev",
+ "maikuolan/phpmussel": ">=1,<1.6",
+ "mainwp/mainwp": "<=4.4.3.3",
+ "mantisbt/mantisbt": "<2.26.2",
+ "marcwillmann/turn": "<0.3.3",
+ "matyhtf/framework": "<3.0.6",
+ "mautic/core": "<4.4.12|>=5.0.0.0-alpha,<5.0.4",
+ "mdanter/ecc": "<2",
+ "mediawiki/core": "<1.36.2",
+ "mediawiki/matomo": "<2.4.3",
+ "mediawiki/semantic-media-wiki": "<4.0.2",
+ "melisplatform/melis-asset-manager": "<5.0.1",
+ "melisplatform/melis-cms": "<5.0.1",
+ "melisplatform/melis-front": "<5.0.1",
+ "mezzio/mezzio-swoole": "<3.7|>=4,<4.3",
+ "mgallegos/laravel-jqgrid": "<=1.3",
+ "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1",
+ "microsoft/microsoft-graph-beta": "<2.0.1",
+ "microsoft/microsoft-graph-core": "<2.0.2",
+ "microweber/microweber": "<=2.0.4",
+ "mikehaertl/php-shellcommand": "<1.6.1",
+ "miniorange/miniorange-saml": "<1.4.3",
+ "mittwald/typo3_forum": "<1.2.1",
+ "mobiledetect/mobiledetectlib": "<2.8.32",
+ "modx/revolution": "<=2.8.3.0-patch",
+ "mojo42/jirafeau": "<4.4",
+ "mongodb/mongodb": ">=1,<1.9.2",
"monolog/monolog": ">=1.8,<1.12",
+ "moodle/moodle": "<4.3.5|>=4.4.0.0-beta,<4.4.1",
+ "mos/cimage": "<0.7.19",
+ "movim/moxl": ">=0.8,<=0.10",
+ "movingbytes/social-network": "<=1.2.1",
+ "mpdf/mpdf": "<=7.1.7",
+ "munkireport/comment": "<4.1",
+ "munkireport/managedinstalls": "<2.6",
+ "munkireport/munki_facts": "<1.5",
+ "munkireport/munkireport": ">=2.5.3,<5.6.3",
+ "munkireport/reportdata": "<3.5",
+ "munkireport/softwareupdate": "<1.6",
+ "mustache/mustache": ">=2,<2.14.1",
"namshi/jose": "<2.2",
+ "neoan3-apps/template": "<1.1.1",
+ "neorazorx/facturascripts": "<2022.04",
+ "neos/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
+ "neos/form": ">=1.2,<4.3.3|>=5,<5.0.9|>=5.1,<5.1.3",
+ "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9",
+ "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2",
+ "neos/swiftmailer": "<5.4.5",
+ "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15",
+ "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6",
+ "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13",
+ "nilsteampassnet/teampass": "<3.0.10",
+ "nonfiction/nterchange": "<4.1.1",
+ "notrinos/notrinos-erp": "<=0.7",
+ "noumo/easyii": "<=0.9",
+ "novaksolutions/infusionsoft-php-sdk": "<1",
+ "nukeviet/nukeviet": "<4.5.02",
+ "nyholm/psr7": "<1.6.1",
+ "nystudio107/craft-seomatic": "<3.4.12",
+ "nzedb/nzedb": "<0.8",
+ "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1",
+ "october/backend": "<1.1.2",
+ "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1",
+ "october/october": "<=3.4.4",
+ "october/rain": "<1.0.472|>=1.1,<1.1.2",
+ "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.15",
+ "omeka/omeka-s": "<4.0.3",
"onelogin/php-saml": "<2.10.4",
+ "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5",
+ "open-web-analytics/open-web-analytics": "<1.7.4",
+ "opencart/opencart": ">=0",
"openid/php-openid": "<2.3",
- "oro/crm": ">=1.7,<1.7.4",
- "oro/platform": ">=1.7,<1.7.4",
+ "openmage/magento-lts": "<20.10.1",
+ "opensolutions/vimbadmin": "<=3.0.15",
+ "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2",
+ "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5",
+ "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1",
+ "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1",
+ "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7",
+ "oro/crm-call-bundle": ">=4.2,<=4.2.5|>=5,<5.0.4|>=5.1,<5.1.1",
+ "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3",
+ "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3",
+ "oveleon/contao-cookiebar": "<1.16.3|>=2,<2.1.3",
+ "oxid-esales/oxideshop-ce": "<4.5",
+ "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1",
+ "packbackbooks/lti-1-3-php-library": "<5",
"padraic/humbug_get_contents": "<1.1.2",
- "pagarme/pagarme-php": ">=0,<3",
+ "pagarme/pagarme-php": "<3",
+ "pagekit/pagekit": "<=1.0.18",
+ "paragonie/ecc": "<2.0.1",
"paragonie/random_compat": "<2",
+ "passbolt/passbolt_api": "<4.6.2",
+ "paypal/adaptivepayments-sdk-php": "<=3.9.2",
+ "paypal/invoice-sdk-php": "<=3.9",
"paypal/merchant-sdk-php": "<3.12",
- "pear/archive_tar": "<1.4.4",
- "phpmailer/phpmailer": ">=5,<5.2.27|>=6,<6.0.6",
- "phpoffice/phpexcel": "<=1.8.1",
- "phpoffice/phpspreadsheet": "<=1.5",
+ "paypal/permissions-sdk-php": "<=3.9.1",
+ "pear/archive_tar": "<1.4.14",
+ "pear/auth": "<1.2.4",
+ "pear/crypt_gpg": "<1.6.7",
+ "pear/pear": "<=1.10.1",
+ "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1",
+ "personnummer/personnummer": "<3.0.2",
+ "phanan/koel": "<5.1.4",
+ "phenx/php-svg-lib": "<0.5.2",
+ "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5",
+ "php-mod/curl": "<2.3.2",
+ "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1",
+ "phpems/phpems": ">=6,<=6.1.3",
+ "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7",
+ "phpmailer/phpmailer": "<6.5",
+ "phpmussel/phpmussel": ">=1,<1.6",
+ "phpmyadmin/phpmyadmin": "<5.2.1",
+ "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5",
+ "phpoffice/common": "<0.2.9",
+ "phpoffice/phpexcel": "<1.8",
+ "phpoffice/phpspreadsheet": "<1.16",
+ "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36",
+ "phpservermon/phpservermon": "<3.6",
+ "phpsysinfo/phpsysinfo": "<3.4.3",
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
"phpwhois/phpwhois": "<=4.2.5",
"phpxmlrpc/extras": "<0.6.1",
- "propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
+ "phpxmlrpc/phpxmlrpc": "<4.9.2",
+ "pi/pi": "<=2.5",
+ "pimcore/admin-ui-classic-bundle": "<=1.5.1",
+ "pimcore/customer-management-framework-bundle": "<4.0.6",
+ "pimcore/data-hub": "<1.2.4",
+ "pimcore/demo": "<10.3",
+ "pimcore/ecommerce-framework-bundle": "<1.0.10",
+ "pimcore/perspective-editor": "<1.5.1",
+ "pimcore/pimcore": "<11.2.4",
+ "pixelfed/pixelfed": "<0.11.11",
+ "plotly/plotly.js": "<2.25.2",
+ "pocketmine/bedrock-protocol": "<8.0.2",
+ "pocketmine/pocketmine-mp": "<5.11.2",
+ "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1",
+ "pressbooks/pressbooks": "<5.18",
+ "prestashop/autoupgrade": ">=4,<4.10.1",
+ "prestashop/blockreassurance": "<=5.1.3",
+ "prestashop/blockwishlist": ">=2,<2.1.1",
+ "prestashop/contactform": ">=1.0.1,<4.3",
+ "prestashop/gamification": "<2.3.2",
+ "prestashop/prestashop": "<8.1.6",
+ "prestashop/productcomments": "<5.0.2",
+ "prestashop/ps_emailsubscription": "<2.6.1",
+ "prestashop/ps_facetedsearch": "<3.4.1",
+ "prestashop/ps_linklist": "<3.1",
+ "privatebin/privatebin": "<1.4|>=1.5,<1.7.4",
+ "processwire/processwire": "<=3.0.229",
+ "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7",
"propel/propel1": ">=1,<=1.7.1",
+ "pterodactyl/panel": "<1.11.6",
+ "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2",
+ "ptrofimov/beanstalk_console": "<1.7.14",
+ "pubnub/pubnub": "<6.1",
"pusher/pusher-php-server": "<2.2.1",
- "robrichards/xmlseclibs": ">=1,<3.0.2",
- "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
+ "pwweb/laravel-core": "<=0.3.6.0-beta",
+ "pyrocms/pyrocms": "<=3.9.1",
+ "qcubed/qcubed": "<=3.1.1",
+ "quickapps/cms": "<=2.0.0.0-beta2",
+ "rainlab/blog-plugin": "<1.4.1",
+ "rainlab/debugbar-plugin": "<3.1",
+ "rainlab/user-plugin": "<=1.4.5",
+ "rankmath/seo-by-rank-math": "<=1.0.95",
+ "rap2hpoutre/laravel-log-viewer": "<0.13",
+ "react/http": ">=0.7,<1.9",
+ "really-simple-plugins/complianz-gdpr": "<6.4.2",
+ "redaxo/source": "<=5.15.1",
+ "remdex/livehelperchat": "<4.29",
+ "reportico-web/reportico": "<=8.1",
+ "rhukster/dom-sanitizer": "<1.0.7",
+ "rmccue/requests": ">=1.6,<1.8",
+ "robrichards/xmlseclibs": ">=1,<3.0.4",
+ "roots/soil": "<4.1",
+ "rudloff/alltube": "<3.0.3",
+ "s-cart/core": "<6.9",
+ "s-cart/s-cart": "<6.9",
+ "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1",
+ "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9",
+ "scheb/two-factor-bundle": "<3.26|>=4,<4.11",
"sensiolabs/connect": "<4.2.3",
"serluck/phpwhois": "<=4.2.6",
- "shopware/shopware": "<5.3.7",
- "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11",
+ "sfroemken/url_redirect": "<=1.2.1",
+ "sheng/yiicms": "<=1.2",
+ "shopware/core": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1",
+ "shopware/platform": "<6.5.8.8-dev|>=6.6.0.0-RC1-dev,<6.6.1",
+ "shopware/production": "<=6.3.5.2",
+ "shopware/shopware": "<=5.7.17",
+ "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev",
+ "shopxo/shopxo": "<=6.1",
+ "showdoc/showdoc": "<2.10.4",
+ "silverstripe-australia/advancedreports": ">=1,<=2",
+ "silverstripe/admin": "<1.13.19|>=2,<2.1.8",
+ "silverstripe/assets": ">=1,<1.11.1",
+ "silverstripe/cms": "<4.11.3",
+ "silverstripe/comments": ">=1.3,<3.1.1",
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
- "silverstripe/framework": ">=3,<3.6.7|>=3.7,<3.7.3|>=4,<4.0.7|>=4.1,<4.1.5|>=4.2,<4.2.4|>=4.3,<4.3.1",
- "silverstripe/userforms": "<3",
+ "silverstripe/framework": "<5.2.16",
+ "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3",
+ "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1",
+ "silverstripe/recipe-cms": ">=4.5,<4.5.3",
+ "silverstripe/registry": ">=2.1,<2.1.2|>=2.2,<2.2.1",
+ "silverstripe/reports": "<5.2.3",
+ "silverstripe/restfulserver": ">=1,<1.0.9|>=2,<2.0.4|>=2.1,<2.1.2",
+ "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1",
+ "silverstripe/subsites": ">=2,<2.6.1",
+ "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1",
+ "silverstripe/userforms": "<3|>=5,<5.4.2",
+ "silverstripe/versioned-admin": ">=1,<1.11.1",
"simple-updates/phpwhois": "<=1",
- "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
- "simplesamlphp/simplesamlphp": "<1.16.3",
+ "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12",
+ "simplesamlphp/simplesamlphp": "<1.18.6",
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
+ "simplesamlphp/simplesamlphp-module-openid": "<1",
+ "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9",
+ "simplesamlphp/xml-security": "==1.6.11",
+ "simplito/elliptic-php": "<1.0.6",
+ "sitegeist/fluid-components": "<3.5",
+ "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3",
+ "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1",
"slim/slim": "<2.6",
- "smarty/smarty": "<3.1.33",
+ "slub/slub-events": "<3.0.3",
+ "smarty/smarty": "<4.5.3|>=5,<5.1.1",
+ "snipe/snipe-it": "<6.4.2",
"socalnick/scn-social-auth": "<1.15.2",
+ "socialiteproviders/steam": "<1.1",
+ "spatie/browsershot": "<3.57.4",
+ "spatie/image-optimizer": "<1.7.3",
+ "spipu/html2pdf": "<5.2.8",
+ "spoon/library": "<1.4.1",
"spoonity/tcpdf": "<6.2.22",
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
- "stormpath/sdk": ">=0,<9.9.99",
- "swiftmailer/swiftmailer": ">=4,<5.4.5",
+ "ssddanbrown/bookstack": "<24.05.1",
+ "statamic/cms": "<4.46|>=5.3,<5.6.2",
+ "stormpath/sdk": "<9.9.99",
+ "studio-42/elfinder": "<=2.1.64",
+ "studiomitte/friendlycaptcha": "<0.1.4",
+ "subhh/libconnect": "<7.0.8|>=8,<8.1",
+ "sukohi/surpass": "<1",
+ "sulu/form-bundle": ">=2,<2.5.3",
+ "sulu/sulu": "<1.6.44|>=2,<2.4.17|>=2.5,<2.5.13",
+ "sumocoders/framework-user-bundle": "<1.4",
+ "superbig/craft-audit": "<3.0.2",
+ "swag/paypal": "<5.4.4",
+ "swiftmailer/swiftmailer": "<6.2.5",
+ "swiftyedit/swiftyedit": "<1.2",
"sylius/admin-bundle": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
- "sylius/sylius": ">=1,<1.0.17|>=1.1,<1.1.9|>=1.2,<1.2.2",
- "symfony/dependency-injection": ">=2,<2.0.17",
+ "sylius/grid": ">=1,<1.1.19|>=1.2,<1.2.18|>=1.3,<1.3.13|>=1.4,<1.4.5|>=1.5,<1.5.1",
+ "sylius/grid-bundle": "<1.10.1",
+ "sylius/paypal-plugin": ">=1,<1.2.4|>=1.3,<1.3.1",
+ "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4",
+ "sylius/sylius": "<1.12.19|>=1.13.0.0-alpha1,<1.13.4",
+ "symbiote/silverstripe-multivaluefield": ">=3,<3.1",
+ "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4",
+ "symbiote/silverstripe-seed": "<6.0.3",
+ "symbiote/silverstripe-versionedfiles": "<=2.0.3",
+ "symfont/process": ">=0",
+ "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8",
+ "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
+ "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4",
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
- "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2",
- "symfony/http-foundation": ">=2,<2.7.49|>=2.8,<2.8.44|>=3,<3.3.18|>=3.4,<3.4.14|>=4,<4.0.14|>=4.1,<4.1.3",
- "symfony/http-kernel": ">=2,<2.3.29|>=2.4,<2.5.12|>=2.6,<2.6.8",
+ "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4",
+ "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7",
+ "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
+ "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1",
+ "symfony/mime": ">=4.3,<4.3.8",
+ "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
"symfony/polyfill": ">=1,<1.10",
"symfony/polyfill-php55": ">=1,<1.10",
+ "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7",
"symfony/routing": ">=2,<2.0.19",
- "symfony/security": ">=2,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.19|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
- "symfony/security-bundle": ">=2,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
- "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<2.8.37|>=3,<3.3.17|>=3.4,<3.4.7|>=4,<4.0.7",
+ "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8",
+ "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
+ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9",
"symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
- "symfony/security-guard": ">=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11",
- "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
- "symfony/serializer": ">=2,<2.0.11",
- "symfony/symfony": ">=2,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
+ "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
+ "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8",
+ "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
+ "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
"symfony/translation": ">=2,<2.0.17",
+ "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
+ "symfony/ux-autocomplete": "<2.11.2",
"symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3",
+ "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8",
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
- "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
- "tecnickcom/tcpdf": "<6.2.22",
+ "symfony/webhook": ">=6.3,<6.3.8",
+ "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2",
+ "symphonycms/symphony-2": "<2.6.4",
+ "t3/dce": "<0.11.5|>=2.2,<2.6.2",
+ "t3g/svg-sanitizer": "<1.0.3",
+ "t3s/content-consent": "<1.0.3|>=2,<2.0.2",
+ "tastyigniter/tastyigniter": "<3.3",
+ "tcg/voyager": "<=1.4",
+ "tecnickcom/tcpdf": "<=6.7.4",
+ "terminal42/contao-tablelookupwizard": "<3.3.5",
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
- "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
+ "thelia/thelia": ">=2.1,<2.1.3",
"theonedemon/phpwhois": "<=4.2.5",
- "titon/framework": ">=0,<9.9.99",
+ "thinkcmf/thinkcmf": "<6.0.8",
+ "thorsten/phpmyfaq": "<3.2.2",
+ "tikiwiki/tiki-manager": "<=17.1",
+ "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1",
+ "tinymce/tinymce": "<7.2",
+ "tinymighty/wiki-seo": "<1.2.2",
+ "titon/framework": "<9.9.99",
+ "tobiasbg/tablepress": "<=2.0.0.0-RC1",
+ "topthink/framework": "<6.0.17|>=6.1,<6.1.5|>=8,<8.0.4",
+ "topthink/think": "<=6.1.1",
+ "topthink/thinkphp": "<=3.2.3",
+ "torrentpier/torrentpier": "<=2.4.3",
+ "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2",
+ "tribalsystems/zenario": "<9.5.60602",
"truckersmp/phpwhois": "<=4.3.1",
- "twig/twig": "<1.38|>=2,<2.7",
- "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.23|>=9,<9.5.4",
- "typo3/cms-core": ">=8,<8.7.23|>=9,<9.5.4",
- "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.10|>=3.1,<3.1.7|>=3.2,<3.2.7|>=3.3,<3.3.5",
- "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4",
+ "ttskch/pagination-service-provider": "<1",
+ "twbs/bootstrap": "<=3.4.1|>=4,<=4.6.2",
+ "twig/twig": "<1.44.7|>=2,<2.15.3|>=3,<3.4.3",
+ "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2",
+ "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
+ "typo3/cms-core": "<=8.7.56|>=9,<=9.5.47|>=10,<=10.4.44|>=11,<=11.5.36|>=12,<=12.4.14|>=13,<=13.1",
+ "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1",
+ "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1",
+ "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1",
+ "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5",
+ "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8",
+ "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30",
+ "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6",
+ "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3",
+ "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3",
+ "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1",
+ "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5",
+ "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10",
"ua-parser/uap-php": "<3.8",
+ "uasoft-indonesia/badaso": "<=2.9.7",
+ "unisharp/laravel-filemanager": "<2.6.4",
+ "userfrosting/userfrosting": ">=0.3.1,<4.6.3",
+ "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2",
+ "uvdesk/community-skeleton": "<=1.1.1",
+ "uvdesk/core-framework": "<=1.1.1",
+ "vanilla/safecurl": "<0.9.2",
+ "verbb/comments": "<1.5.5",
+ "verbb/formie": "<2.1.6",
+ "verbb/image-resizer": "<2.0.9",
+ "verbb/knock-knock": "<1.2.8",
+ "verot/class.upload.php": "<=2.1.6",
+ "villagedefrance/opencart-overclocked": "<=1.11.1",
+ "vova07/yii2-fileapi-widget": "<0.1.9",
+ "vrana/adminer": "<4.8.1",
+ "vufind/vufind": ">=2,<9.1.1",
+ "waldhacker/hcaptcha": "<2.1.2",
"wallabag/tcpdf": "<6.2.22",
+ "wallabag/wallabag": "<2.6.7",
+ "wanglelecc/laracms": "<=1.0.3",
+ "web-auth/webauthn-framework": ">=3.3,<3.3.4|>=4.5,<4.9",
+ "web-auth/webauthn-lib": ">=4.5,<4.9",
+ "web-feet/coastercms": "==5.5",
+ "webbuilders-group/silverstripe-kapost-bridge": "<0.4",
+ "webcoast/deferred-image-processing": "<1.0.2",
+ "webklex/laravel-imap": "<5.3",
+ "webklex/php-imap": "<5.3",
+ "webpa/webpa": "<3.1.2",
+ "wikibase/wikibase": "<=1.39.3",
+ "wikimedia/parsoid": "<0.12.2",
"willdurand/js-translation-bundle": "<2.1.1",
- "yiisoft/yii": ">=1.1.14,<1.1.15",
- "yiisoft/yii2": "<2.0.15",
+ "winter/wn-backend-module": "<1.2.4",
+ "winter/wn-dusk-plugin": "<2.1",
+ "winter/wn-system-module": "<1.2.4",
+ "wintercms/winter": "<=1.2.3",
+ "woocommerce/woocommerce": "<6.6|>=8.8,<8.8.5|>=8.9,<8.9.3",
+ "wp-cli/wp-cli": ">=0.12,<2.5",
+ "wp-graphql/wp-graphql": "<=1.14.5",
+ "wp-premium/gravityforms": "<2.4.21",
+ "wpanel/wpanel4-cms": "<=4.3.1",
+ "wpcloud/wp-stateless": "<3.2",
+ "wpglobus/wpglobus": "<=1.9.6",
+ "wwbn/avideo": "<14.3",
+ "xataface/xataface": "<3",
+ "xpressengine/xpressengine": "<3.0.15",
+ "yab/quarx": "<2.4.5",
+ "yeswiki/yeswiki": "<4.1",
+ "yetiforce/yetiforce-crm": "<=6.4",
+ "yidashi/yii2cmf": "<=2",
+ "yii2mod/yii2-cms": "<1.9.2",
+ "yiisoft/yii": "<1.1.29",
+ "yiisoft/yii2": "<2.0.49.4-dev",
+ "yiisoft/yii2-authclient": "<2.2.15",
"yiisoft/yii2-bootstrap": "<2.0.4",
- "yiisoft/yii2-dev": "<2.0.15",
+ "yiisoft/yii2-dev": "<2.0.43",
"yiisoft/yii2-elasticsearch": "<2.0.5",
- "yiisoft/yii2-gii": "<2.0.4",
+ "yiisoft/yii2-gii": "<=2.2.4",
"yiisoft/yii2-jui": "<2.0.4",
"yiisoft/yii2-redis": "<2.0.8",
+ "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6",
+ "yoast-seo-for-typo3/yoast_seo": "<7.2.3",
+ "yourls/yourls": "<=1.8.2",
+ "yuan1994/tpadmin": "<=1.3.12",
+ "zencart/zencart": "<=1.5.7.0-beta",
+ "zendesk/zendesk_api_client_php": "<2.2.11",
"zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3",
"zendframework/zend-captcha": ">=2,<2.4.9|>=2.5,<2.5.2",
"zendframework/zend-crypt": ">=2,<2.4.9|>=2.5,<2.5.2",
- "zendframework/zend-db": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.10|>=2.3,<2.3.5",
+ "zendframework/zend-db": "<2.2.10|>=2.3,<2.3.5",
"zendframework/zend-developer-tools": ">=1.2.2,<1.2.3",
- "zendframework/zend-diactoros": ">=1,<1.8.4",
- "zendframework/zend-feed": ">=1,<2.10.3",
+ "zendframework/zend-diactoros": "<1.8.4",
+ "zendframework/zend-feed": "<2.10.3",
"zendframework/zend-form": ">=2,<2.2.7|>=2.3,<2.3.1",
- "zendframework/zend-http": ">=1,<2.8.1",
+ "zendframework/zend-http": "<2.8.1",
"zendframework/zend-json": ">=2.1,<2.1.6|>=2.2,<2.2.6",
"zendframework/zend-ldap": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.8|>=2.3,<2.3.3",
- "zendframework/zend-mail": ">=2,<2.4.11|>=2.5,<2.7.2",
+ "zendframework/zend-mail": "<2.4.11|>=2.5,<2.7.2",
"zendframework/zend-navigation": ">=2,<2.2.7|>=2.3,<2.3.1",
- "zendframework/zend-session": ">=2,<2.0.99|>=2.1,<2.1.99|>=2.2,<2.2.9|>=2.3,<2.3.4",
+ "zendframework/zend-session": ">=2,<2.2.9|>=2.3,<2.3.4",
"zendframework/zend-validator": ">=2.3,<2.3.6",
"zendframework/zend-view": ">=2,<2.2.7|>=2.3,<2.3.1",
"zendframework/zend-xmlrpc": ">=2.1,<2.1.6|>=2.2,<2.2.6",
- "zendframework/zendframework": "<2.5.1",
+ "zendframework/zendframework": "<=3",
"zendframework/zendframework1": "<1.12.20",
- "zendframework/zendopenid": ">=2,<2.0.2",
+ "zendframework/zendopenid": "<2.0.2",
+ "zendframework/zendrest": "<2.0.2",
+ "zendframework/zendservice-amazon": "<2.0.3",
+ "zendframework/zendservice-api": "<1",
+ "zendframework/zendservice-audioscrobbler": "<2.0.2",
+ "zendframework/zendservice-nirvanix": "<2.0.2",
+ "zendframework/zendservice-slideshare": "<2.0.2",
+ "zendframework/zendservice-technorati": "<2.0.2",
+ "zendframework/zendservice-windowsazure": "<2.0.2",
"zendframework/zendxml": ">=1,<1.0.1",
+ "zenstruck/collection": "<0.2.1",
"zetacomponents/mail": "<1.8.2",
"zf-commons/zfc-user": "<1.2.2",
"zfcampus/zf-apigility-doctrine": ">=1,<1.0.3",
- "zfr/zfr-oauth2-server-module": "<0.1.2"
+ "zfr/zfr-oauth2-server-module": "<0.1.2",
+ "zoujingli/thinkadmin": "<=6.1.53"
+ },
+ "type": "metapackage",
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "role": "maintainer"
+ },
+ {
+ "name": "Ilya Tribusean",
+ "email": "slash3b@gmail.com",
+ "role": "maintainer"
+ }
+ ],
+ "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
+ "keywords": [
+ "dev"
+ ],
+ "support": {
+ "issues": "https://github.com/Roave/SecurityAdvisories/issues",
+ "source": "https://github.com/Roave/SecurityAdvisories/tree/latest"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Ocramius",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/roave/security-advisories",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2024-08-05T15:04:41+00:00"
+ },
+ {
+ "name": "sebastian/cli-parser",
+ "version": "1.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/cli-parser.git",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
},
- "type": "metapackage",
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Marco Pivetta",
- "email": "ocramius@gmail.com",
- "role": "maintainer"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
- "time": "2019-04-07T10:25:46+00:00"
+ "description": "Library for parsing CLI options",
+ "homepage": "https://github.com/sebastianbergmann/cli-parser",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+ "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:27:43+00:00"
+ },
+ {
+ "name": "sebastian/code-unit",
+ "version": "1.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/code-unit.git",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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",
+ "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:08:54+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.1",
+ "version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+ "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^5.7 || ^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -6765,34 +8928,44 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2017-03-04T06:30:41+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-09-28T05:30:19+00:00"
},
{
"name": "sebastian/comparator",
- "version": "2.1.3",
+ "version": "4.0.8",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9"
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9",
- "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a",
+ "reference": "fa0f136dd2334583309d32b62544682ee972b51a",
"shasum": ""
},
"require": {
- "php": "^7.0",
- "sebastian/diff": "^2.0 || ^3.0",
- "sebastian/exporter": "^3.1"
+ "php": ">=7.3",
+ "sebastian/diff": "^4.0",
+ "sebastian/exporter": "^4.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.4"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.1.x-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -6805,6 +8978,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -6816,10 +8993,6 @@
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
@@ -6829,27 +9002,38 @@
"compare",
"equality"
],
- "time": "2018-02-01T13:46:46+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2022-09-14T12:41:17+00:00"
},
{
- "name": "sebastian/diff",
- "version": "2.0.1",
+ "name": "sebastian/complexity",
+ "version": "2.0.3",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd"
+ "url": "https://github.com/sebastianbergmann/complexity.git",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
- "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd",
+ "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a",
+ "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^6.2"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
@@ -6868,45 +9052,118 @@
],
"authors": [
{
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
+ "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",
+ "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:19:30+00:00"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "4.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3",
+ "symfony/process": "^4.2 || ^5"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.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"
+ "diff",
+ "udiff",
+ "unidiff",
+ "unified diff"
+ ],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2017-08-03T08:09:46+00:00"
+ "time": "2024-03-02T06:30:58+00:00"
},
{
"name": "sebastian/environment",
- "version": "3.1.0",
+ "version": "5.1.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5"
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
- "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
+ "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^6.1"
+ "phpunit/phpunit": "^9.3"
+ },
+ "suggest": {
+ "ext-posix": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.1.x-dev"
+ "dev-master": "5.1-dev"
}
},
"autoload": {
@@ -6931,34 +9188,44 @@
"environment",
"hhvm"
],
- "time": "2017-07-01T08:51:00+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:03:51+00:00"
},
{
"name": "sebastian/exporter",
- "version": "3.1.0",
+ "version": "4.0.6",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "234199f4528de6d12aaa58b612e98f7d36adb937"
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937",
- "reference": "234199f4528de6d12aaa58b612e98f7d36adb937",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72",
+ "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72",
"shasum": ""
},
"require": {
- "php": "^7.0",
- "sebastian/recursion-context": "^3.0"
+ "php": ">=7.3",
+ "sebastian/recursion-context": "^4.0"
},
"require-dev": {
"ext-mbstring": "*",
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.1.x-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -6971,6 +9238,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -6979,46 +9250,55 @@
"name": "Volker Dusch",
"email": "github@wallbash.com"
},
- {
- "name": "Bernhard Schussek",
- "email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
- },
{
"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": "http://www.github.com/sebastianbergmann/exporter",
+ "homepage": "https://www.github.com/sebastianbergmann/exporter",
"keywords": [
"export",
"exporter"
],
- "time": "2017-04-03T13:19:02+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:33:00+00:00"
},
{
"name": "sebastian/global-state",
- "version": "2.0.0",
+ "version": "5.0.7",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4"
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
- "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
+ "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "ext-dom": "*",
+ "phpunit/phpunit": "^9.3"
},
"suggest": {
"ext-uopz": "*"
@@ -7026,7 +9306,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0-dev"
+ "dev-master": "5.0-dev"
}
},
"autoload": {
@@ -7049,34 +9329,101 @@
"keywords": [
"global state"
],
- "time": "2017-04-27T15:39:26+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-02T06:35:11+00:00"
+ },
+ {
+ "name": "sebastian/lines-of-code",
+ "version": "1.0.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.18 || ^5.0",
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.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",
+ "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-12-22T06:20:34+00:00"
},
{
"name": "sebastian/object-enumerator",
- "version": "3.0.3",
+ "version": "4.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+ "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
"shasum": ""
},
"require": {
- "php": "^7.0",
- "sebastian/object-reflector": "^1.1.1",
- "sebastian/recursion-context": "^3.0"
+ "php": ">=7.3",
+ "sebastian/object-reflector": "^2.0",
+ "sebastian/recursion-context": "^4.0"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0.x-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -7096,32 +9443,42 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-08-03T12:35:26+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:12:34+00:00"
},
{
"name": "sebastian/object-reflector",
- "version": "1.1.1",
+ "version": "2.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "773f97c67f28de00d397be301821b06708fca0be"
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
- "reference": "773f97c67f28de00d397be301821b06708fca0be",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+ "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.1-dev"
+ "dev-master": "2.0-dev"
}
},
"autoload": {
@@ -7141,32 +9498,42 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "time": "2017-03-29T09:07:27+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-10-26T13:14:26+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "3.0.0",
+ "version": "4.0.5",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
+ "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.3"
},
"require-dev": {
- "phpunit/phpunit": "^6.0"
+ "phpunit/phpunit": "^9.3"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.0.x-dev"
+ "dev-master": "4.0-dev"
}
},
"autoload": {
@@ -7179,44 +9546,57 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
{
"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": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2017-03-03T06:23:57+00:00"
+ "homepage": "https://github.com/sebastianbergmann/recursion-context",
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:07:39+00:00"
},
{
"name": "sebastian/resource-operations",
- "version": "1.0.0",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52"
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
- "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
+ "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e",
"shasum": ""
},
"require": {
- "php": ">=5.6.0"
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-main": "3.0-dev"
}
},
"autoload": {
@@ -7234,31 +9614,43 @@
"email": "sebastian@phpunit.de"
}
],
- "description": "Provides a list of PHP built-in functions that operate on resources",
- "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2015-07-28T20:34:47+00:00"
+ "description": "Provides a list of PHP built-in functions that operate on resources",
+ "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+ "support": {
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2024-03-14T16:00:52+00:00"
},
{
- "name": "sebastian/version",
- "version": "2.0.1",
+ "name": "sebastian/type",
+ "version": "3.2.1",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/version.git",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019"
+ "url": "https://github.com/sebastianbergmann/type.git",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019",
- "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
+ "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7",
"shasum": ""
},
"require": {
- "php": ">=5.6"
+ "php": ">=7.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.0.x-dev"
+ "dev-master": "3.2-dev"
}
},
"autoload": {
@@ -7277,68 +9669,46 @@
"role": "lead"
}
],
- "description": "Library that helps with managing the version number of Git-hosted PHP projects",
- "homepage": "https://github.com/sebastianbergmann/version",
- "time": "2016-10-03T07:35:21+00:00"
+ "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",
+ "source": "https://github.com/sebastianbergmann/type/tree/3.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2023-02-03T06:13:03+00:00"
},
{
- "name": "squizlabs/php_codesniffer",
- "version": "2.9.2",
+ "name": "sebastian/version",
+ "version": "3.0.2",
"source": {
"type": "git",
- "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "2acf168de78487db620ab4bc524135a13cfe6745"
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745",
- "reference": "2acf168de78487db620ab4bc524135a13cfe6745",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+ "reference": "c6c1022351a901512170118436c764e473f6de8c",
"shasum": ""
},
"require": {
- "ext-simplexml": "*",
- "ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": ">=5.1.2"
- },
- "require-dev": {
- "phpunit/phpunit": "~4.0"
+ "php": ">=7.3"
},
- "bin": [
- "scripts/phpcs",
- "scripts/phpcbf"
- ],
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.x-dev"
+ "dev-master": "3.0-dev"
}
},
"autoload": {
"classmap": [
- "CodeSniffer.php",
- "CodeSniffer/CLI.php",
- "CodeSniffer/Exception.php",
- "CodeSniffer/File.php",
- "CodeSniffer/Fixer.php",
- "CodeSniffer/Report.php",
- "CodeSniffer/Reporting.php",
- "CodeSniffer/Sniff.php",
- "CodeSniffer/Tokens.php",
- "CodeSniffer/Reports/",
- "CodeSniffer/Tokenizers/",
- "CodeSniffer/DocGenerators/",
- "CodeSniffer/Standards/AbstractPatternSniff.php",
- "CodeSniffer/Standards/AbstractScopeSniff.php",
- "CodeSniffer/Standards/AbstractVariableSniff.php",
- "CodeSniffer/Standards/IncorrectPatternException.php",
- "CodeSniffer/Standards/Generic/Sniffs/",
- "CodeSniffer/Standards/MySource/Sniffs/",
- "CodeSniffer/Standards/PEAR/Sniffs/",
- "CodeSniffer/Standards/PSR1/Sniffs/",
- "CodeSniffer/Standards/PSR2/Sniffs/",
- "CodeSniffer/Standards/Squiz/Sniffs/",
- "CodeSniffer/Standards/Zend/Sniffs/"
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -7347,56 +9717,58 @@
],
"authors": [
{
- "name": "Greg Sherwood",
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
"role": "lead"
}
],
- "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
- "homepage": "http://www.squizlabs.com/php-codesniffer",
- "keywords": [
- "phpcs",
- "standards"
+ "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",
+ "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
],
- "time": "2018-11-07T22:31:41+00:00"
+ "time": "2020-09-28T06:39:44+00:00"
},
{
- "name": "symfony/browser-kit",
- "version": "v4.2.5",
+ "name": "spatie/array-to-xml",
+ "version": "3.3.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/browser-kit.git",
- "reference": "61d85c5af2fc058014c7c89504c3944e73a086f0"
+ "url": "https://github.com/spatie/array-to-xml.git",
+ "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/61d85c5af2fc058014c7c89504c3944e73a086f0",
- "reference": "61d85c5af2fc058014c7c89504c3944e73a086f0",
+ "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f56b220fe2db1ade4c88098d83413ebdfc3bf876",
+ "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/dom-crawler": "~3.4|~4.0"
+ "ext-dom": "*",
+ "php": "^8.0"
},
"require-dev": {
- "symfony/css-selector": "~3.4|~4.0",
- "symfony/process": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/process": ""
+ "mockery/mockery": "^1.2",
+ "pestphp/pest": "^1.21",
+ "spatie/pest-plugin-snapshots": "^1.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "4.2-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
- "Symfony\\Component\\BrowserKit\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
+ "Spatie\\ArrayToXml\\": "src"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -7404,51 +9776,62 @@
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "name": "Freek Van der Herten",
+ "email": "freek@spatie.be",
+ "homepage": "https://freek.dev",
+ "role": "Developer"
+ }
+ ],
+ "description": "Convert an array to xml",
+ "homepage": "https://github.com/spatie/array-to-xml",
+ "keywords": [
+ "array",
+ "convert",
+ "xml"
+ ],
+ "support": {
+ "source": "https://github.com/spatie/array-to-xml/tree/3.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://spatie.be/open-source/support-us",
+ "type": "custom"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "url": "https://github.com/spatie",
+ "type": "github"
}
],
- "description": "Symfony BrowserKit Component",
- "homepage": "https://symfony.com",
- "time": "2019-02-23T15:17:42+00:00"
+ "time": "2024-05-01T10:20:27+00:00"
},
{
- "name": "symfony/class-loader",
- "version": "v3.4.24",
+ "name": "symfony/browser-kit",
+ "version": "v7.1.1",
"source": {
"type": "git",
- "url": "https://github.com/symfony/class-loader.git",
- "reference": "4459eef5298dedfb69f771186a580062b8516497"
+ "url": "https://github.com/symfony/browser-kit.git",
+ "reference": "9c13742e3175b5815e272b981876ae329bec2040"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/class-loader/zipball/4459eef5298dedfb69f771186a580062b8516497",
- "reference": "4459eef5298dedfb69f771186a580062b8516497",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/9c13742e3175b5815e272b981876ae329bec2040",
+ "reference": "9c13742e3175b5815e272b981876ae329bec2040",
"shasum": ""
},
"require": {
- "php": "^5.5.9|>=7.0.8"
+ "php": ">=8.2",
+ "symfony/dom-crawler": "^6.4|^7.0"
},
"require-dev": {
- "symfony/finder": "~2.8|~3.0|~4.0",
- "symfony/polyfill-apcu": "~1.1"
- },
- "suggest": {
- "symfony/polyfill-apcu": "For using ApcClassLoader on HHVM"
+ "symfony/css-selector": "^6.4|^7.0",
+ "symfony/http-client": "^6.4|^7.0",
+ "symfony/mime": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.4-dev"
- }
- },
"autoload": {
"psr-4": {
- "Symfony\\Component\\ClassLoader\\": ""
+ "Symfony\\Component\\BrowserKit\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -7468,33 +9851,45 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony ClassLoader Component",
+ "description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
"homepage": "https://symfony.com",
- "time": "2019-01-16T09:39:14+00:00"
+ "support": {
+ "source": "https://github.com/symfony/browser-kit/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v3.4.24",
+ "version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "8ca29297c29b64fb3a1a135e71cb25f67f9fdccf"
+ "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/8ca29297c29b64fb3a1a135e71cb25f67f9fdccf",
- "reference": "8ca29297c29b64fb3a1a135e71cb25f67f9fdccf",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
+ "reference": "1c7cee86c6f812896af54434f8ce29c8d94f9ff4",
"shasum": ""
},
"require": {
- "php": "^5.5.9|>=7.0.8"
+ "php": ">=8.2"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.4-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
@@ -7508,54 +9903,64 @@
"MIT"
],
"authors": [
- {
- "name": "Jean-FranΓ§ois Simon",
- "email": "jeanfrancois.simon@sensiolabs.com"
- },
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
+ {
+ "name": "Jean-FranΓ§ois Simon",
+ "email": "jeanfrancois.simon@sensiolabs.com"
+ },
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony CssSelector Component",
+ "description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
- "time": "2019-01-16T09:39:14+00:00"
+ "support": {
+ "source": "https://github.com/symfony/css-selector/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v4.2.5",
+ "version": "v7.1.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb"
+ "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/53c97769814c80a84a8403efcf3ae7ae966d53bb",
- "reference": "53c97769814c80a84a8403efcf3ae7ae966d53bb",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/01ce8174447f1f1dd33a5854b01beef79061d9fa",
+ "reference": "01ce8174447f1f1dd33a5854b01beef79061d9fa",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
+ "masterminds/html5": "^2.6",
+ "php": ">=8.2",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
- "symfony/css-selector": "~3.4|~4.0"
- },
- "suggest": {
- "symfony/css-selector": ""
+ "symfony/css-selector": "^6.4|^7.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\DomCrawler\\": ""
@@ -7578,52 +9983,81 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony DomCrawler Component",
+ "description": "Eases DOM navigation for HTML and XML documents",
"homepage": "https://symfony.com",
- "time": "2019-02-23T15:17:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/dom-crawler/tree/v7.1.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-05-31T14:57:53+00:00"
},
{
- "name": "symfony/phpunit-bridge",
- "version": "v4.2.5",
+ "name": "symfony/translation",
+ "version": "v7.1.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/phpunit-bridge.git",
- "reference": "8796da921e4613352818b478e9bb0803ea0dbb9a"
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/8796da921e4613352818b478e9bb0803ea0dbb9a",
- "reference": "8796da921e4613352818b478e9bb0803ea0dbb9a",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/8d5e50c813ba2859a6dfc99a0765c550507934a1",
+ "reference": "8d5e50c813ba2859a6dfc99a0765c550507934a1",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=8.2",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/translation-contracts": "^2.5|^3.0"
},
"conflict": {
- "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0"
+ "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"
},
- "suggest": {
- "symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
+ "provide": {
+ "symfony/translation-implementation": "2.3|3.0"
},
- "bin": [
- "bin/simple-phpunit"
- ],
- "type": "symfony-bridge",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- },
- "thanks": {
- "name": "phpunit/phpunit",
- "url": "https://github.com/sebastianbergmann/phpunit"
- }
+ "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": [
- "bootstrap.php"
+ "Resources/functions.php"
],
"psr-4": {
- "Symfony\\Bridge\\PhpUnit\\": ""
+ "Symfony\\Component\\Translation\\": ""
},
"exclude-from-classmap": [
"/Tests/"
@@ -7635,214 +10069,285 @@
],
"authors": [
{
- "name": "Nicolas Grekas",
- "email": "p@tchwork.com"
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony PHPUnit Bridge",
+ "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
- "time": "2019-03-26T20:16:42+00:00"
+ "support": {
+ "source": "https://github.com/symfony/translation/tree/v7.1.3"
+ },
+ "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-07-26T12:41:01+00:00"
},
{
- "name": "symfony/proxy-manager-bridge",
- "version": "v4.2.5",
+ "name": "symplify/easy-coding-standard",
+ "version": "12.3.4",
"source": {
"type": "git",
- "url": "https://github.com/symfony/proxy-manager-bridge.git",
- "reference": "5c0a3b921fbd5d6ca6cfc9321e67ebb2a8727ac3"
+ "url": "https://github.com/easy-coding-standard/easy-coding-standard.git",
+ "reference": "03cd792d7fa6d9dc59b6e12a5ca73d9873ee9c0e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/proxy-manager-bridge/zipball/5c0a3b921fbd5d6ca6cfc9321e67ebb2a8727ac3",
- "reference": "5c0a3b921fbd5d6ca6cfc9321e67ebb2a8727ac3",
+ "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/03cd792d7fa6d9dc59b6e12a5ca73d9873ee9c0e",
+ "reference": "03cd792d7fa6d9dc59b6e12a5ca73d9873ee9c0e",
"shasum": ""
},
"require": {
- "ocramius/proxy-manager": "~2.1",
- "php": "^7.1.3",
- "symfony/dependency-injection": "~4.0"
+ "php": ">=7.2"
},
"conflict": {
- "zendframework/zend-eventmanager": "2.6.0"
- },
- "require-dev": {
- "symfony/config": "~3.4|~4.0"
+ "friendsofphp/php-cs-fixer": "<3.46",
+ "phpcsstandards/php_codesniffer": "<3.8",
+ "symplify/coding-standard": "<12.1"
},
- "type": "symfony-bridge",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
+ "suggest": {
+ "ext-dom": "Needed to support checkstyle output format in class CheckstyleOutputFormatter"
},
+ "bin": [
+ "bin/ecs"
+ ],
+ "type": "library",
"autoload": {
- "psr-4": {
- "Symfony\\Bridge\\ProxyManager\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "files": [
+ "bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "authors": [
+ "description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer",
+ "keywords": [
+ "Code style",
+ "automation",
+ "fixer",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues",
+ "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.3.4"
+ },
+ "funding": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
+ "url": "https://www.paypal.me/rectorphp",
+ "type": "custom"
},
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "url": "https://github.com/tomasvotruba",
+ "type": "github"
}
],
- "description": "Symfony ProxyManager Bridge",
- "homepage": "https://symfony.com",
- "time": "2019-02-23T15:42:05+00:00"
+ "time": "2024-08-01T07:55:09+00:00"
},
{
- "name": "symfony/translation",
- "version": "v4.2.5",
+ "name": "theseer/tokenizer",
+ "version": "1.2.3",
"source": {
"type": "git",
- "url": "https://github.com/symfony/translation.git",
- "reference": "e46933cc31b68f51f7fc5470fb55550407520f56"
+ "url": "https://github.com/theseer/tokenizer.git",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/e46933cc31b68f51f7fc5470fb55550407520f56",
- "reference": "e46933cc31b68f51f7fc5470fb55550407520f56",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
"shasum": ""
},
"require": {
- "php": "^7.1.3",
- "symfony/contracts": "^1.0.2",
- "symfony/polyfill-mbstring": "~1.0"
- },
- "conflict": {
- "symfony/config": "<3.4",
- "symfony/dependency-injection": "<3.4",
- "symfony/yaml": "<3.4"
- },
- "provide": {
- "symfony/translation-contracts-implementation": "1.0"
- },
- "require-dev": {
- "psr/log": "~1.0",
- "symfony/config": "~3.4|~4.0",
- "symfony/console": "~3.4|~4.0",
- "symfony/dependency-injection": "~3.4|~4.0",
- "symfony/finder": "~2.8|~3.0|~4.0",
- "symfony/intl": "~3.4|~4.0",
- "symfony/yaml": "~3.4|~4.0"
- },
- "suggest": {
- "psr/log-implementation": "To use logging capability in translator",
- "symfony/config": "",
- "symfony/yaml": ""
+ "ext-dom": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.2-dev"
- }
- },
"autoload": {
- "psr-4": {
- "Symfony\\Component\\Translation\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
+ "classmap": [
+ "src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
+ "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": [
{
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
+ "url": "https://github.com/theseer",
+ "type": "github"
}
],
- "description": "Symfony Translation Component",
- "homepage": "https://symfony.com",
- "time": "2019-04-01T14:13:08+00:00"
+ "time": "2024-03-03T12:36:25+00:00"
},
{
- "name": "theseer/tokenizer",
- "version": "1.1.2",
+ "name": "vimeo/psalm",
+ "version": "5.25.0",
"source": {
"type": "git",
- "url": "https://github.com/theseer/tokenizer.git",
- "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8"
+ "url": "https://github.com/vimeo/psalm.git",
+ "reference": "01a8eb06b9e9cc6cfb6a320bf9fb14331919d505"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/1c42705be2b6c1de5904f8afacef5895cab44bf8",
- "reference": "1c42705be2b6c1de5904f8afacef5895cab44bf8",
+ "url": "https://api.github.com/repos/vimeo/psalm/zipball/01a8eb06b9e9cc6cfb6a320bf9fb14331919d505",
+ "reference": "01a8eb06b9e9cc6cfb6a320bf9fb14331919d505",
"shasum": ""
},
"require": {
+ "amphp/amp": "^2.4.2",
+ "amphp/byte-stream": "^1.5",
+ "composer-runtime-api": "^2",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
+ "composer/xdebug-handler": "^2.0 || ^3.0",
+ "dnoegel/php-xdg-base-dir": "^0.1.1",
+ "ext-ctype": "*",
"ext-dom": "*",
+ "ext-json": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
"ext-tokenizer": "*",
- "ext-xmlwriter": "*",
- "php": "^7.0"
+ "felixfbecker/advanced-json-rpc": "^3.1",
+ "felixfbecker/language-server-protocol": "^1.5.2",
+ "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0",
+ "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+ "nikic/php-parser": "^4.16",
+ "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0",
+ "sebastian/diff": "^4.0 || ^5.0 || ^6.0",
+ "spatie/array-to-xml": "^2.17.0 || ^3.0",
+ "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0",
+ "symfony/filesystem": "^5.4 || ^6.0 || ^7.0"
+ },
+ "conflict": {
+ "nikic/php-parser": "4.17.0"
+ },
+ "provide": {
+ "psalm/psalm": "self.version"
+ },
+ "require-dev": {
+ "amphp/phpunit-util": "^2.0",
+ "bamarni/composer-bin-plugin": "^1.4",
+ "brianium/paratest": "^6.9",
+ "ext-curl": "*",
+ "mockery/mockery": "^1.5",
+ "nunomaduro/mock-final-classes": "^1.1",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpdoc-parser": "^1.6",
+ "phpunit/phpunit": "^9.6",
+ "psalm/plugin-mockery": "^1.1",
+ "psalm/plugin-phpunit": "^0.18",
+ "slevomat/coding-standard": "^8.4",
+ "squizlabs/php_codesniffer": "^3.6",
+ "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "suggest": {
+ "ext-curl": "In order to send data to shepherd",
+ "ext-igbinary": "^2.0.5 is required, used to serialize caching data"
+ },
+ "bin": [
+ "psalm",
+ "psalm-language-server",
+ "psalm-plugin",
+ "psalm-refactor",
+ "psalter"
+ ],
+ "type": "project",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.x-dev",
+ "dev-4.x": "4.x-dev",
+ "dev-3.x": "3.x-dev",
+ "dev-2.x": "2.x-dev",
+ "dev-1.x": "1.x-dev"
+ }
},
- "type": "library",
"autoload": {
- "classmap": [
- "src/"
- ]
+ "psr-4": {
+ "Psalm\\": "src/Psalm/"
+ }
},
"notification-url": "https://packagist.org/downloads/",
"license": [
- "BSD-3-Clause"
+ "MIT"
],
"authors": [
{
- "name": "Arne Blankerts",
- "email": "arne@blankerts.de",
- "role": "Developer"
+ "name": "Matthew Brown"
}
],
- "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
- "time": "2019-04-04T09:56:43+00:00"
+ "description": "A static analysis tool for finding errors in PHP applications",
+ "keywords": [
+ "code",
+ "inspection",
+ "php",
+ "static analysis"
+ ],
+ "support": {
+ "docs": "https://psalm.dev/docs",
+ "issues": "https://github.com/vimeo/psalm/issues",
+ "source": "https://github.com/vimeo/psalm"
+ },
+ "time": "2024-06-16T15:08:35+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.4.0",
+ "version": "1.11.0",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9"
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9",
- "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+ "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0",
- "symfony/polyfill-ctype": "^1.8"
+ "ext-ctype": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan": "<0.12.20",
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.6",
- "sebastian/version": "^1.0.1"
+ "phpunit/phpunit": "^8.5.13"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.3-dev"
+ "dev-master": "1.10-dev"
}
},
"autoload": {
@@ -7866,28 +10371,30 @@
"check",
"validate"
],
- "time": "2018-12-25T11:19:39+00:00"
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.11.0"
+ },
+ "time": "2022-06-03T18:03:27+00:00"
}
],
"aliases": [],
- "minimum-stability": "stable",
+ "minimum-stability": "RC",
"stability-flags": {
"roave/security-advisories": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": "^7.3",
+ "php": "^8.3",
"ext-amqp": "*",
"ext-apcu": "*",
- "ext-bcmath": "*",
- "ext-ctype": "*",
- "ext-intl": "*",
"ext-json": "*",
"ext-zend-opcache": "*",
"ext-pdo": "*"
},
"platform-dev": {
"ext-xdebug": "*"
- }
+ },
+ "plugin-api-version": "2.6.0"
}
diff --git a/databases/_pre_mooc.sql b/databases/_pre_mooc.sql
deleted file mode 100644
index 03a1f0e5c..000000000
--- a/databases/_pre_mooc.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-CREATE DATABASE IF NOT EXISTS `video`;
-
-USE `video`;
diff --git a/databases/mooc.sql b/databases/mooc.sql
deleted file mode 100644
index d50f02bea..000000000
--- a/databases/mooc.sql
+++ /dev/null
@@ -1,48 +0,0 @@
-CREATE TABLE `videos` (
- `id` CHAR(36) NOT NULL,
- `type` VARCHAR(32) NOT NULL,
- `title` VARCHAR(255) NOT NULL,
- `url` VARCHAR(255) NOT NULL,
- `course_id` CHAR(36) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-CREATE TABLE `students` (
- `id` CHAR(36) NOT NULL,
- `name` VARCHAR(155) NOT NULL,
- `total_videos_created` INTEGER(5) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-CREATE TABLE `steps` (
- `id` CHAR(36) NOT NULL,
- `type` tinyint(3) unsigned NOT NULL,
- `lesson_id` CHAR(36) NOT NULL,
- `title` VARCHAR(155) NOT NULL,
- `estimated_duration` INTEGER(5) NOT NULL,
- `step_order` INTEGER(5) NOT NULL,
- `creation_date` timestamp NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-CREATE TABLE `step_challenges` (
- `id` CHAR(36) NOT NULL,
- `statement` TEXT NOT NULL,
- PRIMARY KEY (`id`),
- CONSTRAINT `fk_steps_challenges__step_id` FOREIGN KEY (`id`) REFERENCES `steps` (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-CREATE TABLE `step_quiz` (
- `id` CHAR(36) NOT NULL,
- `questions` TEXT NOT NULL,
- PRIMARY KEY (`id`),
- CONSTRAINT `fk_steps_quiz__step_id` FOREIGN KEY (`id`) REFERENCES `steps` (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-
-CREATE TABLE `step_video` (
- `id` CHAR(36) NOT NULL,
- `url` VARCHAR(255) NOT NULL,
- `text` TEXT NOT NULL,
- PRIMARY KEY (`id`),
- CONSTRAINT `fk_steps_video__step_id` FOREIGN KEY (`id`) REFERENCES `steps` (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
diff --git a/docker-compose.yml b/docker-compose.yml
index 22fde7377..19fc0366b 100755
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,49 +1,107 @@
version: '3'
services:
- nginx:
- container_name: codelytv-cqrs_ddd_php_example-nginx
- image: nginx:1.15-alpine
+ shared_rabbitmq:
+ container_name: codely-php_ddd_skeleton-rabbitmq
+ image: 'rabbitmq:3.10.5-management'
restart: unless-stopped
ports:
- - "8030:80"
+ - "5630:5672"
+ - "8090:15672"
+ environment:
+ - RABBITMQ_DEFAULT_USER=codely
+ - RABBITMQ_DEFAULT_PASS=c0d3ly
+
+ shared_prometheus:
+ container_name: codely-php_ddd_skeleton-prometheus
+ image: prom/prometheus:v2.36.1
volumes:
- - .:/app:delegated
- - ./etc/infrastructure/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
- depends_on:
- - php
+ - ./etc/prometheus/:/etc/prometheus/
+ command:
+ - '--config.file=/etc/prometheus/prometheus.yml'
+ - '--storage.tsdb.path=/prometheus'
+ - '--web.console.libraries=/usr/share/prometheus/console_libraries'
+ - '--web.console.templates=/usr/share/prometheus/consoles'
+ ports:
+ - "9999:9090"
+
+ mooc_mysql:
+ container_name: codely-php_ddd_skeleton-mooc-mysql
+ image: mariadb:10.7.4
+ ports:
+ - "3360:3306"
+ environment:
+ - MYSQL_ROOT_PASSWORD=
+ - MYSQL_ALLOW_EMPTY_PASSWORD=yes
+ healthcheck:
+ test: ["CMD", "mysqladmin", "--user=root", "--password=", "--host=127.0.0.1", "ping", "--silent"]
+ interval: 2s
+ timeout: 10s
+ retries: 10
+ command: ["--default-authentication-plugin=mysql_native_password"]
- php:
- container_name: codelytv-cqrs_ddd_php_example-php
+ backoffice_elasticsearch:
+ container_name: codely-php_ddd_skeleton-backoffice-elastic
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.2.3
+ ports:
+ - "9200:9200"
+ - "9300:9300"
+ environment:
+ - discovery.type=single-node
+ - xpack.security.enabled=false
+ - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
+
+ backoffice_backend_php:
+ container_name: codely-php_ddd_skeleton-backoffice_backend-php
+ user: "${UID}:${GID}"
build:
context: .
dockerfile: Dockerfile
restart: unless-stopped
ports:
- - "9030:9001"
+ - "8040:8040"
+ - "9040:9001"
volumes:
- .:/app:delegated
- env_file:
- - .env
depends_on:
- - mysql
- - rabbitmq
+ - shared_rabbitmq
+ - shared_prometheus
+ - backoffice_elasticsearch
+ command: symfony serve --dir=apps/backoffice/backend/public --port=8040
- mysql:
- container_name: codelytv-cqrs_ddd_php_example-mysql
- image: mariadb:10.4
+ backoffice_frontend_php:
+ container_name: codely-php_ddd_skeleton-backoffice_frontend-php
+ user: "${UID}:${GID}"
+ build:
+ context: .
+ dockerfile: Dockerfile
restart: unless-stopped
ports:
- - "3330:3306"
- env_file:
- - .env
+ - "8041:8041"
+ - "9041:9001"
+ volumes:
+ - .:/app:delegated
+ depends_on:
+ - shared_rabbitmq
+ - shared_prometheus
+ - backoffice_elasticsearch
+ - mooc_mysql
+ command: symfony serve --dir=apps/backoffice/frontend/public --port=8041
- rabbitmq:
- container_name: codelytv-cqrs_ddd_php_example-rabbitmq
- image: 'rabbitmq:3.7-management'
+ mooc_backend_php:
+ container_name: codely-php_ddd_skeleton-mooc_backend-php
+ user: "${UID}:${GID}"
+ build:
+ context: .
+ dockerfile: Dockerfile
restart: unless-stopped
ports:
- - 5630:5672
- - 15630:15672
- env_file:
- - .env
+ - "8030:8030"
+ - "9030:9001"
+ volumes:
+ - .:/app:delegated
+ depends_on:
+ - shared_rabbitmq
+ - shared_prometheus
+ - mooc_mysql
+ command: symfony serve --dir=apps/mooc/backend/public --port=8030
diff --git a/ecs.php b/ecs.php
new file mode 100644
index 000000000..e3ed961ba
--- /dev/null
+++ b/ecs.php
@@ -0,0 +1,26 @@
+paths([__DIR__ . '/apps', __DIR__ . '/src', __DIR__ . '/tests', ]);
+
+ $ecsConfig->sets([CodingStyle::DEFAULT]);
+
+ $ecsConfig->skip([
+ FinalClassFixer::class => [
+ __DIR__ . '/apps/backoffice/backend/src/BackofficeBackendKernel.php',
+ __DIR__ . '/apps/backoffice/frontend/src/BackofficeFrontendKernel.php',
+ __DIR__ . '/apps/mooc/backend/src/MoocBackendKernel.php',
+ __DIR__ . '/src/Shared/Infrastructure/Bus/Event/InMemory/InMemorySymfonyEventBus.php',
+ ],
+ __DIR__ . '/apps/backoffice/backend/var',
+ __DIR__ . '/apps/backoffice/frontend/var',
+ __DIR__ . '/apps/mooc/backend/var',
+ __DIR__ . '/apps/mooc/frontend/var',
+ ]);
+};
diff --git a/etc/consume.sh b/etc/consume.sh
deleted file mode 100755
index b83a3b0ec..000000000
--- a/etc/consume.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env bash
-
-while :
- do
- ./../applications/api/bin/console codelytv:domain-events:consume increase_user_total_videos_created_on_video_created 100
- done
-
diff --git a/etc/databases/backoffice/courses.json b/etc/databases/backoffice/courses.json
new file mode 100644
index 000000000..bbf66139e
--- /dev/null
+++ b/etc/databases/backoffice/courses.json
@@ -0,0 +1,20 @@
+{
+ "mappings": {
+ "courses": {
+ "properties": {
+ "id": {
+ "type": "keyword",
+ "index": true
+ },
+ "name": {
+ "type": "text",
+ "index": true
+ },
+ "duration": {
+ "type": "text",
+ "index": true
+ }
+ }
+ }
+ }
+}
diff --git a/etc/databases/mooc.sql b/etc/databases/mooc.sql
new file mode 100644
index 000000000..1a094f827
--- /dev/null
+++ b/etc/databases/mooc.sql
@@ -0,0 +1,129 @@
+/* -------------------------
+ MOOC CONTEXT
+---------------------------- */
+
+-- Generic tables
+
+CREATE TABLE mutations (
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
+ table_name VARCHAR(255) NOT NULL,
+ operation ENUM ('INSERT', 'UPDATE', 'DELETE') NOT NULL,
+ old_value JSON NULL,
+ new_value JSON NULL,
+ mutation_timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE domain_events (
+ id CHAR(36) NOT NULL,
+ aggregate_id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ body JSON NOT NULL,
+ occurred_on TIMESTAMP NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+-- Aggregates tables
+
+CREATE TABLE courses (
+ id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ duration VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TRIGGER after_courses_insert
+ AFTER INSERT
+ ON courses
+ FOR EACH ROW
+BEGIN
+ INSERT INTO mutations (table_name, operation, new_value, mutation_timestamp)
+ VALUES ('courses', 'INSERT', JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration), NOW());
+END;
+
+CREATE TRIGGER after_courses_update
+ AFTER UPDATE
+ ON courses
+ FOR EACH ROW
+BEGIN
+ INSERT INTO mutations (table_name, operation, old_value, new_value, mutation_timestamp)
+ VALUES ('courses',
+ 'UPDATE',
+ JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration),
+ JSON_OBJECT('id', new.id, 'name', new.name, 'duration', new.duration),
+ NOW());
+END;
+
+CREATE TRIGGER after_courses_delete
+ AFTER DELETE
+ ON courses
+ FOR EACH ROW
+BEGIN
+ INSERT INTO mutations (table_name, operation, old_value, mutation_timestamp)
+ VALUES ('courses', 'DELETE', JSON_OBJECT('id', old.id, 'name', old.name, 'duration', old.duration), NOW());
+END;
+
+CREATE TABLE courses_counter (
+ id CHAR(36) NOT NULL,
+ total INT NOT NULL,
+ existing_courses JSON NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+INSERT INTO courses_counter (id, total, existing_courses)
+VALUES ("cdf26d7d-3deb-4e8c-9f73-4ac085a8d6f3", 0, "[]");
+
+CREATE TABLE steps (
+ id CHAR(36) NOT NULL,
+ title VARCHAR(255) NOT NULL,
+ duration INT NOT NULL,
+ type VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_video (
+ id CHAR(36) NOT NULL,
+ url VARCHAR(255) NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_exercise (
+ id CHAR(36) NOT NULL,
+ content VARCHAR(255) NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+CREATE TABLE steps_quiz (
+ id CHAR(36) NOT NULL,
+ questions TEXT NOT NULL,
+ FOREIGN KEY (id) REFERENCES steps(id) ON DELETE CASCADE
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
+
+
+/* -------------------------
+ BACKOFFICE CONTEXT
+---------------------------- */
+
+CREATE TABLE backoffice_courses (
+ id CHAR(36) NOT NULL,
+ name VARCHAR(255) NOT NULL,
+ duration VARCHAR(255) NOT NULL,
+ PRIMARY KEY (id)
+) ENGINE = InnoDB
+ DEFAULT CHARSET = utf8mb4
+ COLLATE = utf8mb4_unicode_ci;
diff --git a/etc/endpoints/backoffice_frontend.http b/etc/endpoints/backoffice_frontend.http
new file mode 100644
index 000000000..78b30022a
--- /dev/null
+++ b/etc/endpoints/backoffice_frontend.http
@@ -0,0 +1,19 @@
+# ELASTIC - Search
+POST localhost:9200/backoffice_courses/_search
+Content-Type: application/json
+
+{
+ "query": {
+ "term": {
+ "name": "Pepe"
+ }
+ }
+}
+
+###
+# ELASTIC - Search
+POST localhost:9200/backoffice_courses/_search
+Content-Type: application/json
+
+###
+
diff --git a/etc/endpoints/mooc_backend.http b/etc/endpoints/mooc_backend.http
new file mode 100644
index 000000000..070955a99
--- /dev/null
+++ b/etc/endpoints/mooc_backend.http
@@ -0,0 +1,10 @@
+# Create a course
+PUT localhost:8030/courses/{{$uuid}}
+Content-Type: application/json
+
+{
+ "name": "The best course",
+ "duration": "5 hours"
+}
+
+###
diff --git a/etc/hooks/install-hooks.sh b/etc/hooks/install-hooks.sh
deleted file mode 100755
index 6a901d9a5..000000000
--- a/etc/hooks/install-hooks.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-cd "$(dirname "$0")/../.."
-
-rm -rf .git/hooks
-
-ln -s ../etc/hooks .git/hooks
-chmod -R 777 etc/hooks/*
diff --git a/etc/hooks/pre-push b/etc/hooks/pre-push
deleted file mode 100755
index dcaa735d5..000000000
--- a/etc/hooks/pre-push
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/bin/bash
-
-# Checks if locally staged changes are formatted properly ignoring non-staged changes.
-# Install it with the `install-hooks.sh` script
-# Based on: https://gist.github.com/cvogt/2676ed6c6d1abafa3d6a
-
-PATH=$PATH:/usr/local/bin:/usr/local/sbin
-
-echo ""
-echo "Running pre-push hook⦠(you can omit this with --no-verify, but don't)"
-
-echo "* Moving to the project directoryβ¦"
-_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-DIR=$( echo $_DIR | sed 's/\/.git\/hooks$//' )
-
-echo "* Stashing non-staged changes so we avoid checking themβ¦"
-git diff --quiet
-hadNoNonStagedChanges=$?
-
-if ! [ $hadNoNonStagedChanges -eq 0 ]
-then
- git stash --keep-index -u > /dev/null
-fi
-
-echo "* Checking pre push conditions ('test' composer task)β¦"
-composer test > /dev/null
-canPush=$?
-
-if [ $canPush -ne 0 ]
-then
- echo " [KO] Error :("
-fi
-
-echo "* Applying the stash with the non-staged changesβ¦"
-if ! [ $hadNoNonStagedChanges -eq 0 ]
-then
- sleep 1 && git stash pop --index > /dev/null & # sleep because otherwise commit fails when this leads to a merge conflict
-fi
-
-# Final result
-echo ""
-
-if [ $canPush -eq 0 ]
-then
- echo "[OK] Your code will be pushed young Padawan"
- exit 0
-else
- echo "[KO] Cancelling push due to 'composer test' task error (run 'composer test' for more information)"
- exit 1
-fi
diff --git a/etc/http/status.http b/etc/http/status.http
deleted file mode 100644
index 94f147f2e..000000000
--- a/etc/http/status.http
+++ /dev/null
@@ -1,3 +0,0 @@
-GET http://localhost:8030/status
-
-###
diff --git a/etc/http/student.http b/etc/http/student.http
deleted file mode 100644
index 96a1dea60..000000000
--- a/etc/http/student.http
+++ /dev/null
@@ -1,9 +0,0 @@
-PUT http://localhost:8030/students/75b14bd7-7925-424c-9a69-29b89d2b44f9
-Content-Type: application/json
-{
-}
-
-###
-GET http://localhost:8030/students/75b14bd7-7925-424c-9a69-29b89d2b44f9
-
-###
diff --git a/etc/infrastructure/nginx/default.conf b/etc/infrastructure/nginx/default.conf
deleted file mode 100755
index 58a681ac3..000000000
--- a/etc/infrastructure/nginx/default.conf
+++ /dev/null
@@ -1,30 +0,0 @@
-server {
- listen 80;
- server_name localhost api.codelytv.localhost;
- root /app/applications/mooc_backend/web;
-
- error_log stderr;
- access_log stdout;
-
- rewrite ^/api\.php/?(.*)$ /$1 permanent;
-
- try_files $uri @rewriteapp;
-
- location @rewriteapp {
- rewrite ^(.*)$ /api.php/$1 last;
- }
-
- location ~ /\. {
- deny all;
- }
-
- location ~ ^/(api)\.php(/|$) {
- fastcgi_split_path_info ^(.+\.php)(/.*)$;
- include fastcgi_params;
- fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
- fastcgi_index api.php;
- send_timeout 1800;
- fastcgi_read_timeout 1800;
- fastcgi_pass php:9000;
- }
-}
diff --git a/etc/infrastructure/php/conf.d/apcu.ini b/etc/infrastructure/php/conf.d/apcu.ini
index 3fb1fc345..8fae9c5a0 100644
--- a/etc/infrastructure/php/conf.d/apcu.ini
+++ b/etc/infrastructure/php/conf.d/apcu.ini
@@ -1,3 +1,5 @@
+apc.enable_cli=1
+apc.enabled=1
apc.shm_segments=1
apc.shm_size=256M
apc.num_files_hint=7000
diff --git a/etc/infrastructure/php/conf.d/xdebug.ini b/etc/infrastructure/php/conf.d/xdebug.ini
index 8d7170a6e..d97b6a059 100644
--- a/etc/infrastructure/php/conf.d/xdebug.ini
+++ b/etc/infrastructure/php/conf.d/xdebug.ini
@@ -1,14 +1,15 @@
-zend_extension=xdebug.so
+zend_extension = xdebug.so
;Debugging
-xdebug.remote_enable = 1;
-xdebug.remote_connect_back = 1;
-xdebug.remote_autostart = 1;
-xdebug.remote_port = 9001;
+xdebug.mode=debug
+xdebug.start_with_request = yes
+xdebug.discover_client_host = yes
+xdebug.client_port = 9001
+xdebug.client_host = host.docker.internal
;Profiling
-xdebug.profiler_enable = 0;
-xdebug.profiler_enable_trigger = 1;
-xdebug.profiler_output_dir = "/tmp/xdebug";
+xdebug.mode=profile
+xdebug.start_with_request=trigger
-xdebug.max_nesting_level = 500;
+xdebug.output_dir = "/tmp/xdebug"
+xdebug.max_nesting_level = 500
diff --git a/etc/infrastructure/php/php.ini b/etc/infrastructure/php/php.ini
index dd77c36da..21ab98fdd 100644
--- a/etc/infrastructure/php/php.ini
+++ b/etc/infrastructure/php/php.ini
@@ -1,4 +1,4 @@
date.timezone = "UTC"
html_errors = "On"
display_errors = "On"
-error_reporting = E_ALL
\ No newline at end of file
+error_reporting = E_ALL
diff --git a/etc/phpstan/phpstan.neon b/etc/phpstan/phpstan.neon
deleted file mode 100644
index 34e294fb6..000000000
--- a/etc/phpstan/phpstan.neon
+++ /dev/null
@@ -1,13 +0,0 @@
-parameters:
- bootstrap: %currentWorkingDirectory%/vendor/autoload.php
- includes:
- - %currentWorkingDirectory%/vendor/phpstan/phpstan-mockery/extension.neon
- reportUnmatchedIgnoredErrors: false
- ignoreErrors:
- - '#Ternary operator condition is always true.#'
- - '#Static call to instance method CodelyTv.*#'
- - '#Strict comparison using === between.*#'
- - '#Call to an undefined method .*::shouldReceive#'
- - '#Call to an undefined method .*::shouldNotReceive#'
- - '#Parameter .*MockInterface given.#'
- - '#.*was not matched in reported errors.#'
diff --git a/etc/prometheus/prometheus.yml b/etc/prometheus/prometheus.yml
new file mode 100644
index 000000000..db505fd9d
--- /dev/null
+++ b/etc/prometheus/prometheus.yml
@@ -0,0 +1,21 @@
+scrape_configs:
+
+ - job_name: 'prometheus'
+ scrape_interval: 5s
+ static_configs:
+ - targets: ['localhost:9090']
+
+ - job_name: 'backoffice_backend'
+ scrape_interval: 5s
+ static_configs:
+ - targets: ['codelytv-php_ddd_skeleton-backoffice_backend-php:8040']
+
+ - job_name: 'backoffice_frontend'
+ scrape_interval: 5s
+ static_configs:
+ - targets: ['codelytv-php_ddd_skeleton-backoffice_frontend-php:8041']
+
+ - job_name: 'mooc_backend'
+ scrape_interval: 5s
+ static_configs:
+ - targets: ['codelytv-php_ddd_skeleton-mooc_backend-php:8030']
diff --git a/phpmd.xml b/phpmd.xml
new file mode 100644
index 000000000..dee5bbe84
--- /dev/null
+++ b/phpmd.xml
@@ -0,0 +1,48 @@
+
+
+
+ apps/*/*/var/*
+ *SimilarComparator*
+ *IsSimilar*
+
+ src/Shared/Infrastructure/Symfony/AddJsonBodyToRequestListener.php
+
+ tests/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBusTest.php
+
+ tests/Shared/Infrastructure/PhpUnit/UnitTestCase.php
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 000000000..4404d69b2
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,25 @@
+includes:
+ - vendor/phpat/phpat/extension.neon
+
+parameters:
+ level: 0
+ paths:
+ - ./apps
+ - ./src
+ - ./tests
+ excludePaths:
+ - ./apps/backoffice/backend/var
+ - ./apps/backoffice/frontend/var
+ - ./apps/mooc/backend/var
+ - ./apps/mooc/frontend/var
+
+services:
+ -
+ class: CodelyTv\Tests\Shared\SharedArchitectureTest
+ tags:
+ - phpat.test
+
+ -
+ class: CodelyTv\Tests\Mooc\MoocArchitectureTest
+ tags:
+ - phpat.test
diff --git a/phpunit.xml.dist b/phpunit.xml
similarity index 72%
rename from phpunit.xml.dist
rename to phpunit.xml
index 1cd153f28..06fda8b8b 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml
@@ -9,7 +9,7 @@
beStrictAboutChangesToGlobalState="true"
beStrictAboutTestsThatDoNotTestAnything="false"
beStrictAboutTodoAnnotatedTests="true"
- bootstrap="./applications/bootstrap.php"
+ bootstrap="./apps/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
@@ -24,17 +24,19 @@
-
+
-
- ./tests
+
+ ./tests/Backoffice
+
+
+ ./tests/Mooc
+
+
+ ./tests/Shared
-
-
-
-
diff --git a/psalm.xml b/psalm.xml
new file mode 100644
index 000000000..228b2ab7b
--- /dev/null
+++ b/psalm.xml
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 000000000..7ec25f27b
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,27 @@
+paths([
+ __DIR__ . '/apps',
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
+ ]);
+
+ $rectorConfig->sets([
+ LevelSetList::UP_TO_PHP_82,
+ SetList::TYPE_DECLARATION
+ ]);
+
+ $rectorConfig->skip([
+ __DIR__ . '/apps/backoffice/backend/var',
+ __DIR__ . '/apps/backoffice/frontend/var',
+ __DIR__ . '/apps/mooc/backend/var',
+ __DIR__ . '/apps/mooc/frontend/var',
+ ]);
+};
diff --git a/src/Analytics/DomainEvents/Application/Store/DomainEventStorer.php b/src/Analytics/DomainEvents/Application/Store/DomainEventStorer.php
new file mode 100644
index 000000000..22dfbb7ba
--- /dev/null
+++ b/src/Analytics/DomainEvents/Application/Store/DomainEventStorer.php
@@ -0,0 +1,28 @@
+repository->save($domainEvent);
+ }
+}
diff --git a/src/Analytics/DomainEvents/Application/Store/StoreDomainEventOnOccurred.php b/src/Analytics/DomainEvents/Application/Store/StoreDomainEventOnOccurred.php
new file mode 100644
index 000000000..5607d45ce
--- /dev/null
+++ b/src/Analytics/DomainEvents/Application/Store/StoreDomainEventOnOccurred.php
@@ -0,0 +1,32 @@
+eventId());
+ $aggregateId = new AnalyticsDomainEventAggregateId($event->aggregateId());
+ $name = new AnalyticsDomainEventName($event::eventName());
+ $body = new AnalyticsDomainEventBody($event->toPrimitives());
+
+ $this->storer->store($id, $aggregateId, $name, $body);
+ }
+}
diff --git a/src/Analytics/DomainEvents/Domain/AnalyticsDomainEvent.php b/src/Analytics/DomainEvents/Domain/AnalyticsDomainEvent.php
new file mode 100644
index 000000000..db3fe917e
--- /dev/null
+++ b/src/Analytics/DomainEvents/Domain/AnalyticsDomainEvent.php
@@ -0,0 +1,15 @@
+value;
+ }
+}
diff --git a/src/Analytics/DomainEvents/Domain/AnalyticsDomainEventId.php b/src/Analytics/DomainEvents/Domain/AnalyticsDomainEventId.php
new file mode 100644
index 000000000..6cfebcb7a
--- /dev/null
+++ b/src/Analytics/DomainEvents/Domain/AnalyticsDomainEventId.php
@@ -0,0 +1,9 @@
+username;
+ }
+
+ public function password(): string
+ {
+ return $this->password;
+ }
+}
diff --git a/src/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandler.php b/src/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandler.php
new file mode 100644
index 000000000..6278c023d
--- /dev/null
+++ b/src/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandler.php
@@ -0,0 +1,22 @@
+username());
+ $password = new AuthPassword($command->password());
+
+ $this->authenticator->authenticate($username, $password);
+ }
+}
diff --git a/src/Backoffice/Auth/Application/Authenticate/UserAuthenticator.php b/src/Backoffice/Auth/Application/Authenticate/UserAuthenticator.php
new file mode 100644
index 000000000..99bcf5dfe
--- /dev/null
+++ b/src/Backoffice/Auth/Application/Authenticate/UserAuthenticator.php
@@ -0,0 +1,35 @@
+repository->search($username);
+
+ if ($auth === null) {
+ throw new InvalidAuthUsername($username);
+ }
+
+ $this->ensureCredentialsAreValid($auth, $password);
+ }
+
+ private function ensureCredentialsAreValid(AuthUser $auth, AuthPassword $password): void
+ {
+ if (!$auth->passwordMatches($password)) {
+ throw new InvalidAuthCredentials($auth->username());
+ }
+ }
+}
diff --git a/src/Backoffice/Auth/Domain/AuthPassword.php b/src/Backoffice/Auth/Domain/AuthPassword.php
new file mode 100644
index 000000000..ec76483a7
--- /dev/null
+++ b/src/Backoffice/Auth/Domain/AuthPassword.php
@@ -0,0 +1,15 @@
+value() === $other->value();
+ }
+}
diff --git a/src/Backoffice/Auth/Domain/AuthRepository.php b/src/Backoffice/Auth/Domain/AuthRepository.php
new file mode 100644
index 000000000..49088ecd2
--- /dev/null
+++ b/src/Backoffice/Auth/Domain/AuthRepository.php
@@ -0,0 +1,10 @@
+password->isEquals($password);
+ }
+
+ public function username(): AuthUsername
+ {
+ return $this->username;
+ }
+}
diff --git a/src/Backoffice/Auth/Domain/AuthUsername.php b/src/Backoffice/Auth/Domain/AuthUsername.php
new file mode 100644
index 000000000..bc1f5b884
--- /dev/null
+++ b/src/Backoffice/Auth/Domain/AuthUsername.php
@@ -0,0 +1,9 @@
+ are invalid', $username->value()));
+ }
+}
diff --git a/src/Backoffice/Auth/Domain/InvalidAuthUsername.php b/src/Backoffice/Auth/Domain/InvalidAuthUsername.php
new file mode 100644
index 000000000..b120207cb
--- /dev/null
+++ b/src/Backoffice/Auth/Domain/InvalidAuthUsername.php
@@ -0,0 +1,15 @@
+ does not exists', $username->value()));
+ }
+}
diff --git a/src/Backoffice/Auth/Infrastructure/Persistence/InMemoryAuthRepository.php b/src/Backoffice/Auth/Infrastructure/Persistence/InMemoryAuthRepository.php
new file mode 100644
index 000000000..dea981f8a
--- /dev/null
+++ b/src/Backoffice/Auth/Infrastructure/Persistence/InMemoryAuthRepository.php
@@ -0,0 +1,27 @@
+ 'barbitas',
+ 'rafa' => 'pelazo',
+ ];
+
+ public function search(AuthUsername $username): ?AuthUser
+ {
+ $password = get($username->value(), self::USERS);
+
+ return $password !== null ? new AuthUser($username, new AuthPassword($password)) : null;
+ }
+}
diff --git a/src/Backoffice/Courses/Application/BackofficeCourseResponse.php b/src/Backoffice/Courses/Application/BackofficeCourseResponse.php
new file mode 100644
index 000000000..d7984b858
--- /dev/null
+++ b/src/Backoffice/Courses/Application/BackofficeCourseResponse.php
@@ -0,0 +1,25 @@
+id;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function duration(): string
+ {
+ return $this->duration;
+ }
+}
diff --git a/src/Backoffice/Courses/Application/BackofficeCoursesResponse.php b/src/Backoffice/Courses/Application/BackofficeCoursesResponse.php
new file mode 100644
index 000000000..489841794
--- /dev/null
+++ b/src/Backoffice/Courses/Application/BackofficeCoursesResponse.php
@@ -0,0 +1,22 @@
+courses = $courses;
+ }
+
+ public function courses(): array
+ {
+ return $this->courses;
+ }
+}
diff --git a/src/Backoffice/Courses/Application/Create/BackofficeCourseCreator.php b/src/Backoffice/Courses/Application/Create/BackofficeCourseCreator.php
new file mode 100644
index 000000000..8493f6a46
--- /dev/null
+++ b/src/Backoffice/Courses/Application/Create/BackofficeCourseCreator.php
@@ -0,0 +1,18 @@
+repository->save(new BackofficeCourse($id, $name, $duration));
+ }
+}
diff --git a/src/Backoffice/Courses/Application/Create/CreateBackofficeCourseOnCourseCreated.php b/src/Backoffice/Courses/Application/Create/CreateBackofficeCourseOnCourseCreated.php
new file mode 100644
index 000000000..06ecd9541
--- /dev/null
+++ b/src/Backoffice/Courses/Application/Create/CreateBackofficeCourseOnCourseCreated.php
@@ -0,0 +1,23 @@
+creator->create($event->aggregateId(), $event->name(), $event->duration());
+ }
+}
diff --git a/src/Backoffice/Courses/Application/SearchAll/AllBackofficeCoursesSearcher.php b/src/Backoffice/Courses/Application/SearchAll/AllBackofficeCoursesSearcher.php
new file mode 100644
index 000000000..8cb541d64
--- /dev/null
+++ b/src/Backoffice/Courses/Application/SearchAll/AllBackofficeCoursesSearcher.php
@@ -0,0 +1,31 @@
+toResponse(), $this->repository->searchAll()));
+ }
+
+ private function toResponse(): callable
+ {
+ return static fn (BackofficeCourse $course): BackofficeCourseResponse => new BackofficeCourseResponse(
+ $course->id(),
+ $course->name(),
+ $course->duration()
+ );
+ }
+}
diff --git a/src/Backoffice/Courses/Application/SearchAll/SearchAllBackofficeCoursesQuery.php b/src/Backoffice/Courses/Application/SearchAll/SearchAllBackofficeCoursesQuery.php
new file mode 100644
index 000000000..41df25386
--- /dev/null
+++ b/src/Backoffice/Courses/Application/SearchAll/SearchAllBackofficeCoursesQuery.php
@@ -0,0 +1,9 @@
+searcher->searchAll();
+ }
+}
diff --git a/src/Backoffice/Courses/Application/SearchByCriteria/BackofficeCoursesByCriteriaSearcher.php b/src/Backoffice/Courses/Application/SearchByCriteria/BackofficeCoursesByCriteriaSearcher.php
new file mode 100644
index 000000000..4ed2280a4
--- /dev/null
+++ b/src/Backoffice/Courses/Application/SearchByCriteria/BackofficeCoursesByCriteriaSearcher.php
@@ -0,0 +1,36 @@
+toResponse(), $this->repository->matching($criteria)));
+ }
+
+ private function toResponse(): callable
+ {
+ return static fn (BackofficeCourse $course): BackofficeCourseResponse => new BackofficeCourseResponse(
+ $course->id(),
+ $course->name(),
+ $course->duration()
+ );
+ }
+}
diff --git a/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQuery.php b/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQuery.php
new file mode 100644
index 000000000..3833cd4e5
--- /dev/null
+++ b/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQuery.php
@@ -0,0 +1,43 @@
+filters;
+ }
+
+ public function orderBy(): ?string
+ {
+ return $this->orderBy;
+ }
+
+ public function order(): ?string
+ {
+ return $this->order;
+ }
+
+ public function limit(): ?int
+ {
+ return $this->limit;
+ }
+
+ public function offset(): ?int
+ {
+ return $this->offset;
+ }
+}
diff --git a/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQueryHandler.php b/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQueryHandler.php
new file mode 100644
index 000000000..9be731db6
--- /dev/null
+++ b/src/Backoffice/Courses/Application/SearchByCriteria/SearchBackofficeCoursesByCriteriaQueryHandler.php
@@ -0,0 +1,23 @@
+filters());
+ $order = Order::fromValues($query->orderBy(), $query->order());
+
+ return $this->searcher->search($filters, $order, $query->limit(), $query->offset());
+ }
+}
diff --git a/src/Backoffice/Courses/Domain/BackofficeCourse.php b/src/Backoffice/Courses/Domain/BackofficeCourse.php
new file mode 100644
index 000000000..85bc4ea53
--- /dev/null
+++ b/src/Backoffice/Courses/Domain/BackofficeCourse.php
@@ -0,0 +1,41 @@
+ $this->id,
+ 'name' => $this->name,
+ 'duration' => $this->duration,
+ ];
+ }
+
+ public function id(): string
+ {
+ return $this->id;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function duration(): string
+ {
+ return $this->duration;
+ }
+}
diff --git a/src/Backoffice/Courses/Domain/BackofficeCourseRepository.php b/src/Backoffice/Courses/Domain/BackofficeCourseRepository.php
new file mode 100644
index 000000000..815a0a6b3
--- /dev/null
+++ b/src/Backoffice/Courses/Domain/BackofficeCourseRepository.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepository.php b/src/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepository.php
new file mode 100644
index 000000000..3a359ce41
--- /dev/null
+++ b/src/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepository.php
@@ -0,0 +1,40 @@
+persist($course->id(), $course->toPrimitives());
+ }
+
+ public function searchAll(): array
+ {
+ return map($this->toCourse(), $this->searchAllInElastic());
+ }
+
+ public function matching(Criteria $criteria): array
+ {
+ return map($this->toCourse(), $this->searchByCriteria($criteria));
+ }
+
+ protected function aggregateName(): string
+ {
+ return 'courses';
+ }
+
+ private function toCourse(): callable
+ {
+ return static fn (array $primitives): BackofficeCourse => BackofficeCourse::fromPrimitives($primitives);
+ }
+}
diff --git a/src/Backoffice/Courses/Infrastructure/Persistence/InMemoryCacheBackofficeCourseRepository.php b/src/Backoffice/Courses/Infrastructure/Persistence/InMemoryCacheBackofficeCourseRepository.php
new file mode 100644
index 000000000..d2d84c341
--- /dev/null
+++ b/src/Backoffice/Courses/Infrastructure/Persistence/InMemoryCacheBackofficeCourseRepository.php
@@ -0,0 +1,44 @@
+repository->save($course);
+ }
+
+ public function searchAll(): array
+ {
+ return empty(self::$allCoursesCache) ? $this->searchAllAndFillCache() : self::$allCoursesCache;
+ }
+
+ public function matching(Criteria $criteria): array
+ {
+ return get($criteria->serialize(), self::$matchingCache) ?: $this->searchMatchingAndFillCache($criteria);
+ }
+
+ private function searchAllAndFillCache(): array
+ {
+ return self::$allCoursesCache = $this->repository->searchAll();
+ }
+
+ private function searchMatchingAndFillCache(Criteria $criteria): array
+ {
+ return self::$matchingCache[$criteria->serialize()] = $this->repository->matching($criteria);
+ }
+}
diff --git a/src/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepository.php b/src/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepository.php
new file mode 100644
index 000000000..46891200b
--- /dev/null
+++ b/src/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepository.php
@@ -0,0 +1,31 @@
+persist($course);
+ }
+
+ public function searchAll(): array
+ {
+ return $this->repository(BackofficeCourse::class)->findAll();
+ }
+
+ public function matching(Criteria $criteria): array
+ {
+ $doctrineCriteria = DoctrineCriteriaConverter::convert($criteria);
+
+ return $this->repository(BackofficeCourse::class)->matching($doctrineCriteria)->toArray();
+ }
+}
diff --git a/src/Backoffice/README.md b/src/Backoffice/README.md
deleted file mode 100644
index 91a697616..000000000
--- a/src/Backoffice/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Here we'll have our Backoffice modules :)
diff --git a/src/Backoffice/Shared/Infrastructure/Symfony/DependencyInjection/backoffice_services.yaml b/src/Backoffice/Shared/Infrastructure/Symfony/DependencyInjection/backoffice_services.yaml
new file mode 100644
index 000000000..3260a112e
--- /dev/null
+++ b/src/Backoffice/Shared/Infrastructure/Symfony/DependencyInjection/backoffice_services.yaml
@@ -0,0 +1,16 @@
+services:
+ # Databases
+ # @todo this should be from backoffice, no mooc
+ Doctrine\ORM\EntityManager:
+ factory: [ CodelyTv\Mooc\Shared\Infrastructure\Doctrine\MoocEntityManagerFactory, create ]
+ arguments:
+ - driver: '%env(MOOC_DATABASE_DRIVER)%'
+ host: '%env(MOOC_DATABASE_HOST)%'
+ port: '%env(MOOC_DATABASE_PORT)%'
+ dbname: '%env(MOOC_DATABASE_NAME)%'
+ user: '%env(MOOC_DATABASE_USER)%'
+ password: '%env(MOOC_DATABASE_PASSWORD)%'
+ - '%env(APP_ENV)%'
+ tags:
+ - { name: codely.database_connection }
+ public: true
diff --git a/src/Mooc/Courses/Application/Create/CourseCreator.php b/src/Mooc/Courses/Application/Create/CourseCreator.php
index b34526983..12b07bed4 100644
--- a/src/Mooc/Courses/Application/Create/CourseCreator.php
+++ b/src/Mooc/Courses/Application/Create/CourseCreator.php
@@ -1,33 +1,25 @@
repository = $repository;
- $this->publisher = $publisher;
- }
+ public function __invoke(CourseId $id, CourseName $name, CourseDuration $duration): void
+ {
+ $course = Course::create($id, $name, $duration);
- public function create(CourseId $id, CourseTitle $title, CourseDescription $description): void
- {
- $course = Course::create($id, $title, $description);
-
- $this->repository->save($course);
-
- $this->publisher->publish(...$course->pullDomainEvents());
- }
+ $this->repository->save($course);
+ $this->bus->publish(...$course->pullDomainEvents());
+ }
}
diff --git a/src/Mooc/Courses/Application/Create/CreateCourseCommand.php b/src/Mooc/Courses/Application/Create/CreateCourseCommand.php
index a6e59b41f..e710c86a9 100644
--- a/src/Mooc/Courses/Application/Create/CreateCourseCommand.php
+++ b/src/Mooc/Courses/Application/Create/CreateCourseCommand.php
@@ -1,39 +1,27 @@
id = $id;
- $this->title = $title;
- $this->description = $description;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function title(): string
- {
- return $this->title;
- }
-
- public function description(): string
- {
- return $this->description;
- }
+ public function __construct(private string $id, private string $name, private string $duration) {}
+
+ public function id(): string
+ {
+ return $this->id;
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function duration(): string
+ {
+ return $this->duration;
+ }
}
diff --git a/src/Mooc/Courses/Application/Create/CreateCourseCommandHandler.php b/src/Mooc/Courses/Application/Create/CreateCourseCommandHandler.php
index cb91aa2f1..e4685c5cb 100644
--- a/src/Mooc/Courses/Application/Create/CreateCourseCommandHandler.php
+++ b/src/Mooc/Courses/Application/Create/CreateCourseCommandHandler.php
@@ -1,28 +1,24 @@
creator = $creator;
- }
+ public function __invoke(CreateCourseCommand $command): void
+ {
+ $id = new CourseId($command->id());
+ $name = new CourseName($command->name());
+ $duration = new CourseDuration($command->duration());
- public function __invoke(CreateCourseCommand $command): void
- {
- $id = new CourseId($command->id());
- $title = new CourseTitle($command->title());
- $description = new CourseDescription($command->description());
-
- $this->creator->create($id, $title, $description);
- }
+ $this->creator->__invoke($id, $name, $duration);
+ }
}
diff --git a/src/Mooc/Courses/Application/Find/CourseFinder.php b/src/Mooc/Courses/Application/Find/CourseFinder.php
new file mode 100644
index 000000000..695e2aef7
--- /dev/null
+++ b/src/Mooc/Courses/Application/Find/CourseFinder.php
@@ -0,0 +1,26 @@
+repository->search($id);
+
+ if ($course === null) {
+ throw new CourseNotExist($id);
+ }
+
+ return $course;
+ }
+}
diff --git a/src/Mooc/Courses/Application/Update/CourseRenamer.php b/src/Mooc/Courses/Application/Update/CourseRenamer.php
new file mode 100644
index 000000000..77c8632d4
--- /dev/null
+++ b/src/Mooc/Courses/Application/Update/CourseRenamer.php
@@ -0,0 +1,31 @@
+finder = new CourseFinder($repository);
+ }
+
+ public function __invoke(CourseId $id, CourseName $newName): void
+ {
+ $course = $this->finder->__invoke($id);
+
+ $course->rename($newName);
+
+ $this->repository->save($course);
+ $this->bus->publish(...$course->pullDomainEvents());
+ }
+}
diff --git a/src/Mooc/Courses/Domain/Course.php b/src/Mooc/Courses/Domain/Course.php
index 4a46bbcb8..854ecdd4e 100644
--- a/src/Mooc/Courses/Domain/Course.php
+++ b/src/Mooc/Courses/Domain/Course.php
@@ -1,6 +1,6 @@
id = $id;
- $this->title = $title;
- $this->description = $description;
- }
-
- public static function create(CourseId $id, CourseTitle $title, CourseDescription $description): Course
- {
- $course = new self($id, $title, $description);
-
- $course->record(
- new CourseCreatedDomainEvent(
- $id,
- [
- 'title' => $title->value(),
- 'description' => $description->value(),
- ]
- )
- );
-
- return $course;
- }
-
- public function id(): CourseId
- {
- return $this->id;
- }
-
- public function title(): CourseTitle
- {
- return $this->title;
- }
-
- public function description(): CourseDescription
- {
- return $this->description;
- }
+ public function __construct(private readonly CourseId $id, private CourseName $name, private readonly CourseDuration $duration) {}
+
+ public static function create(CourseId $id, CourseName $name, CourseDuration $duration): self
+ {
+ $course = new self($id, $name, $duration);
+
+ $course->record(new CourseCreatedDomainEvent($id->value(), $name->value(), $duration->value()));
+
+ return $course;
+ }
+
+ public function id(): CourseId
+ {
+ return $this->id;
+ }
+
+ public function name(): CourseName
+ {
+ return $this->name;
+ }
+
+ public function duration(): CourseDuration
+ {
+ return $this->duration;
+ }
+
+ public function rename(CourseName $newName): void
+ {
+ $this->name = $newName;
+ }
}
diff --git a/src/Mooc/Courses/Domain/CourseCreatedDomainEvent.php b/src/Mooc/Courses/Domain/CourseCreatedDomainEvent.php
index 75ed574c1..69e89f799 100644
--- a/src/Mooc/Courses/Domain/CourseCreatedDomainEvent.php
+++ b/src/Mooc/Courses/Domain/CourseCreatedDomainEvent.php
@@ -1,6 +1,6 @@
['string'],
- 'description' => ['string'],
- ];
- }
+ public function __construct(
+ string $id,
+ private readonly string $name,
+ private readonly string $duration,
+ string $eventId = null,
+ string $occurredOn = null
+ ) {
+ parent::__construct($id, $eventId, $occurredOn);
+ }
+
+ public static function eventName(): string
+ {
+ return 'course.created';
+ }
+
+ public static function fromPrimitives(
+ string $aggregateId,
+ array $body,
+ string $eventId,
+ string $occurredOn
+ ): DomainEvent {
+ return new self($aggregateId, $body['name'], $body['duration'], $eventId, $occurredOn);
+ }
+
+ public function toPrimitives(): array
+ {
+ return [
+ 'name' => $this->name,
+ 'duration' => $this->duration,
+ ];
+ }
+
+ public function name(): string
+ {
+ return $this->name;
+ }
+
+ public function duration(): string
+ {
+ return $this->duration;
+ }
}
diff --git a/src/Mooc/Courses/Domain/CourseTitle.php b/src/Mooc/Courses/Domain/CourseDuration.php
similarity index 57%
rename from src/Mooc/Courses/Domain/CourseTitle.php
rename to src/Mooc/Courses/Domain/CourseDuration.php
index 3bdf6b326..71a56484b 100644
--- a/src/Mooc/Courses/Domain/CourseTitle.php
+++ b/src/Mooc/Courses/Domain/CourseDuration.php
@@ -1,11 +1,9 @@
does not exist', $this->id->value());
+ }
+}
diff --git a/src/Mooc/Courses/Domain/CourseRepository.php b/src/Mooc/Courses/Domain/CourseRepository.php
index 885b4776e..338ad9500 100644
--- a/src/Mooc/Courses/Domain/CourseRepository.php
+++ b/src/Mooc/Courses/Domain/CourseRepository.php
@@ -1,10 +1,14 @@
persist($course);
- }
-}
diff --git a/src/Mooc/Courses/Infrastructure/Cdc/DatabaseMutationToCourseCreatedDomainEvent.php b/src/Mooc/Courses/Infrastructure/Cdc/DatabaseMutationToCourseCreatedDomainEvent.php
new file mode 100644
index 000000000..59f78fe54
--- /dev/null
+++ b/src/Mooc/Courses/Infrastructure/Cdc/DatabaseMutationToCourseCreatedDomainEvent.php
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseDuration.orm.xml b/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseDuration.orm.xml
new file mode 100644
index 000000000..19349c516
--- /dev/null
+++ b/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseDuration.orm.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseIdType.php b/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseIdType.php
new file mode 100644
index 000000000..389f9fb53
--- /dev/null
+++ b/src/Mooc/Courses/Infrastructure/Persistence/Doctrine/CourseIdType.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Courses/Infrastructure/Persistence/DoctrineCourseRepository.php b/src/Mooc/Courses/Infrastructure/Persistence/DoctrineCourseRepository.php
new file mode 100644
index 000000000..376c47039
--- /dev/null
+++ b/src/Mooc/Courses/Infrastructure/Persistence/DoctrineCourseRepository.php
@@ -0,0 +1,23 @@
+persist($course);
+ }
+
+ public function search(CourseId $id): ?Course
+ {
+ return $this->repository(Course::class)->find($id);
+ }
+}
diff --git a/src/Mooc/Courses/Infrastructure/Persistence/FileCourseRepository.php b/src/Mooc/Courses/Infrastructure/Persistence/FileCourseRepository.php
new file mode 100644
index 000000000..b6a15ecbd
--- /dev/null
+++ b/src/Mooc/Courses/Infrastructure/Persistence/FileCourseRepository.php
@@ -0,0 +1,31 @@
+fileName($course->id()->value()), serialize($course));
+ }
+
+ public function search(CourseId $id): ?Course
+ {
+ return file_exists($this->fileName($id->value()))
+ ? unserialize(file_get_contents($this->fileName($id->value())))
+ : null;
+ }
+
+ private function fileName(string $id): string
+ {
+ return sprintf('%s.%s.repo', self::FILE_PATH, $id);
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Application/Find/CoursesCounterFinder.php b/src/Mooc/CoursesCounter/Application/Find/CoursesCounterFinder.php
new file mode 100644
index 000000000..000422643
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Application/Find/CoursesCounterFinder.php
@@ -0,0 +1,24 @@
+repository->search();
+
+ if ($counter === null) {
+ throw new CoursesCounterNotExist();
+ }
+
+ return new CoursesCounterResponse($counter->total()->value());
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Application/Find/CoursesCounterResponse.php b/src/Mooc/CoursesCounter/Application/Find/CoursesCounterResponse.php
new file mode 100644
index 000000000..21e8a0811
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Application/Find/CoursesCounterResponse.php
@@ -0,0 +1,17 @@
+total;
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQuery.php b/src/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQuery.php
new file mode 100644
index 000000000..4be728c05
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQuery.php
@@ -0,0 +1,9 @@
+finder->__invoke();
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Application/Increment/CoursesCounterIncrementer.php b/src/Mooc/CoursesCounter/Application/Increment/CoursesCounterIncrementer.php
new file mode 100644
index 000000000..b1131d11d
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Application/Increment/CoursesCounterIncrementer.php
@@ -0,0 +1,38 @@
+repository->search() ?: $this->initializeCounter();
+
+ if (!$counter->hasIncremented($courseId)) {
+ $counter->increment($courseId);
+
+ $this->repository->save($counter);
+ $this->bus->publish(...$counter->pullDomainEvents());
+ }
+ }
+
+ private function initializeCounter(): CoursesCounter
+ {
+ return CoursesCounter::initialize(new CoursesCounterId($this->uuidGenerator->generate()));
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreated.php b/src/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreated.php
new file mode 100644
index 000000000..d561d7686
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreated.php
@@ -0,0 +1,28 @@
+aggregateId());
+
+ apply($this->incrementer, [$courseId]);
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Domain/CoursesCounter.php b/src/Mooc/CoursesCounter/Domain/CoursesCounter.php
new file mode 100644
index 000000000..3d89a5da0
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Domain/CoursesCounter.php
@@ -0,0 +1,63 @@
+existingCourses = $existingCourses;
+ }
+
+ public static function initialize(CoursesCounterId $id): self
+ {
+ return new self($id, CoursesCounterTotal::initialize());
+ }
+
+ public function id(): CoursesCounterId
+ {
+ return $this->id;
+ }
+
+ public function total(): CoursesCounterTotal
+ {
+ return $this->total;
+ }
+
+ public function existingCourses(): array
+ {
+ return $this->existingCourses;
+ }
+
+ public function increment(CourseId $courseId): void
+ {
+ $this->total = $this->total->increment();
+ $this->existingCourses[] = $courseId;
+
+ $this->record(new CoursesCounterIncrementedDomainEvent($this->id()->value(), $this->total()->value()));
+ }
+
+ public function hasIncremented(CourseId $courseId): bool
+ {
+ $existingCourse = search($this->courseIdComparator($courseId), $this->existingCourses());
+
+ return $existingCourse !== null;
+ }
+
+ private function courseIdComparator(CourseId $courseId): callable
+ {
+ return static fn (CourseId $other): bool => $courseId->equals($other);
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Domain/CoursesCounterId.php b/src/Mooc/CoursesCounter/Domain/CoursesCounterId.php
new file mode 100644
index 000000000..16d0461e9
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Domain/CoursesCounterId.php
@@ -0,0 +1,9 @@
+ $this->total,
+ ];
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Domain/CoursesCounterNotExist.php b/src/Mooc/CoursesCounter/Domain/CoursesCounterNotExist.php
new file mode 100644
index 000000000..a882cdc38
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Domain/CoursesCounterNotExist.php
@@ -0,0 +1,15 @@
+value() + 1);
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CourseCounterIdType.php b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CourseCounterIdType.php
new file mode 100644
index 000000000..6a2c5d95a
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CourseCounterIdType.php
@@ -0,0 +1,16 @@
+ $id->value(), $value), $platform);
+ }
+
+ public function convertToPHPValue($value, AbstractPlatform $platform): array
+ {
+ $scalars = parent::convertToPHPValue($value, $platform);
+
+ return map(fn (string $value): CourseId => new CourseId($value), $scalars);
+ }
+}
diff --git a/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounter.orm.xml b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounter.orm.xml
new file mode 100644
index 000000000..d3d2d09c6
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounter.orm.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounterTotal.orm.xml b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounterTotal.orm.xml
new file mode 100644
index 000000000..ad9799fe7
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Infrastructure/Persistence/Doctrine/CoursesCounterTotal.orm.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/CoursesCounter/Infrastructure/Persistence/DoctrineCoursesCounterRepository.php b/src/Mooc/CoursesCounter/Infrastructure/Persistence/DoctrineCoursesCounterRepository.php
new file mode 100644
index 000000000..64622b072
--- /dev/null
+++ b/src/Mooc/CoursesCounter/Infrastructure/Persistence/DoctrineCoursesCounterRepository.php
@@ -0,0 +1,22 @@
+persist($counter);
+ }
+
+ public function search(): ?CoursesCounter
+ {
+ return $this->repository(CoursesCounter::class)->findOneBy([]);
+ }
+}
diff --git a/src/Mooc/Lesson/Domain/Lesson.php b/src/Mooc/Lesson/Domain/Lesson.php
deleted file mode 100644
index 0bd38fcaf..000000000
--- a/src/Mooc/Lesson/Domain/Lesson.php
+++ /dev/null
@@ -1,80 +0,0 @@
-id = $id;
- $this->courseId = $courseId;
- $this->title = $title;
- $this->description = $description;
- $this->estimatedDuration = $estimatedDuration;
- $this->order = $order;
- $this->scheduledDate = $scheduledDate;
- $this->requireSubscription = $requireSubscription;
- }
-
- public function id(): LessonId
- {
- return $this->id;
- }
-
- public function courseId(): CourseId
- {
- return $this->courseId;
- }
-
- public function title(): LessonTitle
- {
- return $this->title;
- }
-
- public function description(): LessonDescription
- {
- return $this->description;
- }
-
- public function estimatedDuration(): LessonEstimatedDuration
- {
- return $this->estimatedDuration;
- }
-
- public function order(): LessonOrder
- {
- return $this->order;
- }
-
- public function scheduledDate(): LessonScheduledDate
- {
- return $this->scheduledDate;
- }
-
- public function requireSubscription(): bool
- {
- return $this->requireSubscription;
- }
-}
diff --git a/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreated.php b/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreated.php
deleted file mode 100644
index 29a483e4c..000000000
--- a/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreated.php
+++ /dev/null
@@ -1,34 +0,0 @@
-creator = $creator;
- }
-
- public static function subscribedTo(): array
- {
- return [VideoCreatedDomainEvent::class];
- }
-
- public function __invoke(VideoCreatedDomainEvent $event)
- {
- $text = new NotificationText($event->title());
- $action = NotificationType::videoCreated();
-
- apply($this->creator, [$text, $action]);
- }
-}
diff --git a/src/Mooc/Notifications/Application/Create/NotificationCreator.php b/src/Mooc/Notifications/Application/Create/NotificationCreator.php
deleted file mode 100644
index 6514fee45..000000000
--- a/src/Mooc/Notifications/Application/Create/NotificationCreator.php
+++ /dev/null
@@ -1,35 +0,0 @@
-uuidGenerator = $uuidGenerator;
- $this->publisher = $publisher;
- }
-
- public function __invoke(NotificationText $text, NotificationType $action)
- {
- $id = new NotificationId($this->uuidGenerator->next());
-
- $notification = Notification::create($id, $text, $action);
-
- $this->publisher->publish(...$notification->pullDomainEvents());
- }
-}
diff --git a/src/Mooc/Notifications/Application/Send/NotificationSender.php b/src/Mooc/Notifications/Application/Send/NotificationSender.php
deleted file mode 100644
index fb5cc83e8..000000000
--- a/src/Mooc/Notifications/Application/Send/NotificationSender.php
+++ /dev/null
@@ -1,25 +0,0 @@
-notifier = $notifier;
- }
-
- public function __invoke(NotificationText $text, NotificationType $action)
- {
- $this->notifier->notify($text, $action);
- // @todo Send event
- }
-}
diff --git a/src/Mooc/Notifications/Application/Send/SendStaffNotificationOnNotificationCreated.php b/src/Mooc/Notifications/Application/Send/SendStaffNotificationOnNotificationCreated.php
deleted file mode 100644
index ec8b6bedc..000000000
--- a/src/Mooc/Notifications/Application/Send/SendStaffNotificationOnNotificationCreated.php
+++ /dev/null
@@ -1,33 +0,0 @@
-sender = $sender;
- }
-
- public static function subscribedTo(): array
- {
- return [NotificationCreatedDomainEvent::class];
- }
-
- public function __invoke(NotificationCreatedDomainEvent $event)
- {
- $text = new NotificationText($event->text());
- $type = new NotificationType($event->type());
-
- $this->sender->__invoke($text, $type);
- }
-}
diff --git a/src/Mooc/Notifications/Application/SendNewCommentReplyEmail/.gitkeep b/src/Mooc/Notifications/Application/SendNewCommentReplyEmail/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Mooc/Notifications/Application/SendNewCommentReplyPush/.gitkeep b/src/Mooc/Notifications/Application/SendNewCommentReplyPush/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Mooc/Notifications/Application/SendResetPasswordEmail/.gitkeep b/src/Mooc/Notifications/Application/SendResetPasswordEmail/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Mooc/Notifications/Domain/Notification.php b/src/Mooc/Notifications/Domain/Notification.php
deleted file mode 100644
index 161ba1641..000000000
--- a/src/Mooc/Notifications/Domain/Notification.php
+++ /dev/null
@@ -1,69 +0,0 @@
-id = $id;
- $this->text = $text;
- $this->type = $type;
- $this->hasBeenSent = $hasBeenSent;
- }
-
- public static function create(NotificationId $id, NotificationText $text, NotificationType $type): Notification
- {
- $notification = new self($id, $text, $type, false);
-
- $notification->record(
- new NotificationCreatedDomainEvent(
- $id->value(),
- [
- 'text' => $text->value(),
- 'type' => $type->value(),
- ]
- )
- );
-
- return $notification;
- }
-
- public function id(): NotificationId
- {
- return $this->id;
- }
-
- public function text(): NotificationText
- {
- return $this->text;
- }
-
- public function type(): NotificationType
- {
- return $this->type;
- }
-
- public function hasBeenSent(): bool
- {
- return $this->hasBeenSent;
- }
-
- public function markAsNotified(): void
- {
- $this->hasBeenSent = true;
- }
-}
diff --git a/src/Mooc/Notifications/Domain/NotificationCreatedDomainEvent.php b/src/Mooc/Notifications/Domain/NotificationCreatedDomainEvent.php
deleted file mode 100644
index 056db69bb..000000000
--- a/src/Mooc/Notifications/Domain/NotificationCreatedDomainEvent.php
+++ /dev/null
@@ -1,27 +0,0 @@
- ['string'],
- 'type' => ['string'],
- ];
- }
-}
diff --git a/src/Mooc/Notifications/Domain/NotificationFinder.php b/src/Mooc/Notifications/Domain/NotificationFinder.php
deleted file mode 100644
index 605cfa9ab..000000000
--- a/src/Mooc/Notifications/Domain/NotificationFinder.php
+++ /dev/null
@@ -1,26 +0,0 @@
-repository = $repository;
- }
-
- public function __invoke(NotificationId $id): Notification
- {
- $notification = $this->repository->search($id);
-
- if (null === $notification) {
- throw new NotificationNotFound($id);
- }
-
- return $notification;
- }
-}
diff --git a/src/Mooc/Notifications/Domain/NotificationId.php b/src/Mooc/Notifications/Domain/NotificationId.php
deleted file mode 100644
index 60142b059..000000000
--- a/src/Mooc/Notifications/Domain/NotificationId.php
+++ /dev/null
@@ -1,11 +0,0 @@
-id = $id;
- }
-
- public function errorCode(): string
- {
- return 'notification_not_found';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The notification <%s> has not been found', $this->id()->value());
- }
-
- public function id(): NotificationId
- {
- return $this->id;
- }
-}
diff --git a/src/Mooc/Notifications/Domain/NotificationRepository.php b/src/Mooc/Notifications/Domain/NotificationRepository.php
deleted file mode 100644
index 06fd1c998..000000000
--- a/src/Mooc/Notifications/Domain/NotificationRepository.php
+++ /dev/null
@@ -1,12 +0,0 @@
- is not a valid notification type', $value));
- }
-}
diff --git a/src/Mooc/Notifications/Domain/Notifier.php b/src/Mooc/Notifications/Domain/Notifier.php
deleted file mode 100644
index 62da0d431..000000000
--- a/src/Mooc/Notifications/Domain/Notifier.php
+++ /dev/null
@@ -1,10 +0,0 @@
- 'New video, yeah!',
- ];
- private $client;
-
- public function __construct(string $username, string $password)
- {
- $this->client = new GmailSwiftMailerEmailClient($username, $password);
- }
-
- public function notify(NotificationText $text, NotificationType $action): void
- {
- $from = new EmailAddress(self::NOTIFY_FROM);
- $to = new EmailAddress(self::NOTIFY_TO);
- $subject = get($action->value(), self::$subjects, self::UNKNOWN_NOTIFICATION);
-
- $this->client->send($from, $to, $subject, $text->value());
- }
-}
diff --git a/src/Mooc/Notifications/Infrastructure/Notifier/FakeNotifier.php b/src/Mooc/Notifications/Infrastructure/Notifier/FakeNotifier.php
deleted file mode 100644
index 8ddff734a..000000000
--- a/src/Mooc/Notifications/Infrastructure/Notifier/FakeNotifier.php
+++ /dev/null
@@ -1,17 +0,0 @@
-setUsername($username)
- ->setPassword($password);
-
- $this->mailer = Swift_Mailer::newInstance($transport);
- }
-
- public function send(EmailAddress $from, EmailAddress $to, string $subject, string $body): void
- {
- $message = Swift_Message::newInstance($subject)
- ->setFrom($from->value())
- ->setTo($to->value())
- ->setBody($body)
- ->setCharset('UTF-8');
-
- $this->mailer->send($message);
- }
-}
diff --git a/src/Mooc/Notifications/Infrastructure/Notifier/SlackNotifier.php b/src/Mooc/Notifications/Infrastructure/Notifier/SlackNotifier.php
deleted file mode 100644
index 4ceb99537..000000000
--- a/src/Mooc/Notifications/Infrastructure/Notifier/SlackNotifier.php
+++ /dev/null
@@ -1,36 +0,0 @@
- '(qββΏβq)',
- ];
- private $client;
-
- public function __construct(string $hookUrl, array $settings)
- {
- $this->client = new Client($hookUrl, $settings);
- }
-
- public function notify(NotificationText $text, NotificationType $action): void
- {
- $message = $this->client->createMessage();
-
- $message->setText(
- sprintf('%s %s', get($action->value(), self::$actionsFaces, self::UNKNOWN_NOTIFICATION), $text->value())
- );
-
- $this->client->sendMessage($message);
- }
-}
diff --git a/src/Mooc/Notifications/Infrastructure/Persistence/MySqlNotificationRepository.php b/src/Mooc/Notifications/Infrastructure/Persistence/MySqlNotificationRepository.php
deleted file mode 100644
index 0e72bcc10..000000000
--- a/src/Mooc/Notifications/Infrastructure/Persistence/MySqlNotificationRepository.php
+++ /dev/null
@@ -1,23 +0,0 @@
-repository(Notification::class)->find($id);
- }
-
- public function save(Notification $notification): void
- {
- $this->persist($notification);
- }
-}
diff --git a/src/Mooc/Shared/Domain/Courses/CourseId.php b/src/Mooc/Shared/Domain/Courses/CourseId.php
index c8620b084..ff6b551a8 100644
--- a/src/Mooc/Shared/Domain/Courses/CourseId.php
+++ b/src/Mooc/Shared/Domain/Courses/CourseId.php
@@ -1,11 +1,9 @@
ensureIsValidUrl($value);
+ public function __construct(string $value)
+ {
+ $this->ensureIsValidUrl($value);
- parent::__construct($value);
- }
+ parent::__construct($value);
+ }
- private function ensureIsValidUrl(string $url): void
- {
- if (false === filter_var($url, FILTER_VALIDATE_URL)) {
- throw new \InvalidArgumentException(sprintf('The url <%s> is not well formatted', $url));
- }
- }
+ private function ensureIsValidUrl(string $url): void
+ {
+ if (filter_var($url, FILTER_VALIDATE_URL) === false) {
+ throw new InvalidArgumentException(sprintf('The url <%s> is not well formatted', $url));
+ }
+ }
}
diff --git a/src/Mooc/Shared/Infrastructure/Doctrine/DbalTypesSearcher.php b/src/Mooc/Shared/Infrastructure/Doctrine/DbalTypesSearcher.php
new file mode 100644
index 000000000..28823de48
--- /dev/null
+++ b/src/Mooc/Shared/Infrastructure/Doctrine/DbalTypesSearcher.php
@@ -0,0 +1,69 @@
+ !in_array($possibleModule, ['.', '..'], true),
+ scandir($path)
+ );
+ }
+
+ private static function possibleDbalPaths(string $path): array
+ {
+ return map(
+ static function (mixed $_unused, string $module) use ($path) {
+ $mappingsPath = self::MAPPINGS_PATH;
+
+ return realpath("$path/$module/$mappingsPath");
+ },
+ array_flip(self::modulesInPath($path))
+ );
+ }
+
+ private static function isExistingDbalPath(): callable
+ {
+ return static fn (string $path): bool => !empty($path);
+ }
+
+ private static function dbalClassesSearcher(string $contextName): callable
+ {
+ return static function (array $totalNamespaces, string $path) use ($contextName): array {
+ $possibleFiles = scandir($path);
+ $files = filter(static fn (string $file): bool => str_ends_with($file, 'Type.php'), $possibleFiles);
+
+ $namespaces = map(
+ static function (string $file) use ($path, $contextName): string {
+ $fullPath = "$path/$file";
+ $splittedPath = explode("/src/$contextName/", $fullPath);
+
+ $classWithoutPrefix = str_replace(['.php', '/'], ['', '\\'], $splittedPath[1]);
+
+ return "CodelyTv\\$contextName\\$classWithoutPrefix";
+ },
+ $files
+ );
+
+ return array_merge($totalNamespaces, $namespaces);
+ };
+ }
+}
diff --git a/src/Mooc/Shared/Infrastructure/Doctrine/DoctrinePrefixesSearcher.php b/src/Mooc/Shared/Infrastructure/Doctrine/DoctrinePrefixesSearcher.php
new file mode 100644
index 000000000..85f65ed63
--- /dev/null
+++ b/src/Mooc/Shared/Infrastructure/Doctrine/DoctrinePrefixesSearcher.php
@@ -0,0 +1,52 @@
+ !in_array($possibleModule, ['.', '..'], true),
+ scandir($path)
+ );
+ }
+
+ private static function possibleMappingPaths(string $path): array
+ {
+ return map(
+ static function (mixed $_unused, string $module) use ($path) {
+ $mappingsPath = self::MAPPINGS_PATH;
+
+ return realpath("$path/$module/$mappingsPath");
+ },
+ array_flip(self::modulesInPath($path))
+ );
+ }
+
+ private static function isExistingMappingPath(): callable
+ {
+ return static fn (string $path): bool => !empty($path);
+ }
+
+ private static function namespaceFormatter(string $baseNamespace): callable
+ {
+ return static fn (string $path, string $module): string => "$baseNamespace\\$module\Domain";
+ }
+}
diff --git a/src/Mooc/Shared/Infrastructure/Doctrine/MoocEntityManagerFactory.php b/src/Mooc/Shared/Infrastructure/Doctrine/MoocEntityManagerFactory.php
index 3cfb476a0..71f0b4566 100644
--- a/src/Mooc/Shared/Infrastructure/Doctrine/MoocEntityManagerFactory.php
+++ b/src/Mooc/Shared/Infrastructure/Doctrine/MoocEntityManagerFactory.php
@@ -1,36 +1,33 @@
'Shared/Infrastructure/Persistence',
-
- 'Videos\Domain' => 'Videos/Infrastructure/Persistence',
- 'Students\Domain' => 'Students/Infrastructure/Persistence',
- 'Steps\Domain' => 'Steps/Infrastructure/Persistence',
- ];
-
- public static function create(array $parameters, $rootPath, $onDemand, $schemaFile): EntityManagerInterface
- {
- return DoctrineEntityManagerFactory::create(
- $parameters,
- self::getNormalizedPrefixes($rootPath),
- $onDemand,
- $schemaFile
- );
- }
-
- private static function getNormalizedPrefixes($rootPath)
- {
- return apply(new PrefixesNormalizer(realpath($rootPath), self::$namespace), [self::$prefixes]);
- }
+ private const SCHEMA_PATH = __DIR__ . '/../../../../../etc/databases/mooc.sql';
+
+ public static function create(array $parameters, string $environment): EntityManagerInterface
+ {
+ $isDevMode = $environment !== 'prod';
+
+ $prefixes = array_merge(
+ DoctrinePrefixesSearcher::inPath(__DIR__ . '/../../../../Mooc', 'CodelyTv\Mooc'),
+ DoctrinePrefixesSearcher::inPath(__DIR__ . '/../../../../Backoffice', 'CodelyTv\Backoffice')
+ );
+
+ $dbalCustomTypesClasses = DbalTypesSearcher::inPath(__DIR__ . '/../../../../Mooc', 'Mooc');
+
+ return DoctrineEntityManagerFactory::create(
+ $parameters,
+ $prefixes,
+ $isDevMode,
+ self::SCHEMA_PATH,
+ $dbalCustomTypesClasses
+ );
+ }
}
diff --git a/src/Mooc/Shared/Infrastructure/Doctrine/PrefixesNormalizer.php b/src/Mooc/Shared/Infrastructure/Doctrine/PrefixesNormalizer.php
deleted file mode 100644
index f617a8283..000000000
--- a/src/Mooc/Shared/Infrastructure/Doctrine/PrefixesNormalizer.php
+++ /dev/null
@@ -1,28 +0,0 @@
-path = $path;
- $this->namespacePrefix = $namespacePrefix ? $namespacePrefix . '\\' : '';
- }
-
- public function __invoke(array $prefixes)
- {
- $goodPrefixes = [];
-
- foreach ($prefixes as $className => $path) {
- $goodPrefixes[sprintf('%s/%s', $this->path, $path)] = sprintf('%s%s', $this->namespacePrefix, $className);
- }
-
- return $goodPrefixes;
- }
-}
diff --git a/src/Mooc/Shared/Infrastructure/Persistence/Videos.VideoUrl.orm.yml b/src/Mooc/Shared/Infrastructure/Persistence/Videos.VideoUrl.orm.yml
deleted file mode 100644
index 56f06c7ff..000000000
--- a/src/Mooc/Shared/Infrastructure/Persistence/Videos.VideoUrl.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Shared\Domain\Videos\VideoUrl:
- type: embeddable
-
- fields:
- value:
- type: string
- column: url
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/CodelyTvMoocBundle.php b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/CodelyTvMoocBundle.php
deleted file mode 100644
index 4fd982de3..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/CodelyTvMoocBundle.php
+++ /dev/null
@@ -1,23 +0,0 @@
-addCompilerPass(new DomainEventSubscribersConfigurationCompilerPass('codely.mooc.subscriber'));
- $container->addCompilerPass(new DatabasesConnectionCompilerPass('codely.mooc.database'));
- $container->addCompilerPass(new TransactionalServiceCompilerPass('codely.mooc.domain_event_publisher'));
- }
-}
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/CodelyTvMoocExtension.php b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/CodelyTvMoocExtension.php
deleted file mode 100644
index 62501f990..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/CodelyTvMoocExtension.php
+++ /dev/null
@@ -1,28 +0,0 @@
-registerForAutoconfiguration(CommandHandler::class)->addTag('codely.mooc.command');
- $container->registerForAutoconfiguration(QueryHandler::class)->addTag('codely.mooc.query');
- $container->registerForAutoconfiguration(DomainEventSubscriber::class)->addTag('codely.mooc.subscriber');
-
- $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/Resources'));
-
- $loader->load('mooc_extension.yml');
- $loader->load(sprintf('mooc_config_%s.yml', $container->getParameter('kernel.environment')));
- }
-}
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/_mooc_infrastructure.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/_mooc_infrastructure.yml
deleted file mode 100644
index b830e5967..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/_mooc_infrastructure.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-imports:
- - { resource: mooc_arranger.yml }
- - { resource: mooc_database.yml }
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_arranger.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_arranger.yml
deleted file mode 100644
index 434189d32..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_arranger.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-services:
-
- CodelyTv\Test\Mooc\Shared\Infrastructure\MoocEnvironmentArranger:
- autowire: true
- public: true
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_database.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_database.yml
deleted file mode 100644
index 545aedfb3..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure/mooc_database.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-services:
-
- Doctrine\ORM\EntityManager:
- factory: [CodelyTv\Mooc\Shared\Infrastructure\Doctrine\MoocEntityManagerFactory, create]
- arguments:
- - driver: '%mooc_database_driver%'
- host: '%mooc_database_host%'
- port: '%mooc_database_port%'
- dbname: '%mooc_database_name%'
- user: '%mooc_database_user%'
- password: '%mooc_database_password%'
- - '%codely.mooc.root_path%'
- - '%codely.mooc.infrastructure.database.on_demand%'
- - '%codely.mooc.infrastructure.database.schema_file%'
- tags:
- - { name: codely.mooc.database }
- public: true
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/modules/mooc_modules.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/modules/mooc_modules.yml
deleted file mode 100644
index bb666547d..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/modules/mooc_modules.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-services:
- _defaults:
- autoconfigure: true
- autowire: true
-
- CodelyTv\Mooc\:
- resource: '../../../../../../../*'
-
- # Notifications
- CodelyTv\Mooc\Notifications\Domain\Notifier: '@CodelyTv\Mooc\Notifications\Infrastructure\Notifier\SlackNotifier'
-
- CodelyTv\Mooc\Notifications\Infrastructure\Notifier\SlackNotifier:
- arguments:
- $hookUrl: '%slack_video_notification_hook_url%'
- $settings:
- - username: '%slack_video_notification_username%'
- channel: '%slack_video_notification_channel%'
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config.yml
deleted file mode 100644
index 2bc36609f..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-parameters:
-
- codely.mooc.root_path: '%kernel.root_dir%/../../src/Mooc/'
-
- codely.mooc.infrastructure.database.on_demand: false
- codely.mooc.infrastructure.database.schema_file: '%kernel.root_dir%/../../databases/mooc.sql'
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_dev.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_dev.yml
deleted file mode 100644
index 3daa5bfec..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_dev.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-imports:
- - { resource: mooc_config.yml }
-
-
-parameters:
- codely.mooc.infrastructure.database.on_demand: true
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_prod.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_prod.yml
deleted file mode 100644
index 825ac1180..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_prod.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - { resource: mooc_config.yml }
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_test.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_test.yml
deleted file mode 100644
index 9afb8501c..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_config_test.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-imports:
- - { resource: mooc_config_dev.yml }
-
-
-parameters:
- mooc_database_name: codely_mooc_tests_%kernel.name%
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_extension.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_extension.yml
deleted file mode 100644
index 94e48e21e..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_extension.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-imports:
- - { resource: mooc_parameters.yml }
- - { resource: infrastructure/_mooc_infrastructure.yml }
- - { resource: modules/mooc_modules.yml }
- - { resource: services/_mooc_services.yml }
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_parameters.yml.dist b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_parameters.yml.dist
deleted file mode 100644
index 7dcfc615e..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/mooc_parameters.yml.dist
+++ /dev/null
@@ -1,15 +0,0 @@
-parameters:
-
- mooc_database_driver: pdo_mysql
- mooc_database_host: '%env(MYSQL_HOST)%'
- mooc_database_port: '%env(MYSQL_PORT)%'
- mooc_database_name: codely_video
- mooc_database_user: root
- mooc_database_password: '%env(MYSQL_ROOT_PASSWORD)%'
-
- video_notification_email_username: 'your@email.com'
- video_notification_email_password: 'yourSecretPassword'
-
- slack_video_notification_hook_url: 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
- slack_video_notification_username: 'YourUsername'
- slack_video_notification_channel: '#your_cannel'
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/services/_mooc_services.yml b/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/services/_mooc_services.yml
deleted file mode 100644
index 87dc48a7c..000000000
--- a/src/Mooc/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/services/_mooc_services.yml
+++ /dev/null
@@ -1,22 +0,0 @@
-services:
-
- CodelyTv\Shared\Infrastructure\Bus\Command\SymfonySyncCommandBus:
- arguments: [!tagged codely.mooc.command]
- lazy: true
-
- CodelyTv\Shared\Infrastructure\Bus\Query\SymfonySyncQueryBus:
- arguments: [!tagged codely.mooc.query]
- lazy: true
-
- CodelyTv\Shared\Infrastructure\Bus\Event\SymfonySyncEventBus:
- arguments: [!tagged codely.mooc.subscriber]
- lazy: true
- public: true
-
- CodelyTv\Shared\Infrastructure\Bus\Event\SymfonySyncDomainEventPublisher:
- lazy: true
- public: true
-
- CodelyTv\Shared\Domain\Bus\Event\DomainEventPublisher: '@CodelyTv\Shared\Infrastructure\Bus\Event\SymfonySyncDomainEventPublisher'
- CodelyTv\Shared\Domain\Bus\Command\CommandBus: '@CodelyTv\Shared\Infrastructure\Bus\Command\SymfonySyncCommandBus'
- CodelyTv\Shared\Domain\Bus\Query\QueryBus: '@CodelyTv\Shared\Infrastructure\Bus\Query\SymfonySyncQueryBus'
diff --git a/src/Mooc/Shared/Infrastructure/Symfony/DependencyInjection/mooc_services.yaml b/src/Mooc/Shared/Infrastructure/Symfony/DependencyInjection/mooc_services.yaml
new file mode 100644
index 000000000..fa4f5522b
--- /dev/null
+++ b/src/Mooc/Shared/Infrastructure/Symfony/DependencyInjection/mooc_services.yaml
@@ -0,0 +1,19 @@
+services:
+ # Databases
+ Doctrine\ORM\EntityManager:
+ factory: [ CodelyTv\Mooc\Shared\Infrastructure\Doctrine\MoocEntityManagerFactory, create ]
+ arguments:
+ - driver: '%env(MOOC_DATABASE_DRIVER)%'
+ host: '%env(MOOC_DATABASE_HOST)%'
+ port: '%env(MOOC_DATABASE_PORT)%'
+ dbname: '%env(MOOC_DATABASE_NAME)%'
+ user: '%env(MOOC_DATABASE_USER)%'
+ password: '%env(MOOC_DATABASE_PASSWORD)%'
+ - '%env(APP_ENV)%'
+ tags:
+ - { name: codely.database_connection }
+ public: true
+
+
+ # Courses
+ CodelyTv\Mooc\Courses\Domain\CourseRepository: '@CodelyTv\Mooc\Courses\Infrastructure\Persistence\DoctrineCourseRepository'
diff --git a/src/Mooc/Steps/Application/Create/CreateStepCommandHandler.php b/src/Mooc/Steps/Application/Create/CreateStepCommandHandler.php
deleted file mode 100644
index 3e7275490..000000000
--- a/src/Mooc/Steps/Application/Create/CreateStepCommandHandler.php
+++ /dev/null
@@ -1,26 +0,0 @@
-creator = $creator;
- }
-
- public function __invoke(CreateVideoCommand $command)
- {
- $id = new VideoId($command->id());
-
- $this->creator->__invoke($id);
- }
-}
diff --git a/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php
new file mode 100644
index 000000000..34c301890
--- /dev/null
+++ b/src/Mooc/Steps/Application/Create/CreateVideoStepCommandHandler.php
@@ -0,0 +1,14 @@
+repository = $repository;
- }
-
- public function __invoke(VideoId $id): void
- {
- // $this->repository->save()
- }
-}
diff --git a/src/Mooc/Steps/Application/Create/VideoStepCreator.php b/src/Mooc/Steps/Application/Create/VideoStepCreator.php
new file mode 100644
index 000000000..00a952308
--- /dev/null
+++ b/src/Mooc/Steps/Application/Create/VideoStepCreator.php
@@ -0,0 +1,14 @@
+statement = $statement;
- }
-
- public function points(): StepPoints
- {
- return new StepPoints(5);
- }
-
- public function statement(): ChallengeStepStatement
- {
- return $this->statement;
- }
-}
diff --git a/src/Mooc/Steps/Domain/Challenge/ChallengeStepStatement.php b/src/Mooc/Steps/Domain/Challenge/ChallengeStepStatement.php
deleted file mode 100644
index f2f111d8c..000000000
--- a/src/Mooc/Steps/Domain/Challenge/ChallengeStepStatement.php
+++ /dev/null
@@ -1,11 +0,0 @@
-questions = $questions;
- }
-
- public function points(): StepPoints
- {
- return new StepPoints(10);
- }
-
- public function questions(): array
- {
- return $this->questions;
- }
+ /** @var QuizStepQuestion[] */
+ private array $questions;
+
+ public function __construct(
+ StepId $id,
+ StepTitle $title,
+ StepDuration $duration,
+ QuizStepQuestion ...$questions
+ ) {
+ parent::__construct($id, $title, $duration);
+
+ $this->questions = $questions;
+ }
}
diff --git a/src/Mooc/Steps/Domain/Quiz/QuizStepAnswer.php b/src/Mooc/Steps/Domain/Quiz/QuizStepAnswer.php
deleted file mode 100644
index bdfd5a4ce..000000000
--- a/src/Mooc/Steps/Domain/Quiz/QuizStepAnswer.php
+++ /dev/null
@@ -1,40 +0,0 @@
-answer = $answer;
- $this->isCorrect = $isCorrect;
- }
-
- public function toValues(): array
- {
- return [
- 'answer' => $this->answer(),
- 'is_correct' => $this->isCorrect(),
- ];
- }
-
- public static function fromValues(array $values): self
- {
- return new self($values['answer'], $values['is_correct']);
- }
-
- public function answer(): string
- {
- return $this->answer;
- }
-
- public function isCorrect(): bool
- {
- return $this->isCorrect;
- }
-}
diff --git a/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
index 5541c185e..157172596 100644
--- a/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
+++ b/src/Mooc/Steps/Domain/Quiz/QuizStepQuestion.php
@@ -1,57 +1,22 @@
question = $question;
- $this->answers = $answers;
- }
-
- public function toValues(): array
- {
- return [
- 'question' => $this->question(),
- 'answers' => map($this->answerToValues(), $this->answers()),
- ];
- }
-
- public static function fromValues(array $values): self
- {
- return new self($values['question'], ...map(self::valuesToAnswer(), $values['answers']));
- }
-
- public function question(): string
- {
- return $this->question;
- }
+ public function __construct(private string $question, private array $answers) {}
- /** @return QuizStepAnswer[] */
- public function answers(): array
- {
- return $this->answers;
- }
+ public static function fromString(string $value): self
+ {
+ [$question, $answers] = explode('----', $value);
- private function answerToValues(): callable
- {
- return static function (QuizStepAnswer $answer): array {
- return $answer->toValues();
- };
- }
+ return new self($question, explode('****', $answers));
+ }
- private static function valuesToAnswer(): callable
- {
- return static function (array $values): QuizStepAnswer {
- return QuizStepAnswer::fromValues($values);
- };
- }
+ public function toString(): string
+ {
+ return $this->question . '----' . implode('****', $this->answers);
+ }
}
diff --git a/src/Mooc/Steps/Domain/Step.php b/src/Mooc/Steps/Domain/Step.php
index d379bdde3..b59277cde 100644
--- a/src/Mooc/Steps/Domain/Step.php
+++ b/src/Mooc/Steps/Domain/Step.php
@@ -1,67 +1,16 @@
id = $id;
- $this->lessonId = $lessonId;
- $this->title = $title;
- $this->estimatedDuration = $estimatedDuration;
- $this->order = $order;
- $this->creationDate = $creationDate;
- }
-
- public function id(): StepId
- {
- return $this->id;
- }
-
- public function lessonId(): LessonId
- {
- return $this->lessonId;
- }
-
- public function title(): StepTitle
- {
- return $this->title;
- }
-
- public function estimatedDuration(): StepEstimatedDuration
- {
- return $this->estimatedDuration;
- }
-
- abstract public function points(): StepPoints;
-
- public function order(): StepOrder
- {
- return $this->order;
- }
-
- public function creationDate(): DateTimeImmutable
- {
- return $this->creationDate;
- }
+ public function __construct(
+ public readonly StepId $id,
+ private readonly StepTitle $title,
+ private readonly StepDuration $duration
+ ) {}
}
diff --git a/src/Mooc/Steps/Domain/StepOrder.php b/src/Mooc/Steps/Domain/StepDuration.php
similarity index 57%
rename from src/Mooc/Steps/Domain/StepOrder.php
rename to src/Mooc/Steps/Domain/StepDuration.php
index 5e8aa151d..e3091e195 100644
--- a/src/Mooc/Steps/Domain/StepOrder.php
+++ b/src/Mooc/Steps/Domain/StepDuration.php
@@ -1,11 +1,9 @@
steps = $steps;
- }
-
-}
diff --git a/src/Mooc/Steps/Domain/Video/VideoStep.php b/src/Mooc/Steps/Domain/Video/VideoStep.php
index d1a3e3d13..82c36c34e 100644
--- a/src/Mooc/Steps/Domain/Video/VideoStep.php
+++ b/src/Mooc/Steps/Domain/Video/VideoStep.php
@@ -1,52 +1,22 @@
videoUrl = $videoUrl;
- $this->text = $text;
- }
-
- public function points(): StepPoints
- {
- return new StepPoints(100);
- }
-
- public function videoUrl(): VideoUrl
- {
- return $this->videoUrl;
- }
-
- public function text(): VideoStepText
- {
- return $this->text;
- }
+ public function __construct(
+ StepId $id,
+ StepTitle $title,
+ StepDuration $duration,
+ private readonly VideoStepUrl $url
+ ) {
+ parent::__construct($id, $title, $duration);
+ }
}
diff --git a/src/Mooc/Steps/Domain/Video/VideoStepText.php b/src/Mooc/Steps/Domain/Video/VideoStepUrl.php
similarity index 57%
rename from src/Mooc/Steps/Domain/Video/VideoStepText.php
rename to src/Mooc/Steps/Domain/Video/VideoStepUrl.php
index 6b6cc9f0d..17a4d81f7 100644
--- a/src/Mooc/Steps/Domain/Video/VideoStepText.php
+++ b/src/Mooc/Steps/Domain/Video/VideoStepUrl.php
@@ -1,11 +1,9 @@
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml
new file mode 100644
index 000000000..09e493da9
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Exercise.ExerciseStepContent.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml
new file mode 100644
index 000000000..4b116a567
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Quiz.QuizStep.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php
new file mode 100644
index 000000000..677fee748
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/QuizStepQuestionsType.php
@@ -0,0 +1,40 @@
+ $question->toString(), $value),
+ $platform
+ );
+ }
+
+ public function convertToPHPValue($value, AbstractPlatform $platform): array
+ {
+ $scalars = parent::convertToPHPValue($value, $platform);
+
+ return map(fn (string $value): QuizStepQuestion => QuizStepQuestion::fromString($value), $scalars);
+ }
+}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml
new file mode 100644
index 000000000..229add0ca
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Step.orm.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml
new file mode 100644
index 000000000..c13079530
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepDuration.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php
new file mode 100644
index 000000000..47b979668
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/StepIdType.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml
new file mode 100644
index 000000000..5302800f2
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStep.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml
new file mode 100644
index 000000000..a4141ba8f
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/Doctrine/Video.VideoStepUrl.orm.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php
new file mode 100644
index 000000000..45a1151d3
--- /dev/null
+++ b/src/Mooc/Steps/Infrastructure/Persistence/MySqlStepRepository.php
@@ -0,0 +1,28 @@
+persist($step);
+ }
+
+ public function search(StepId $id): ?Step
+ {
+ return $this->repository(Step::class)->find($id);
+ }
+
+ public function delete(Step $step): void
+ {
+ $this->remove($step);
+ }
+}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Quiz.QuizStep.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/Quiz.QuizStep.orm.yml
deleted file mode 100644
index 67f719f39..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/Quiz.QuizStep.orm.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\Quiz\QuizStep:
- type: entity
- table: step_quiz
-
- fields:
- questions:
- type: quiz_step_questions
- column: questions
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/QuizStepQuestionsType.php b/src/Mooc/Steps/Infrastructure/Persistence/QuizStepQuestionsType.php
deleted file mode 100644
index de4163de4..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/QuizStepQuestionsType.php
+++ /dev/null
@@ -1,45 +0,0 @@
-questionFromValues(), parent::convertToPHPValue($value, $platform));
- }
-
- /** @var QuizStepQuestion[] $value */
- public function convertToDatabaseValue($value, AbstractPlatform $platform)
- {
- return parent::convertToDatabaseValue(map($this->questionToValues(), $value), $platform);
- }
-
- private function questionFromValues(): callable
- {
- return static function (array $values): QuizStepQuestion {
- return QuizStepQuestion::fromValues($values);
- };
- }
-
- private function questionToValues(): callable
- {
- return static function (QuizStepQuestion $question): array {
- return $question->toValues();
- };
- }
-}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Step.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/Step.orm.yml
deleted file mode 100644
index f18135d9d..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/Step.orm.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\Step:
- type: entity
- inheritanceType: JOINED
- discriminatorColumn:
- name: type
- type: smallint
- discriminatorMap:
- 1: CodelyTv\Mooc\Steps\Domain\Challenge\ChallengeStep
- 2: CodelyTv\Mooc\Steps\Domain\Quiz\QuizStep
- 3: CodelyTv\Mooc\Steps\Domain\Video\VideoStep
- table: steps
-
- id:
- id:
- type: step_id
- length: 36
-
- fields:
- lessonId:
- type: lesson_id
- column: lesson_id
- creationDate:
- type: datetime_immutable
- column: creation_date
-
- embedded:
- title:
- class: CodelyTv\Mooc\Steps\Domain\StepTitle
- columnPrefix: false
- estimatedDuration:
- class: CodelyTv\Mooc\Steps\Domain\StepEstimatedDuration
- columnPrefix: false
- order:
- class: CodelyTv\Mooc\Steps\Domain\StepOrder
- columnPrefix: false
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/StepEstimatedDuration.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/StepEstimatedDuration.orm.yml
deleted file mode 100644
index 936b7d01c..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/StepEstimatedDuration.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\StepEstimatedDuration:
- type: embeddable
-
- fields:
- value:
- type: integer
- column: estimated_duration
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/StepIdType.php b/src/Mooc/Steps/Infrastructure/Persistence/StepIdType.php
deleted file mode 100644
index e8c98d653..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/StepIdType.php
+++ /dev/null
@@ -1,30 +0,0 @@
-value();
- }
-}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/StepOrder.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/StepOrder.orm.yml
deleted file mode 100644
index 38e8cbaf7..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/StepOrder.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\StepOrder:
- type: embeddable
-
- fields:
- value:
- type: integer
- column: step_order
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/StepRepositoryMySql.php b/src/Mooc/Steps/Infrastructure/Persistence/StepRepositoryMySql.php
deleted file mode 100644
index aa6c307aa..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/StepRepositoryMySql.php
+++ /dev/null
@@ -1,17 +0,0 @@
-persist($step);
- }
-}
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/StepTitle.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/StepTitle.orm.yml
deleted file mode 100644
index 80c5652d5..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/StepTitle.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\StepTitle:
- type: embeddable
-
- fields:
- value:
- type: string
- column: title
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStep.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStep.orm.yml
deleted file mode 100644
index b731651d6..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStep.orm.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\Video\VideoStep:
- type: entity
- table: step_video
-
- embedded:
- videoUrl:
- class: CodelyTv\Mooc\Shared\Domain\Videos\VideoUrl
- columnPrefix: false
- text:
- class: CodelyTv\Mooc\Steps\Domain\Video\VideoStepText
- columnPrefix: false
diff --git a/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStepText.orm.yml b/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStepText.orm.yml
deleted file mode 100644
index c121e90a2..000000000
--- a/src/Mooc/Steps/Infrastructure/Persistence/Video.VideoStepText.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Steps\Domain\Video\VideoStepText:
- type: embeddable
-
- fields:
- value:
- type: string
- column: text
diff --git a/src/Mooc/Students/Application/Find/FindStudentQuery.php b/src/Mooc/Students/Application/Find/FindStudentQuery.php
deleted file mode 100644
index c72b36a65..000000000
--- a/src/Mooc/Students/Application/Find/FindStudentQuery.php
+++ /dev/null
@@ -1,22 +0,0 @@
-id = $id;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-}
diff --git a/src/Mooc/Students/Application/Find/FindStudentQueryHandler.php b/src/Mooc/Students/Application/Find/FindStudentQueryHandler.php
deleted file mode 100644
index ddb39fa52..000000000
--- a/src/Mooc/Students/Application/Find/FindStudentQueryHandler.php
+++ /dev/null
@@ -1,27 +0,0 @@
-finder = pipe($finder, new StudentResponseConverter());
- }
-
- public function __invoke(FindStudentQuery $query): StudentResponse
- {
- $id = new StudentId($query->id());
-
- return apply($this->finder, [$id]);
- }
-}
diff --git a/src/Mooc/Students/Application/Find/StudentFinder.php b/src/Mooc/Students/Application/Find/StudentFinder.php
deleted file mode 100644
index f13e38f4e..000000000
--- a/src/Mooc/Students/Application/Find/StudentFinder.php
+++ /dev/null
@@ -1,31 +0,0 @@
-repository = $repository;
- }
-
- public function __invoke(StudentId $id): Student
- {
- $student = $this->repository->search($id);
-
- if (null === $student) {
- throw new StudentNotExist($id);
- }
-
- return $student;
- }
-}
diff --git a/src/Mooc/Students/Application/Find/StudentResponse.php b/src/Mooc/Students/Application/Find/StudentResponse.php
deleted file mode 100644
index df6c1e6e2..000000000
--- a/src/Mooc/Students/Application/Find/StudentResponse.php
+++ /dev/null
@@ -1,36 +0,0 @@
-id = $id;
- $this->name = $name;
- $this->totalPendingVideos = $totalPendingVideos;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function name(): string
- {
- return $this->name;
- }
-
- public function totalPendingVideos(): int
- {
- return $this->totalPendingVideos;
- }
-}
diff --git a/src/Mooc/Students/Application/Find/StudentResponseConverter.php b/src/Mooc/Students/Application/Find/StudentResponseConverter.php
deleted file mode 100644
index 59a9f1203..000000000
--- a/src/Mooc/Students/Application/Find/StudentResponseConverter.php
+++ /dev/null
@@ -1,19 +0,0 @@
-id()->value(),
- $student->name()->value(),
- $student->totalVideosCreated()->value()
- );
- }
-}
diff --git a/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentTotalVideosCreatedOnVideoCreated.php b/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentTotalVideosCreatedOnVideoCreated.php
deleted file mode 100644
index 39ee832b1..000000000
--- a/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentTotalVideosCreatedOnVideoCreated.php
+++ /dev/null
@@ -1,32 +0,0 @@
-increaser = $increaser;
- }
-
- public static function subscribedTo(): array
- {
- return [ScalaVideoCreatedDomainEvent::class];
- }
-
- public function __invoke(ScalaVideoCreatedDomainEvent $event)
- {
- $id = new StudentId($event->creatorId());
-
- apply($this->increaser, [$id]);
- }
-}
diff --git a/src/Mooc/Students/Application/IncreasePendingVideos/StudentTotalVideosCreatedIncreaser.php b/src/Mooc/Students/Application/IncreasePendingVideos/StudentTotalVideosCreatedIncreaser.php
deleted file mode 100644
index 8ad8d01af..000000000
--- a/src/Mooc/Students/Application/IncreasePendingVideos/StudentTotalVideosCreatedIncreaser.php
+++ /dev/null
@@ -1,30 +0,0 @@
-finder = new StudentFinder($repository);
- $this->repository = $repository;
- }
-
- public function __invoke(StudentId $id)
- {
- $student = $this->finder->__invoke($id);
-
- $student->increaseTotalVideosCreated();
-
- $this->repository->save($student);
- }
-}
diff --git a/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEvent.php b/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEvent.php
deleted file mode 100644
index 4310f6e4a..000000000
--- a/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEvent.php
+++ /dev/null
@@ -1,25 +0,0 @@
- ['string'],
- ];
- }
-}
diff --git a/src/Mooc/Students/Domain/Student.php b/src/Mooc/Students/Domain/Student.php
deleted file mode 100644
index 9b5a1ff14..000000000
--- a/src/Mooc/Students/Domain/Student.php
+++ /dev/null
@@ -1,41 +0,0 @@
-id = $id;
- $this->name = $name;
- $this->totalVideosCreated = $totalVideosCreated;
- }
-
- public function id(): StudentId
- {
- return $this->id;
- }
-
- public function name(): StudentName
- {
- return $this->name;
- }
-
- public function totalVideosCreated(): StudentTotalVideosCreated
- {
- return $this->totalVideosCreated;
- }
-
- public function increaseTotalVideosCreated(): void
- {
- $this->totalVideosCreated = $this->totalVideosCreated->increase();
- }
-}
diff --git a/src/Mooc/Students/Domain/StudentId.php b/src/Mooc/Students/Domain/StudentId.php
deleted file mode 100644
index 123a2d24d..000000000
--- a/src/Mooc/Students/Domain/StudentId.php
+++ /dev/null
@@ -1,11 +0,0 @@
-id = $id;
-
- parent::__construct();
- }
-
- public function errorCode(): string
- {
- return 'student_not_exist';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The student <%s> does not exists', $this->id->value());
- }
-}
diff --git a/src/Mooc/Students/Domain/StudentRepository.php b/src/Mooc/Students/Domain/StudentRepository.php
deleted file mode 100644
index 9eec7c5de..000000000
--- a/src/Mooc/Students/Domain/StudentRepository.php
+++ /dev/null
@@ -1,16 +0,0 @@
-value() + 1);
- }
-}
diff --git a/src/Mooc/Students/Domain/Students.php b/src/Mooc/Students/Domain/Students.php
deleted file mode 100644
index 279a9d9ff..000000000
--- a/src/Mooc/Students/Domain/Students.php
+++ /dev/null
@@ -1,28 +0,0 @@
-pendingIncreaser(), $this);
- }
-
- private function pendingIncreaser(): callable
- {
- return function (Student $student): void {
- $student->increaseTotalVideosCreated();
- };
- }
-}
diff --git a/src/Mooc/Students/Infrastructure/Persistence/Student.orm.yml b/src/Mooc/Students/Infrastructure/Persistence/Student.orm.yml
deleted file mode 100644
index bf0c14ba4..000000000
--- a/src/Mooc/Students/Infrastructure/Persistence/Student.orm.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-CodelyTv\Mooc\Students\Domain\Student:
- type: entity
- table: students
-
- id:
- id:
- type: student_id
- column: id
- length: 36
-
- embedded:
- name:
- class: CodelyTv\Mooc\Students\Domain\StudentName
- columnPrefix: false
- totalVideosCreated:
- class: CodelyTv\Mooc\Students\Domain\StudentTotalVideosCreated
- columnPrefix: false
diff --git a/src/Mooc/Students/Infrastructure/Persistence/StudentIdType.php b/src/Mooc/Students/Infrastructure/Persistence/StudentIdType.php
deleted file mode 100644
index fb88fdd3c..000000000
--- a/src/Mooc/Students/Infrastructure/Persistence/StudentIdType.php
+++ /dev/null
@@ -1,31 +0,0 @@
-value();
- }
-}
-
diff --git a/src/Mooc/Students/Infrastructure/Persistence/StudentName.orm.yml b/src/Mooc/Students/Infrastructure/Persistence/StudentName.orm.yml
deleted file mode 100644
index 30a62029c..000000000
--- a/src/Mooc/Students/Infrastructure/Persistence/StudentName.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Students\Domain\StudentName:
- type: embeddable
-
- fields:
- value:
- type: string
- column: name
diff --git a/src/Mooc/Students/Infrastructure/Persistence/StudentRepositoryMySql.php b/src/Mooc/Students/Infrastructure/Persistence/StudentRepositoryMySql.php
deleted file mode 100644
index ed79bac53..000000000
--- a/src/Mooc/Students/Infrastructure/Persistence/StudentRepositoryMySql.php
+++ /dev/null
@@ -1,35 +0,0 @@
-persist($student);
- }
-
- public function saveAll(Students $students): void
- {
- each($this->persister(), $students);
- }
-
- public function search(StudentId $id): ?Student
- {
- return $this->repository(Student::class)->find($id);
- }
-
- public function all(): Students
- {
- return new Students($this->repository(Student::class)->findAll());
- }
-}
diff --git a/src/Mooc/Students/Infrastructure/Persistence/StudentTotalVideosCreated.orm.yml b/src/Mooc/Students/Infrastructure/Persistence/StudentTotalVideosCreated.orm.yml
deleted file mode 100644
index 89599338f..000000000
--- a/src/Mooc/Students/Infrastructure/Persistence/StudentTotalVideosCreated.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Students\Domain\StudentTotalVideosCreated:
- type: embeddable
-
- fields:
- value:
- type: integer
- column: total_videos_created
diff --git a/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandHandler.php b/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandHandler.php
deleted file mode 100644
index 0537b35bf..000000000
--- a/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandHandler.php
+++ /dev/null
@@ -1,29 +0,0 @@
-publisher = $publisher;
- }
-
- public function __invoke(PublishVideoCommentCommand $command)
- {
- $id = new VideoCommentId($command->id());
- $videoId = new VideoId($command->videoId());
- $content = new VideoCommentContent($command->content());
-
- $this->publisher->publish($id, $videoId, $content);
- }
-}
diff --git a/src/Mooc/VideoComments/Application/Publish/VideoCommentPublisher.php b/src/Mooc/VideoComments/Application/Publish/VideoCommentPublisher.php
deleted file mode 100644
index 36ea77dc6..000000000
--- a/src/Mooc/VideoComments/Application/Publish/VideoCommentPublisher.php
+++ /dev/null
@@ -1,44 +0,0 @@
-repository = $repository;
- $this->bus = $bus;
- $this->publisher = $publisher;
- }
-
- public function publish(VideoCommentId $id, VideoId $videoId, VideoCommentContent $content): void
- {
- $this->ensureVideoExist($videoId);
-
- $comment = VideoComment::publish($id, $videoId, $content);
-
- $this->repository->save($comment);
-
- $this->publisher->publish(...$comment->pullDomainEvents());
- }
-
- private function ensureVideoExist(VideoId $id): void
- {
- $this->bus->ask(new FindVideoQuery($id->value()));
- }
-}
diff --git a/src/Mooc/VideoComments/Contract/PublishVideoCommentCommand.php b/src/Mooc/VideoComments/Contract/PublishVideoCommentCommand.php
deleted file mode 100644
index 7613ba7fe..000000000
--- a/src/Mooc/VideoComments/Contract/PublishVideoCommentCommand.php
+++ /dev/null
@@ -1,39 +0,0 @@
-id = $id;
- $this->videoId = $videoId;
- $this->content = $content;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function videoId(): string
- {
- return $this->videoId;
- }
-
- public function content(): string
- {
- return $this->content;
- }
-}
diff --git a/src/Mooc/VideoComments/Contract/VideoCommentPublishedDomainEvent.php b/src/Mooc/VideoComments/Contract/VideoCommentPublishedDomainEvent.php
deleted file mode 100644
index a735778ae..000000000
--- a/src/Mooc/VideoComments/Contract/VideoCommentPublishedDomainEvent.php
+++ /dev/null
@@ -1,27 +0,0 @@
- ['string'],
- 'content' => ['string'],
- ];
- }
-}
diff --git a/src/Mooc/VideoComments/Domain/VideoComment.php b/src/Mooc/VideoComments/Domain/VideoComment.php
deleted file mode 100644
index eae6fa90c..000000000
--- a/src/Mooc/VideoComments/Domain/VideoComment.php
+++ /dev/null
@@ -1,55 +0,0 @@
-id = $id;
- $this->videoId = $videoId;
- $this->content = $content;
- }
-
- public static function publish(VideoCommentId $id, VideoId $videoId, VideoCommentContent $content): VideoComment
- {
- $comment = new self($id, $videoId, $content);
-
- $comment->record(
- new VideoCommentPublishedDomainEvent(
- $id->value(),
- [
- 'videoId' => $videoId->value(),
- 'content' => $content->value(),
- ]
- )
- );
-
- return $comment;
- }
-
- public function id(): VideoCommentId
- {
- return $this->id;
- }
-
- public function videoId(): VideoId
- {
- return $this->videoId;
- }
-
- public function content(): VideoCommentContent
- {
- return $this->content;
- }
-}
diff --git a/src/Mooc/VideoComments/Domain/VideoCommentContent.php b/src/Mooc/VideoComments/Domain/VideoCommentContent.php
deleted file mode 100644
index 5e5b755ae..000000000
--- a/src/Mooc/VideoComments/Domain/VideoCommentContent.php
+++ /dev/null
@@ -1,34 +0,0 @@
-ensureHasMinimumLength($value);
-
- $this->value = $value;
- }
-
- public function value(): string
- {
- return $this->value;
- }
-
- private function ensureHasMinimumLength(string $content): void
- {
- $contentLength = strlen($content);
-
- if ($contentLength < self::MIN_LENGTH) {
- throw new \InvalidArgumentException(
- sprintf('The min length for a comment is %s, %s received', self::MIN_LENGTH, $contentLength)
- );
- }
- }
-}
diff --git a/src/Mooc/VideoComments/Domain/VideoCommentId.php b/src/Mooc/VideoComments/Domain/VideoCommentId.php
deleted file mode 100644
index f2d924f6f..000000000
--- a/src/Mooc/VideoComments/Domain/VideoCommentId.php
+++ /dev/null
@@ -1,11 +0,0 @@
-persist($comment);
- }
-}
diff --git a/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommand.php b/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommand.php
deleted file mode 100644
index 5488e51f3..000000000
--- a/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommand.php
+++ /dev/null
@@ -1,46 +0,0 @@
-id = $id;
- $this->from = $from;
- $this->to = $to;
- $this->message = $message;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function from(): int
- {
- return $this->from;
- }
-
- public function to(): int
- {
- return $this->to;
- }
-
- public function message(): string
- {
- return $this->message;
- }
-}
diff --git a/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandler.php b/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandler.php
deleted file mode 100644
index c045a7d2b..000000000
--- a/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandler.php
+++ /dev/null
@@ -1,29 +0,0 @@
-creator = $creator;
- }
-
- public function __invoke(CreateVideoHighlightCommand $command)
- {
- $id = new VideoHighlightId($command->id());
- $interval = SecondsInterval::fromValues($command->from(), $command->to());
- $message = new VideoHighlightMessage($command->message());
-
- $this->creator->create($id, $interval, $message);
- }
-}
diff --git a/src/Mooc/VideoHighlights/Application/Create/VideoHighlightCreator.php b/src/Mooc/VideoHighlights/Application/Create/VideoHighlightCreator.php
deleted file mode 100644
index 3fe5edaa4..000000000
--- a/src/Mooc/VideoHighlights/Application/Create/VideoHighlightCreator.php
+++ /dev/null
@@ -1,33 +0,0 @@
-repository = $repository;
- $this->publisher = $publisher;
- }
-
- public function create(VideoHighlightId $id, SecondsInterval $interval, VideoHighlightMessage $message): void
- {
- $videoHighlight = VideoHighlight::create($id, $interval, $message);
-
- $this->repository->save($videoHighlight);
-
- $this->publisher->publish(...$videoHighlight->pullDomainEvents());
- }
-}
diff --git a/src/Mooc/VideoHighlights/Domain/VideoHighlight.php b/src/Mooc/VideoHighlights/Domain/VideoHighlight.php
deleted file mode 100644
index 77c3c9de4..000000000
--- a/src/Mooc/VideoHighlights/Domain/VideoHighlight.php
+++ /dev/null
@@ -1,58 +0,0 @@
-id = $id;
- $this->interval = $interval;
- $this->message = $message;
- }
-
- public static function create(
- VideoHighlightId $id,
- SecondsInterval $interval,
- VideoHighlightMessage $message
- ): VideoHighlight {
- $videoHighlight = new self($id, $interval, $message);
-
- $videoHighlight->record(
- new VideoHighlightCreatedDomainEvent(
- $id->value(),
- [
- 'from' => $interval->from()->value(),
- 'to' => $interval->to()->value(),
- 'message' => $message->value(),
- ]
- )
- );
-
- return $videoHighlight;
- }
-
- public function id(): VideoHighlightId
- {
- return $this->id;
- }
-
- public function interval(): SecondsInterval
- {
- return $this->interval;
- }
-
- public function message(): VideoHighlightMessage
- {
- return $this->message;
- }
-}
diff --git a/src/Mooc/VideoHighlights/Domain/VideoHighlightCreatedDomainEvent.php b/src/Mooc/VideoHighlights/Domain/VideoHighlightCreatedDomainEvent.php
deleted file mode 100644
index c77119d4b..000000000
--- a/src/Mooc/VideoHighlights/Domain/VideoHighlightCreatedDomainEvent.php
+++ /dev/null
@@ -1,29 +0,0 @@
- ['int'],
- 'to' => ['int'],
- 'message' => ['string'],
- ];
- }
-}
diff --git a/src/Mooc/VideoHighlights/Domain/VideoHighlightId.php b/src/Mooc/VideoHighlights/Domain/VideoHighlightId.php
deleted file mode 100644
index a564c3e3b..000000000
--- a/src/Mooc/VideoHighlights/Domain/VideoHighlightId.php
+++ /dev/null
@@ -1,11 +0,0 @@
-persist($videoHighlight);
- }
-
- public function search(VideoHighlightId $id): ?VideoHighlight
- {
- return $this->repository(VideoHighlight::class)->find($id);
- }
-}
diff --git a/src/Mooc/Videos/Application/Create/CreateVideoCommand.php b/src/Mooc/Videos/Application/Create/CreateVideoCommand.php
index 63dec1100..0a94120f5 100644
--- a/src/Mooc/Videos/Application/Create/CreateVideoCommand.php
+++ b/src/Mooc/Videos/Application/Create/CreateVideoCommand.php
@@ -1,53 +1,43 @@
id = $id;
- $this->type = $type;
- $this->title = $title;
- $this->url = $url;
- $this->courseId = $courseId;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function type(): string
- {
- return $this->type;
- }
-
- public function title(): string
- {
- return $this->title;
- }
-
- public function url(): string
- {
- return $this->url;
- }
-
- public function courseId(): string
- {
- return $this->courseId;
- }
+ public function __construct(
+ private string $id,
+ private string $type,
+ private string $title,
+ private string $url,
+ private string $courseId
+ ) {}
+
+ public function id(): string
+ {
+ return $this->id;
+ }
+
+ public function type(): string
+ {
+ return $this->type;
+ }
+
+ public function title(): string
+ {
+ return $this->title;
+ }
+
+ public function url(): string
+ {
+ return $this->url;
+ }
+
+ public function courseId(): string
+ {
+ return $this->courseId;
+ }
}
diff --git a/src/Mooc/Videos/Application/Create/CreateVideoCommandHandler.php b/src/Mooc/Videos/Application/Create/CreateVideoCommandHandler.php
index d37b24410..4e9222d0b 100644
--- a/src/Mooc/Videos/Application/Create/CreateVideoCommandHandler.php
+++ b/src/Mooc/Videos/Application/Create/CreateVideoCommandHandler.php
@@ -1,6 +1,6 @@
creator = $creator;
- }
+ public function __invoke(CreateVideoCommand $command): void
+ {
+ $id = new VideoId($command->id());
+ $type = VideoType::from($command->type());
+ $title = new VideoTitle($command->title());
+ $url = new VideoUrl($command->url());
+ $courseId = new CourseId($command->courseId());
- public function __invoke(CreateVideoCommand $command)
- {
- $id = new VideoId($command->id());
- $type = new VideoType($command->type());
- $title = new VideoTitle($command->title());
- $url = new VideoUrl($command->url());
- $courseId = new CourseId($command->courseId());
-
- $this->creator->create($id, $type, $title, $url, $courseId);
- }
+ $this->creator->create($id, $type, $title, $url, $courseId);
+ }
}
diff --git a/src/Mooc/Videos/Application/Create/VideoCreator.php b/src/Mooc/Videos/Application/Create/VideoCreator.php
index cfdb6d778..a3bb4a193 100644
--- a/src/Mooc/Videos/Application/Create/VideoCreator.php
+++ b/src/Mooc/Videos/Application/Create/VideoCreator.php
@@ -1,6 +1,6 @@
repository = $repository;
- $this->publisher = $publisher;
- }
+ public function create(VideoId $id, VideoType $type, VideoTitle $title, VideoUrl $url, CourseId $courseId): void
+ {
+ $video = Video::create($id, $type, $title, $url, $courseId);
- public function create(VideoId $id, VideoType $type, VideoTitle $title, VideoUrl $url, CourseId $courseId): void
- {
- $video = Video::create($id, $type, $title, $url, $courseId);
+ $this->repository->save($video);
- $this->repository->save($video);
-
- $this->publisher->publish(...$video->pullDomainEvents());
- }
+ $this->bus->publish(...$video->pullDomainEvents());
+ }
}
diff --git a/src/Mooc/Videos/Application/Find/FindVideoQuery.php b/src/Mooc/Videos/Application/Find/FindVideoQuery.php
index cb7a58034..5df95d32b 100644
--- a/src/Mooc/Videos/Application/Find/FindVideoQuery.php
+++ b/src/Mooc/Videos/Application/Find/FindVideoQuery.php
@@ -1,22 +1,17 @@
id = $id;
- }
-
- public function id(): string
- {
- return $this->id;
- }
+ public function id(): string
+ {
+ return $this->id;
+ }
}
diff --git a/src/Mooc/Videos/Application/Find/FindVideoQueryHandler.php b/src/Mooc/Videos/Application/Find/FindVideoQueryHandler.php
index e1620f189..c533ce272 100644
--- a/src/Mooc/Videos/Application/Find/FindVideoQueryHandler.php
+++ b/src/Mooc/Videos/Application/Find/FindVideoQueryHandler.php
@@ -1,27 +1,29 @@
responseConverter = new VideoResponseConverter();
+ }
- public function __construct(VideoFinder $finder)
- {
- $this->finder = pipe($finder, new VideoResponseConverter());
- }
+ public function __invoke(FindVideoQuery $query): VideoResponse
+ {
+ $id = new VideoId($query->id());
- public function __invoke(FindVideoQuery $query): VideoResponse
- {
- $id = new VideoId($query->id());
+ $video = apply($this->finder, [$id]);
- return apply($this->finder, [$id]);
- }
+ return apply($this->responseConverter, [$video]);
+ }
}
diff --git a/src/Mooc/Videos/Application/Find/VideoFinder.php b/src/Mooc/Videos/Application/Find/VideoFinder.php
index 5ffc24ae0..103ff6e75 100644
--- a/src/Mooc/Videos/Application/Find/VideoFinder.php
+++ b/src/Mooc/Videos/Application/Find/VideoFinder.php
@@ -1,24 +1,25 @@
finder = new DomainVideoFinder($repository);
- }
+ public function __construct(VideoRepository $repository)
+ {
+ $this->finder = new DomainVideoFinder($repository);
+ }
- public function __invoke(VideoId $id)
- {
- return $this->finder->__invoke($id);
- }
+ public function __invoke(VideoId $id): Video
+ {
+ return $this->finder->__invoke($id);
+ }
}
diff --git a/src/Mooc/Videos/Application/Find/VideoResponse.php b/src/Mooc/Videos/Application/Find/VideoResponse.php
index 0504b2fc7..fb1061754 100644
--- a/src/Mooc/Videos/Application/Find/VideoResponse.php
+++ b/src/Mooc/Videos/Application/Find/VideoResponse.php
@@ -1,50 +1,18 @@
id = $id;
- $this->type = $type;
- $this->title = $title;
- $this->url = $url;
- $this->courseId = $courseId;
- }
-
- public function id(): string
- {
- return $this->id;
- }
-
- public function type(): string
- {
- return $this->type;
- }
-
- public function title(): string
- {
- return $this->title;
- }
-
- public function url(): string
- {
- return $this->url;
- }
-
- public function courseId(): string
- {
- return $this->courseId;
- }
+ public function __construct(
+ private string $id,
+ private string $type,
+ private string $title,
+ private string $url,
+ private string $courseId
+ ) {}
}
diff --git a/src/Mooc/Videos/Application/Find/VideoResponseConverter.php b/src/Mooc/Videos/Application/Find/VideoResponseConverter.php
index 997ac3c11..c766fe0cf 100644
--- a/src/Mooc/Videos/Application/Find/VideoResponseConverter.php
+++ b/src/Mooc/Videos/Application/Find/VideoResponseConverter.php
@@ -1,6 +1,6 @@
id()->value(),
- $video->type()->value(),
- $video->title()->value(),
- $video->url()->value(),
- $video->courseId()->value()
- );
- }
+ public function __invoke(Video $video): VideoResponse
+ {
+ return new VideoResponse(
+ $video->id()->value(),
+ $video->type()->value,
+ $video->title()->value(),
+ $video->url()->value(),
+ $video->courseId()->value()
+ );
+ }
}
diff --git a/src/Mooc/Videos/Application/Trim/TrimVideoCommand.php b/src/Mooc/Videos/Application/Trim/TrimVideoCommand.php
index 058bfc311..bb2ab5038 100644
--- a/src/Mooc/Videos/Application/Trim/TrimVideoCommand.php
+++ b/src/Mooc/Videos/Application/Trim/TrimVideoCommand.php
@@ -1,39 +1,27 @@
videoId = $videoId;
- $this->keepFromSecond = $keepFromSecond;
- $this->keepToSecond = $keepToSecond;
- }
-
- public function videoId(): string
- {
- return $this->videoId;
- }
-
- public function keepFromSecond(): int
- {
- return $this->keepFromSecond;
- }
-
- public function keepToSecond(): int
- {
- return $this->keepToSecond;
- }
+ public function __construct(private string $videoId, private int $keepFromSecond, private int $keepToSecond) {}
+
+ public function videoId(): string
+ {
+ return $this->videoId;
+ }
+
+ public function keepFromSecond(): int
+ {
+ return $this->keepFromSecond;
+ }
+
+ public function keepToSecond(): int
+ {
+ return $this->keepToSecond;
+ }
}
diff --git a/src/Mooc/Videos/Application/Trim/TrimVideoCommandHandler.php b/src/Mooc/Videos/Application/Trim/TrimVideoCommandHandler.php
index f3a05618d..94cf1e676 100644
--- a/src/Mooc/Videos/Application/Trim/TrimVideoCommandHandler.php
+++ b/src/Mooc/Videos/Application/Trim/TrimVideoCommandHandler.php
@@ -1,26 +1,21 @@
trimmer = $trimmer;
- }
+ public function __invoke(TrimVideoCommand $command): void
+ {
+ $id = new VideoId($command->videoId());
+ $interval = SecondsInterval::fromValues($command->keepFromSecond(), $command->keepToSecond());
- public function __invoke(TrimVideoCommand $command)
- {
- $id = new VideoId($command->videoId());
- $interval = SecondsInterval::fromValues($command->keepFromSecond(), $command->keepToSecond());
-
- $this->trimmer->trim($id, $interval);
- }
+ $this->trimmer->trim($id, $interval);
+ }
}
diff --git a/src/Mooc/Videos/Application/Trim/VideoTrimmer.php b/src/Mooc/Videos/Application/Trim/VideoTrimmer.php
index 567889e4a..75a6d4624 100644
--- a/src/Mooc/Videos/Application/Trim/VideoTrimmer.php
+++ b/src/Mooc/Videos/Application/Trim/VideoTrimmer.php
@@ -1,6 +1,6 @@
finder = new VideoFinder($repository);
- $this->repository = $repository;
- }
+ public function __construct(private VideoRepository $repository)
+ {
+ $this->finder = new VideoFinder($repository);
+ }
- public function __invoke(VideoId $id, VideoTitle $newTitle): void
- {
- $video = $this->finder->__invoke($id);
+ public function __invoke(VideoId $id, VideoTitle $newTitle): void
+ {
+ $video = $this->finder->__invoke($id);
- $video->updateTitle($newTitle);
+ $video->updateTitle($newTitle);
- $this->repository->save($video);
- }
+ $this->repository->save($video);
+ }
}
diff --git a/src/Mooc/Videos/Domain/Video.php b/src/Mooc/Videos/Domain/Video.php
index df8751436..db7a35bdc 100644
--- a/src/Mooc/Videos/Domain/Video.php
+++ b/src/Mooc/Videos/Domain/Video.php
@@ -1,6 +1,6 @@
id = $id;
- $this->type = $type;
- $this->title = $title;
- $this->url = $url;
- $this->courseId = $courseId;
- }
+ public static function create(
+ VideoId $id,
+ VideoType $type,
+ VideoTitle $title,
+ VideoUrl $url,
+ CourseId $courseId
+ ): self {
+ $video = new self($id, $type, $title, $url, $courseId);
- public static function create(
- VideoId $id,
- VideoType $type,
- VideoTitle $title,
- VideoUrl $url,
- CourseId $courseId
- ): Video {
- $video = new self($id, $type, $title, $url, $courseId);
+ $video->record(
+ new VideoCreatedDomainEvent($id->value(), $type->value, $title->value(), $url->value(), $courseId->value())
+ );
- $video->record(
- new VideoCreatedDomainEvent(
- $id->value(),
- [
- 'type' => $type->value(),
- 'title' => $title->value(),
- 'url' => $url->value(),
- 'courseId' => $courseId->value(),
- ]
- )
- );
+ return $video;
+ }
- return $video;
- }
+ public function updateTitle(VideoTitle $newTitle): void
+ {
+ $this->title = $newTitle;
+ }
- public function updateTitle(VideoTitle $newTitle): void
- {
- $this->title = $newTitle;
- }
+ public function id(): VideoId
+ {
+ return $this->id;
+ }
- public function id(): VideoId
- {
- return $this->id;
- }
+ public function type(): VideoType
+ {
+ return $this->type;
+ }
- public function type(): VideoType
- {
- return $this->type;
- }
+ public function title(): VideoTitle
+ {
+ return $this->title;
+ }
- public function title(): VideoTitle
- {
- return $this->title;
- }
+ public function url(): VideoUrl
+ {
+ return $this->url;
+ }
- public function url(): VideoUrl
- {
- return $this->url;
- }
-
- public function courseId(): CourseId
- {
- return $this->courseId;
- }
+ public function courseId(): CourseId
+ {
+ return $this->courseId;
+ }
}
diff --git a/src/Mooc/Videos/Domain/VideoCreatedDomainEvent.php b/src/Mooc/Videos/Domain/VideoCreatedDomainEvent.php
index daa003996..61cd7f8e8 100644
--- a/src/Mooc/Videos/Domain/VideoCreatedDomainEvent.php
+++ b/src/Mooc/Videos/Domain/VideoCreatedDomainEvent.php
@@ -1,31 +1,54 @@
['string'],
- 'title' => ['string'],
- 'url' => ['string'],
- 'courseId' => ['string'],
- ];
- }
+ public static function eventName(): string
+ {
+ return 'video.created';
+ }
+
+ public static function fromPrimitives(
+ string $aggregateId,
+ array $body,
+ string $eventId,
+ string $occurredOn
+ ): self {
+ return new self(
+ $aggregateId,
+ $body['type'],
+ $body['title'],
+ $body['url'],
+ $body['course_id'],
+ $eventId,
+ $occurredOn
+ );
+ }
+
+ public function toPrimitives(): array
+ {
+ return [
+ 'type' => $this->type,
+ 'title' => $this->title,
+ 'url' => $this->url,
+ 'course_id' => $this->courseId,
+ ];
+ }
}
diff --git a/src/Mooc/Videos/Domain/VideoFinder.php b/src/Mooc/Videos/Domain/VideoFinder.php
index 8cac07773..2386116ef 100644
--- a/src/Mooc/Videos/Domain/VideoFinder.php
+++ b/src/Mooc/Videos/Domain/VideoFinder.php
@@ -1,31 +1,21 @@
repository = $repository;
- }
+ public function __invoke(VideoId $id): Video
+ {
+ $video = $this->repository->search($id);
- public function __invoke(VideoId $id): Video
- {
- $video = $this->repository->search($id);
+ if ($video === null) {
+ throw new VideoNotFound($id);
+ }
- $this->ensureVideoExists($id, $video);
-
- return $video;
- }
-
- private function ensureVideoExists(VideoId $id, Video $video = null): void
- {
- if (null === $video) {
- throw new VideoNotFound($id);
- }
- }
+ return $video;
+ }
}
diff --git a/src/Mooc/Videos/Domain/VideoId.php b/src/Mooc/Videos/Domain/VideoId.php
index 7302fd779..4396d6b85 100644
--- a/src/Mooc/Videos/Domain/VideoId.php
+++ b/src/Mooc/Videos/Domain/VideoId.php
@@ -1,11 +1,9 @@
id = $id;
-
- parent::__construct();
- }
-
- public function errorCode(): string
- {
- return 'video_not_found';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The video <%s> has not been found', $this->id->value());
- }
+ public function __construct(private readonly VideoId $id)
+ {
+ parent::__construct();
+ }
+
+ public function errorCode(): string
+ {
+ return 'video_not_found';
+ }
+
+ protected function errorMessage(): string
+ {
+ return sprintf('The video <%s> has not been found', $this->id->value());
+ }
}
diff --git a/src/Mooc/Videos/Domain/VideoRepository.php b/src/Mooc/Videos/Domain/VideoRepository.php
index cb50b6e5c..0cd6aae41 100644
--- a/src/Mooc/Videos/Domain/VideoRepository.php
+++ b/src/Mooc/Videos/Domain/VideoRepository.php
@@ -1,6 +1,6 @@
value is not a valid video type', $value));
- }
+ case SCREENCAST = 'screencast';
+ case INTERVIEW = 'interview';
}
diff --git a/src/Mooc/Videos/Domain/Videos.php b/src/Mooc/Videos/Domain/Videos.php
index 30c300602..9a21231d5 100644
--- a/src/Mooc/Videos/Domain/Videos.php
+++ b/src/Mooc/Videos/Domain/Videos.php
@@ -1,6 +1,6 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoIdType.php b/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoIdType.php
new file mode 100644
index 000000000..2db8f8d8c
--- /dev/null
+++ b/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoIdType.php
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoType.orm.xml b/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoType.orm.xml
new file mode 100644
index 000000000..b05a427cb
--- /dev/null
+++ b/src/Mooc/Videos/Infrastructure/Persistence/Doctrine/VideoType.orm.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/Video.orm.yml b/src/Mooc/Videos/Infrastructure/Persistence/Video.orm.yml
deleted file mode 100644
index 876b9138f..000000000
--- a/src/Mooc/Videos/Infrastructure/Persistence/Video.orm.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-CodelyTv\Mooc\Videos\Domain\Video:
- type: entity
- table: videos
-
- id:
- id:
- type: video_id
- column: id
- length: 36
-
- fields:
- courseId:
- type: course_id
- column: course_id
-
- embedded:
- type:
- class: CodelyTv\Mooc\Videos\Domain\VideoType
- columnPrefix: false
- title:
- class: CodelyTv\Mooc\Videos\Domain\VideoTitle
- columnPrefix: false
- url:
- class: CodelyTv\Mooc\Shared\Domain\Videos\VideoUrl
- columnPrefix: false
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/VideoIdType.php b/src/Mooc/Videos/Infrastructure/Persistence/VideoIdType.php
deleted file mode 100644
index 4f8738849..000000000
--- a/src/Mooc/Videos/Infrastructure/Persistence/VideoIdType.php
+++ /dev/null
@@ -1,31 +0,0 @@
-value();
- }
-}
-
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/VideoRepositoryMySql.php b/src/Mooc/Videos/Infrastructure/Persistence/VideoRepositoryMySql.php
index 4299c8d2a..76e4d8a0c 100644
--- a/src/Mooc/Videos/Infrastructure/Persistence/VideoRepositoryMySql.php
+++ b/src/Mooc/Videos/Infrastructure/Persistence/VideoRepositoryMySql.php
@@ -1,6 +1,6 @@
'id',
- 'type' => 'type',
- 'title' => 'title',
- 'url' => 'url',
- 'course_id' => 'courseId',
- ];
-
- public function save(Video $video): void
- {
- $this->persist($video);
- }
-
- public function search(VideoId $id): ?Video
- {
- return $this->repository(Video::class)->find($id);
- }
-
- public function searchByCriteria(Criteria $criteria): Videos
- {
- $doctrineCriteria = DoctrineCriteriaConverter::convert($criteria, self::$criteriaToDoctrineFields);
- $videos = $this->repository(Video::class)->matching($doctrineCriteria)->toArray();
-
- return new Videos($videos);
- }
+ private static array $criteriaToDoctrineFields = [
+ 'id' => 'id',
+ 'type' => 'type',
+ 'title' => 'title',
+ 'url' => 'url',
+ 'course_id' => 'courseId',
+ ];
+
+ public function save(Video $video): void
+ {
+ $this->persist($video);
+ }
+
+ public function search(VideoId $id): ?Video
+ {
+ return $this->repository(Video::class)->find($id);
+ }
+
+ public function searchByCriteria(Criteria $criteria): Videos
+ {
+ $doctrineCriteria = DoctrineCriteriaConverter::convert($criteria, self::$criteriaToDoctrineFields);
+ $videos = $this->repository(Video::class)->matching($doctrineCriteria)->toArray();
+
+ return new Videos($videos);
+ }
}
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/VideoTitle.orm.yml b/src/Mooc/Videos/Infrastructure/Persistence/VideoTitle.orm.yml
deleted file mode 100644
index 730a5c931..000000000
--- a/src/Mooc/Videos/Infrastructure/Persistence/VideoTitle.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Videos\Domain\VideoTitle:
- type: embeddable
-
- fields:
- value:
- type: string
- column: title
diff --git a/src/Mooc/Videos/Infrastructure/Persistence/VideoType.orm.yml b/src/Mooc/Videos/Infrastructure/Persistence/VideoType.orm.yml
deleted file mode 100644
index ac6da1871..000000000
--- a/src/Mooc/Videos/Infrastructure/Persistence/VideoType.orm.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-CodelyTv\Mooc\Videos\Domain\VideoType:
- type: embeddable
-
- fields:
- value:
- type: string
- column: type
diff --git a/src/Retention/Campaign/Application/NewCourseAvailable/Schedule/.gitkeep b/src/Retention/Campaign/Application/NewCourseAvailable/Schedule/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Campaign/Application/NewCourseAvailable/Trigger/.gitkeep b/src/Retention/Campaign/Application/NewCourseAvailable/Trigger/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Campaign/Application/WelcomeUser/Trigger/.gitkeep b/src/Retention/Campaign/Application/WelcomeUser/Trigger/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Campaign/Domain/.gitkeep b/src/Retention/Campaign/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Campaign/Infrastructure/.gitkeep b/src/Retention/Campaign/Infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Email/Application/SendNewCourseAvailable/.gitkeep b/src/Retention/Email/Application/SendNewCourseAvailable/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Email/Application/SendWelcomeUser/.gitkeep b/src/Retention/Email/Application/SendWelcomeUser/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Email/Domain/.gitkeep b/src/Retention/Email/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Email/Infrastructure/.gitkeep b/src/Retention/Email/Infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Push/Application/SendNewCourseAvailable/.gitkeep b/src/Retention/Push/Application/SendNewCourseAvailable/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Push/Domain/.gitkeep b/src/Retention/Push/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Push/Infrastructure/.gitkeep b/src/Retention/Push/Infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Sms/Application/.gitkeep b/src/Retention/Sms/Application/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Sms/Domain/.gitkeep b/src/Retention/Sms/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Retention/Sms/Infrastructure/.gitkeep b/src/Retention/Sms/Infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/Shared/Domain/Aggregate/AggregateRoot.php b/src/Shared/Domain/Aggregate/AggregateRoot.php
index e9cb40325..8162916cf 100644
--- a/src/Shared/Domain/Aggregate/AggregateRoot.php
+++ b/src/Shared/Domain/Aggregate/AggregateRoot.php
@@ -1,6 +1,6 @@
domainEvents;
- $this->domainEvents = [];
+ final public function pullDomainEvents(): array
+ {
+ $domainEvents = $this->domainEvents;
+ $this->domainEvents = [];
- return $domainEvents;
- }
+ return $domainEvents;
+ }
- final protected function record(DomainEvent $domainEvent): void
- {
- $this->domainEvents[] = $domainEvent;
- }
+ final protected function record(DomainEvent $domainEvent): void
+ {
+ $this->domainEvents[] = $domainEvent;
+ }
}
diff --git a/src/Shared/Domain/Aggregate/AggregateRootCollection.php b/src/Shared/Domain/Aggregate/AggregateRootCollection.php
deleted file mode 100644
index 7d0a50d28..000000000
--- a/src/Shared/Domain/Aggregate/AggregateRootCollection.php
+++ /dev/null
@@ -1,25 +0,0 @@
-pullItemDomainEvents(), $this, []);
- }
-
- private function pullItemDomainEvents(): callable
- {
- return function (array $accumulatedEvents, AggregateRoot $aggregateRoot): array {
- return array_merge($accumulatedEvents, $aggregateRoot->pullDomainEvents());
- };
- }
-}
diff --git a/src/Shared/Domain/Assert.php b/src/Shared/Domain/Assert.php
index fa8ea01e3..d1c5f6e2d 100644
--- a/src/Shared/Domain/Assert.php
+++ b/src/Shared/Domain/Assert.php
@@ -1,6 +1,6 @@
is not an instance of <%s>', $class, get_class($item))
- );
- }
- }
-
- public static function money($value): void
- {
- if (!self::isValidMoneyAmount($value)) {
- throw new InvalidArgumentException(sprintf('The value <%s> is not a valid money amount', $value));
- }
- }
-
- private static function isValidMoneyAmount($value): bool
- {
- return is_numeric($value) && $value >= 0;
- }
+ public static function instanceOf(string $class, mixed $item): void
+ {
+ if (!$item instanceof $class) {
+ throw new InvalidArgumentException(sprintf('The object <%s> is not an instance of <%s>', $class, $item::class));
+ }
+ }
}
diff --git a/src/Shared/Domain/Bus/Command/Command.php b/src/Shared/Domain/Bus/Command/Command.php
index a307add33..dceac12c7 100644
--- a/src/Shared/Domain/Bus/Command/Command.php
+++ b/src/Shared/Domain/Bus/Command/Command.php
@@ -1,21 +1,7 @@
requestId();
- }
-
- public function messageType(): string
- {
- return 'command';
- }
-}
+interface Command {}
diff --git a/src/Shared/Domain/Bus/Command/CommandBus.php b/src/Shared/Domain/Bus/Command/CommandBus.php
index 91422d333..fdf5e9ef9 100644
--- a/src/Shared/Domain/Bus/Command/CommandBus.php
+++ b/src/Shared/Domain/Bus/Command/CommandBus.php
@@ -1,10 +1,10 @@
value();
-
- parent::__construct(new Uuid($eventId));
-
- $this->eventId = $eventId;
- DomainEventDataValidator::isValid($data, $this->rules(), static::class);
-
- $this->aggregateId = $aggregateId;
- $this->data = $data;
- $this->occurredOn = $occurredOn ?: date_to_string(new DateTimeImmutable());
- }
-
- abstract protected function rules(): array;
-
- abstract public static function eventName(): string;
-
- public function messageType(): string
- {
- return 'domain_event';
- }
-
- public function eventId(): string
- {
- return $this->eventId;
- }
-
- public function aggregateId(): string
- {
- return $this->aggregateId;
- }
-
- public function data(): array
- {
- return $this->data;
- }
-
- public function occurredOn(): string
- {
- return $this->occurredOn;
- }
-
- public function __call($method, $args)
- {
- $attributeName = $method;
- if (0 === strpos($method, 'is')) {
- $attributeName = lcfirst(substr($method, 2));
- }
-
- if (0 === strpos($method, 'has')) {
- $attributeName = lcfirst(substr($method, 3));
- }
-
- if (isset($this->data[$attributeName])) {
- return $this->data[$attributeName];
- }
-
- throw new RuntimeException(sprintf('The method "%s" does not exist.', $method));
- }
+ private readonly string $eventId;
+ private readonly string $occurredOn;
+
+ public function __construct(private readonly string $aggregateId, string $eventId = null, string $occurredOn = null)
+ {
+ $this->eventId = $eventId ?: SimpleUuid::random()->value();
+ $this->occurredOn = $occurredOn ?: Utils::dateToString(new DateTimeImmutable());
+ }
+
+ abstract public static function fromPrimitives(
+ string $aggregateId,
+ array $body,
+ string $eventId,
+ string $occurredOn
+ ): self;
+
+ abstract public static function eventName(): string;
+
+ abstract public function toPrimitives(): array;
+
+ final public function aggregateId(): string
+ {
+ return $this->aggregateId;
+ }
+
+ final public function eventId(): string
+ {
+ return $this->eventId;
+ }
+
+ final public function occurredOn(): string
+ {
+ return $this->occurredOn;
+ }
}
diff --git a/src/Shared/Domain/Bus/Event/DomainEventPublisher.php b/src/Shared/Domain/Bus/Event/DomainEventPublisher.php
deleted file mode 100644
index 8dba0c9a1..000000000
--- a/src/Shared/Domain/Bus/Event/DomainEventPublisher.php
+++ /dev/null
@@ -1,23 +0,0 @@
-messageId = $messageId;
- }
-
- public function messageId(): Uuid
- {
- return $this->messageId;
- }
-
- abstract public function messageType(): string;
-}
diff --git a/src/Shared/Domain/Bus/MessageSerializer.php b/src/Shared/Domain/Bus/MessageSerializer.php
deleted file mode 100644
index f787e05d3..000000000
--- a/src/Shared/Domain/Bus/MessageSerializer.php
+++ /dev/null
@@ -1,50 +0,0 @@
-getMethods();
-
- $methodNames = reindex($this->methodNameExtractor(), $methods);
-
- return map($this->nameExtractor($message), filter(not($this->isConstruct()), $methodNames));
- }
-
- private function methodNameExtractor(): callable
- {
- return function (ReflectionMethod $method): string {
- return camel_to_snake($method->getName());
- };
- }
-
- private function nameExtractor(Request $message): callable
- {
- return function ($unused, $name) use ($message): string {
- $methodName = snake_to_camel($name);
-
- return $message->$methodName();
- };
- }
-
- private function isConstruct(): callable
- {
- return function ($unused, $name) {
- return $name === '__construct';
- };
- }
-}
diff --git a/src/Shared/Domain/Bus/Query/Asker.php b/src/Shared/Domain/Bus/Query/Asker.php
deleted file mode 100644
index 98fef4391..000000000
--- a/src/Shared/Domain/Bus/Query/Asker.php
+++ /dev/null
@@ -1,20 +0,0 @@
-queryBus = $queryBus;
- }
-
- public function __invoke(Query $query): ?Response
- {
- return $this->queryBus->ask($query);
- }
-}
diff --git a/src/Shared/Domain/Bus/Query/Query.php b/src/Shared/Domain/Bus/Query/Query.php
index b7acefb96..3ed4d1467 100644
--- a/src/Shared/Domain/Bus/Query/Query.php
+++ b/src/Shared/Domain/Bus/Query/Query.php
@@ -1,12 +1,7 @@
messageId();
- }
-}
diff --git a/src/Shared/Domain/Collection.php b/src/Shared/Domain/Collection.php
index eb206bc6a..c0b664aa8 100644
--- a/src/Shared/Domain/Collection.php
+++ b/src/Shared/Domain/Collection.php
@@ -1,45 +1,36 @@
*/
abstract class Collection implements Countable, IteratorAggregate
{
- /** @var array */
- private $items;
-
- public function __construct(array $items)
- {
- Assert::arrayOf($this->type(), $items);
-
- $this->items = $items;
- }
-
- abstract protected function type(): string;
-
- public function getIterator()
- {
- return new ArrayIterator($this->items());
- }
-
- public function count()
- {
- return count($this->items());
- }
-
- protected function each(callable $fn)
- {
- each($fn, $this->items());
- }
-
- protected function items()
- {
- return $this->items;
- }
+ public function __construct(private readonly array $items)
+ {
+ Assert::arrayOf($this->type(), $items);
+ }
+
+ abstract protected function type(): string;
+
+ final public function getIterator(): Traversable
+ {
+ return new ArrayIterator($this->items());
+ }
+
+ final public function count(): int
+ {
+ return count($this->items());
+ }
+
+ protected function items(): array
+ {
+ return $this->items;
+ }
}
diff --git a/src/Shared/Domain/Criteria/Criteria.php b/src/Shared/Domain/Criteria/Criteria.php
index f0ff01931..876c9f441 100644
--- a/src/Shared/Domain/Criteria/Criteria.php
+++ b/src/Shared/Domain/Criteria/Criteria.php
@@ -1,56 +1,61 @@
filters = $filters;
- $this->order = $order;
- $this->offset = $offset;
- $this->limit = $limit;
- }
-
- public function hasFilters(): bool
- {
- return $this->filters->count() > 0;
- }
-
- public function hasOrder(): bool
- {
- return null !== $this->order;
- }
-
- public function plainFilters(): array
- {
- return $this->filters->filters();
- }
-
- public function filters(): Filters
- {
- return $this->filters;
- }
-
- public function order(): ?Order
- {
- return $this->order;
- }
-
- public function offset(): ?int
- {
- return $this->offset;
- }
-
- public function limit(): ?int
- {
- return $this->limit;
- }
+ public function __construct(
+ private Filters $filters,
+ private Order $order,
+ private ?int $offset,
+ private ?int $limit
+ ) {}
+
+ public function hasFilters(): bool
+ {
+ return $this->filters->count() > 0;
+ }
+
+ public function hasOrder(): bool
+ {
+ return !$this->order->isNone();
+ }
+
+ public function plainFilters(): array
+ {
+ return $this->filters->filters();
+ }
+
+ public function filters(): Filters
+ {
+ return $this->filters;
+ }
+
+ public function order(): Order
+ {
+ return $this->order;
+ }
+
+ public function offset(): ?int
+ {
+ return $this->offset;
+ }
+
+ public function limit(): ?int
+ {
+ return $this->limit;
+ }
+
+ public function serialize(): string
+ {
+ return sprintf(
+ '%s~~%s~~%s~~%s',
+ $this->filters->serialize(),
+ $this->order->serialize(),
+ $this->offset ?? 'none',
+ $this->limit ?? 'none'
+ );
+ }
}
diff --git a/src/Shared/Domain/Criteria/Filter.php b/src/Shared/Domain/Criteria/Filter.php
index d7fac8013..33f15c365 100644
--- a/src/Shared/Domain/Criteria/Filter.php
+++ b/src/Shared/Domain/Criteria/Filter.php
@@ -1,43 +1,43 @@
field = $field;
- $this->operator = $operator;
- $this->value = $value;
- }
-
- public static function fromValues(array $values): self
- {
- return new self(
- new FilterField($values['field']),
- new FilterOperator($values['operator']),
- new FilterValue($values['value'])
- );
- }
-
- public function field(): FilterField
- {
- return $this->field;
- }
-
- public function operator(): FilterOperator
- {
- return $this->operator;
- }
-
- public function value(): FilterValue
- {
- return $this->value;
- }
+ public function __construct(
+ private FilterField $field,
+ private FilterOperator $operator,
+ private FilterValue $value
+ ) {}
+
+ public static function fromValues(array $values): self
+ {
+ return new self(
+ new FilterField($values['field']),
+ FilterOperator::from($values['operator']),
+ new FilterValue($values['value'])
+ );
+ }
+
+ public function field(): FilterField
+ {
+ return $this->field;
+ }
+
+ public function operator(): FilterOperator
+ {
+ return $this->operator;
+ }
+
+ public function value(): FilterValue
+ {
+ return $this->value;
+ }
+
+ public function serialize(): string
+ {
+ return sprintf('%s.%s.%s', $this->field->value(), $this->operator->value, $this->value->value());
+ }
}
diff --git a/src/Shared/Domain/Criteria/FilterField.php b/src/Shared/Domain/Criteria/FilterField.php
index c53383e4d..fcc11e2de 100644
--- a/src/Shared/Domain/Criteria/FilterField.php
+++ b/src/Shared/Domain/Criteria/FilterField.php
@@ -1,11 +1,9 @@
';
- public const LT = '<';
- public const CONTAINS = 'CONTAINS';
-
- public static function equal(): self
- {
- return new self('=');
- }
+ case EQUAL = '=';
+ case NOT_EQUAL = '!=';
+ case GT = '>';
+ case LT = '<';
+ case CONTAINS = 'CONTAINS';
+ case NOT_CONTAINS = 'NOT_CONTAINS';
- protected function throwExceptionForInvalidValue($value): void
- {
- throw new InvalidArgumentException(sprintf('The filter <%s> is invalid', $value));
- }
+ public function isContaining(): bool
+ {
+ return in_array($this->value, [self::CONTAINS->value, self::NOT_CONTAINS->value], true);
+ }
}
diff --git a/src/Shared/Domain/Criteria/FilterValue.php b/src/Shared/Domain/Criteria/FilterValue.php
index 78aef7bd6..5576c10fb 100644
--- a/src/Shared/Domain/Criteria/FilterValue.php
+++ b/src/Shared/Domain/Criteria/FilterValue.php
@@ -1,11 +1,9 @@
items(), [$filter]));
- }
-
- public function filters(): array
- {
- return $this->items();
- }
-
- private static function filterBuilder(): callable
- {
- return function (array $values) {
- return Filter::fromValues($values);
- };
- }
+ public static function fromValues(array $values): self
+ {
+ return new self(array_map(self::filterBuilder(), $values));
+ }
+
+ private static function filterBuilder(): callable
+ {
+ return fn (array $values): Filter => Filter::fromValues($values);
+ }
+
+ public function add(Filter $filter): self
+ {
+ return new self(array_merge($this->items(), [$filter]));
+ }
+
+ public function filters(): array
+ {
+ return $this->items();
+ }
+
+ public function serialize(): string
+ {
+ return reduce(
+ static fn (string $accumulate, Filter $filter): string => sprintf('%s^%s', $accumulate, $filter->serialize()),
+ $this->items(),
+ ''
+ );
+ }
+
+ protected function type(): string
+ {
+ return Filter::class;
+ }
}
diff --git a/src/Shared/Domain/Criteria/Order.php b/src/Shared/Domain/Criteria/Order.php
index d5f1b90f0..dfbc8e016 100644
--- a/src/Shared/Domain/Criteria/Order.php
+++ b/src/Shared/Domain/Criteria/Order.php
@@ -1,32 +1,48 @@
orderBy = $orderBy;
- $this->orderType = $orderType ?: OrderType::asc();
- }
-
- public static function createDesc(OrderBy $orderBy): Order
- {
- return new self($orderBy, OrderType::desc());
- }
-
- public function orderBy(): OrderBy
- {
- return $this->orderBy;
- }
-
- public function orderType(): OrderType
- {
- return $this->orderType;
- }
+ public function __construct(private OrderBy $orderBy, private OrderType $orderType) {}
+
+ public static function createDesc(OrderBy $orderBy): self
+ {
+ return new self($orderBy, OrderType::DESC);
+ }
+
+ public static function fromValues(?string $orderBy, ?string $order): self
+ {
+ return ($orderBy === null || $order === null) ? self::none() : new self(
+ new OrderBy($orderBy),
+ OrderType::from($order)
+ );
+ }
+
+ public static function none(): self
+ {
+ return new self(new OrderBy(''), OrderType::NONE);
+ }
+
+ public function orderBy(): OrderBy
+ {
+ return $this->orderBy;
+ }
+
+ public function orderType(): OrderType
+ {
+ return $this->orderType;
+ }
+
+ public function isNone(): bool
+ {
+ return $this->orderType()->isNone();
+ }
+
+ public function serialize(): string
+ {
+ return sprintf('%s.%s', $this->orderBy->value(), $this->orderType->value);
+ }
}
diff --git a/src/Shared/Domain/Criteria/OrderBy.php b/src/Shared/Domain/Criteria/OrderBy.php
index ac0f1a3bf..d2d054cae 100644
--- a/src/Shared/Domain/Criteria/OrderBy.php
+++ b/src/Shared/Domain/Criteria/OrderBy.php
@@ -1,11 +1,9 @@
value === self::NONE->value;
+ }
}
diff --git a/src/Shared/Domain/DomainError.php b/src/Shared/Domain/DomainError.php
index 8b9f9c755..18eec3f93 100644
--- a/src/Shared/Domain/DomainError.php
+++ b/src/Shared/Domain/DomainError.php
@@ -1,6 +1,6 @@
errorMessage());
- }
+ public function __construct()
+ {
+ parent::__construct($this->errorMessage());
+ }
- abstract public function errorCode(): string;
+ abstract public function errorCode(): string;
- abstract protected function errorMessage(): string;
+ abstract protected function errorMessage(): string;
}
diff --git a/src/Shared/Domain/EmailAddress.php b/src/Shared/Domain/EmailAddress.php
deleted file mode 100644
index d221ebb9a..000000000
--- a/src/Shared/Domain/EmailAddress.php
+++ /dev/null
@@ -1,31 +0,0 @@
-ensureIsValidEmail($value);
-
- $this->value = $value;
- }
-
- private function ensureIsValidEmail(string $value): void
- {
- if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
- throw new InvalidArgumentException(sprintf('The email <%s> is not valid', $value));
- }
- }
-
- public function value(): string
- {
- return $this->value;
- }
-}
diff --git a/src/Shared/Domain/InvalidUuid.php b/src/Shared/Domain/InvalidUuid.php
deleted file mode 100644
index ce99bd5b1..000000000
--- a/src/Shared/Domain/InvalidUuid.php
+++ /dev/null
@@ -1,27 +0,0 @@
-uuid = $uuid;
- }
-
- public function errorCode(): string
- {
- return 'invalid_uuid';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The <%s> is an invalid uuid', $this->uuid);
- }
-}
diff --git a/src/Shared/Domain/Logger.php b/src/Shared/Domain/Logger.php
new file mode 100644
index 000000000..fbaa7710c
--- /dev/null
+++ b/src/Shared/Domain/Logger.php
@@ -0,0 +1,14 @@
+ensureIntervalEndsAfterStart($from, $to);
-
- $this->from = $from;
- $this->to = $to;
- }
-
- public function from(): Second
- {
- return $this->from;
- }
-
- public function to(): Second
- {
- return $this->to;
- }
-
- public static function fromValues(int $from, int $to): SecondsInterval
- {
- return new self(new Second($from), new Second($to));
- }
-
- private function ensureIntervalEndsAfterStart(Second $from, Second $to): void
- {
- if ($from->isBiggerThan($to)) {
- throw new DomainException('To is bigger than from');
- }
- }
+ public function __construct(private Second $from, private Second $to)
+ {
+ $this->ensureIntervalEndsAfterStart($from, $to);
+ }
+
+ public static function fromValues(int $from, int $to): self
+ {
+ return new self(new Second($from), new Second($to));
+ }
+
+ private function ensureIntervalEndsAfterStart(Second $from, Second $to): void
+ {
+ if ($from->isBiggerThan($to)) {
+ throw new DomainException('To is bigger than from');
+ }
+ }
}
diff --git a/src/Shared/Domain/Utils.php b/src/Shared/Domain/Utils.php
new file mode 100644
index 000000000..92a9d1117
--- /dev/null
+++ b/src/Shared/Domain/Utils.php
@@ -0,0 +1,73 @@
+format(DateTimeInterface::ATOM);
+ }
+
+ public static function stringToDate(string $date): DateTimeImmutable
+ {
+ return new DateTimeImmutable($date);
+ }
+
+ public static function jsonEncode(array $values): string
+ {
+ return json_encode($values, JSON_THROW_ON_ERROR);
+ }
+
+ public static function jsonDecode(string $json): array
+ {
+ return json_decode($json, true, flags: JSON_THROW_ON_ERROR);
+ }
+
+ public static function toSnakeCase(string $text): string
+ {
+ return ctype_lower($text) ? $text : strtolower((string) preg_replace('/([^A-Z\s])([A-Z])/', '$1_$2', $text));
+ }
+
+ public static function toCamelCase(string $text): string
+ {
+ return lcfirst(str_replace('_', '', ucwords($text, '_')));
+ }
+
+ public static function dot(array $array, string $prepend = ''): array
+ {
+ $results = [];
+ foreach ($array as $key => $value) {
+ if (is_array($value) && !empty($value)) {
+ $results = array_merge($results, self::dot($value, $prepend . $key . '.'));
+ } else {
+ $results[$prepend . $key] = $value;
+ }
+ }
+
+ return $results;
+ }
+
+ public static function filesIn(string $path, string $fileType): array
+ {
+ return filter(
+ static fn (string $possibleModule): false | string => strstr($possibleModule, $fileType),
+ scandir($path)
+ );
+ }
+
+ public static function iterableToArray(iterable $iterable): array
+ {
+ if (is_array($iterable)) {
+ return $iterable;
+ }
+
+ return iterator_to_array($iterable);
+ }
+}
diff --git a/src/Shared/Domain/UuidGenerator.php b/src/Shared/Domain/UuidGenerator.php
new file mode 100644
index 000000000..1064a6edc
--- /dev/null
+++ b/src/Shared/Domain/UuidGenerator.php
@@ -0,0 +1,10 @@
+ self::stringValidator(),
- 'int' => self::intValidator(),
- 'float' => self::floatValidator(),
- 'array' => self::arrayValidator(),
- ];
-
- return $validators[$type];
- }
-
- private static function stringValidator(): callable
- {
- return function ($value): bool {
- return is_string($value);
- };
- }
-
- private static function intValidator(): callable
- {
- return function ($value): bool {
- return is_int($value);
- };
- }
-
- private static function arrayValidator(): callable
- {
- return function ($value): bool {
- return is_array($value);
- };
- }
-
- private static function floatValidator(): callable
- {
- return function ($value): bool {
- return is_float($value);
- };
- }
-}
diff --git a/src/Shared/Domain/ValueObject/Enum.php b/src/Shared/Domain/ValueObject/Enum.php
deleted file mode 100644
index bcb94447b..000000000
--- a/src/Shared/Domain/ValueObject/Enum.php
+++ /dev/null
@@ -1,85 +0,0 @@
-ensureIsBetweenAcceptedValues($value);
-
- $this->value = $value;
- }
-
- abstract protected function throwExceptionForInvalidValue($value);
-
- public static function __callStatic(string $name, $args)
- {
- return new static(self::values()[$name]);
- }
-
- public static function fromString(string $value)
- {
- return new static($value);
- }
-
- public static function values(): array
- {
- $class = static::class;
-
- if (!isset(self::$cache[$class])) {
- $reflected = new ReflectionClass($class);
- self::$cache[$class] = reindex(self::keysFormatter(), $reflected->getConstants());
- }
-
- return self::$cache[$class];
- }
-
- public static function randomValue()
- {
- return self::values()[array_rand(self::values())];
- }
-
- public function value()
- {
- return $this->value;
- }
-
- public function equals(Enum $other): bool
- {
- return $other == $this;
- }
-
- private function ensureIsBetweenAcceptedValues($value): void
- {
- if (!\in_array($value, static::values(), true)) {
- $this->throwExceptionForInvalidValue($value);
- }
- }
-
- public static function random(): self
- {
- return new static(self::randomValue());
- }
-
- private static function keysFormatter(): callable
- {
- return function ($unused, string $key): string {
- return snake_to_camel(strtolower($key));
- };
- }
-
- public function __toString(): string
- {
- return (string) $this->value();
- }
-}
diff --git a/src/Shared/Domain/ValueObject/IntValueObject.php b/src/Shared/Domain/ValueObject/IntValueObject.php
index 2a4c49582..77e13cd76 100644
--- a/src/Shared/Domain/ValueObject/IntValueObject.php
+++ b/src/Shared/Domain/ValueObject/IntValueObject.php
@@ -1,30 +1,20 @@
value = $value;
- }
+ final public function value(): int
+ {
+ return $this->value;
+ }
- public function value(): int
- {
- return $this->value;
- }
-
- public function equalsTo(IntValueObject $other): bool
- {
- return $this->value() === $other->value();
- }
-
- public function isBiggerThan(IntValueObject $other): bool
- {
- return $this->value() > $other->value();
- }
+ final public function isBiggerThan(self $other): bool
+ {
+ return $this->value() > $other->value();
+ }
}
diff --git a/src/Shared/Domain/ValueObject/SimpleUuid.php b/src/Shared/Domain/ValueObject/SimpleUuid.php
new file mode 100644
index 000000000..250f41c40
--- /dev/null
+++ b/src/Shared/Domain/ValueObject/SimpleUuid.php
@@ -0,0 +1,7 @@
+value = $value;
- }
-
- public function value(): string
- {
- return $this->value;
- }
-
- public function __toString()
- {
- return $this->value();
- }
+ final public function value(): string
+ {
+ return $this->value;
+ }
}
diff --git a/src/Shared/Domain/ValueObject/Uuid.php b/src/Shared/Domain/ValueObject/Uuid.php
index 1108ae90c..63a30fcc8 100644
--- a/src/Shared/Domain/ValueObject/Uuid.php
+++ b/src/Shared/Domain/ValueObject/Uuid.php
@@ -1,44 +1,44 @@
ensureIsValidUuid($value);
-
- $this->value = $value;
- }
-
- public static function random(): self
- {
- return new self(RamseyUuid::uuid4()->toString());
- }
-
- public function value(): string
- {
- return $this->value;
- }
-
- private function ensureIsValidUuid($id): void
- {
- if (!RamseyUuid::isValid($id)) {
- throw new InvalidArgumentException(
- sprintf('<%s> does not allow the value <%s>.', static::class, is_scalar($id) ? $id : gettype($id))
- );
- }
- }
-
- public function __toString()
- {
- return $this->value();
- }
+ final public function __construct(protected string $value)
+ {
+ $this->ensureIsValidUuid($value);
+ }
+
+ final public static function random(): self
+ {
+ return new static(RamseyUuid::uuid4()->toString());
+ }
+
+ final public function value(): string
+ {
+ return $this->value;
+ }
+
+ final public function equals(self $other): bool
+ {
+ return $this->value() === $other->value();
+ }
+
+ public function __toString(): string
+ {
+ return $this->value();
+ }
+
+ private function ensureIsValidUuid(string $id): void
+ {
+ if (!RamseyUuid::isValid($id)) {
+ throw new InvalidArgumentException(sprintf('<%s> does not allow the value <%s>.', self::class, $id));
+ }
+ }
}
diff --git a/src/Shared/Infrastructure/Api/Controller/ApiController.php b/src/Shared/Infrastructure/Api/Controller/ApiController.php
deleted file mode 100644
index 672110abf..000000000
--- a/src/Shared/Infrastructure/Api/Controller/ApiController.php
+++ /dev/null
@@ -1,51 +0,0 @@
-queryBus = $queryBus;
- $this->commandBus = $commandBus;
- $this->exceptionHandler = $exceptionHandler;
-
- each($this->exceptionRegistrar(), $this->exceptions());
- }
-
- abstract protected function exceptions(): array;
-
- protected function dispatch(Command $command): void
- {
- $this->commandBus->dispatch($command);
- }
-
- protected function ask(Query $query): ?Response
- {
- return $this->queryBus->ask($query);
- }
-
- private function exceptionRegistrar(): callable
- {
- return function ($httpCode, $exception): void {
- $this->exceptionHandler->register($exception, $httpCode);
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionLoggerSubscriber.php b/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionLoggerSubscriber.php
deleted file mode 100644
index f4df7be9a..000000000
--- a/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionLoggerSubscriber.php
+++ /dev/null
@@ -1,70 +0,0 @@
-logger = $logger;
- $this->exceptionHandler = $exceptionHandler;
- }
-
- public static function getSubscribedEvents(): array
- {
- return [KernelEvents::EXCEPTION => ['onKernelException', 1]];
- }
-
- public function onKernelException(GetResponseForExceptionEvent $event): void
- {
- $exception = $event->getException();
-
- $this->logException(
- $exception,
- sprintf(
- 'Uncaught PHP Exception %s: "%s" at %s line %s',
- get_class($exception),
- $exception->getMessage(),
- $exception->getFile(),
- $exception->getLine()
- )
- );
- }
-
- protected function logException(Exception $exception, $message): void
- {
- $level = $this->logLevel($this->exceptionStatusCode($exception));
-
- $this->logger->log($level, $message, ['exception' => $exception]);
- }
-
- protected function exceptionStatusCode(Exception $exception)
- {
- $statusCode = 500;
- $exceptionClass = get_class($exception);
-
- if ($this->exceptionHandler->exists($exceptionClass)) {
- $statusCode = $this->exceptionHandler->getStatusCode($exceptionClass);
- }
-
- return $statusCode;
- }
-
- private function logLevel($statusCode): string
- {
- return $statusCode >= 500 ? LogLevel::CRITICAL : LogLevel::ERROR;
- }
-}
diff --git a/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionSubscriber.php b/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionSubscriber.php
deleted file mode 100644
index 1ecc1ae32..000000000
--- a/src/Shared/Infrastructure/Api/EventSubscriber/ApiExceptionSubscriber.php
+++ /dev/null
@@ -1,67 +0,0 @@
-viewHandler = $viewHandler;
- $this->exceptionHandler = $exceptionHandler;
- }
-
- public static function getSubscribedEvents(): array
- {
- return [KernelEvents::EXCEPTION => ['onKernelException', 0]];
- }
-
- public function onKernelException(GetResponseForExceptionEvent $event): void
- {
- $exception = $event->getException();
- $exceptionClass = get_class($exception);
-
- if ($this->exceptionHandler->exists($exceptionClass)) {
- $event->setResponse($this->createResponseFromApiErrorException($exception));
- }
- }
-
- private function createResponseFromApiErrorException(Exception $exception): Response
- {
- $data = [
- 'code' => $this->getExceptionCode($exception),
- 'message' => $exception->getMessage(),
- ];
-
- return $this->viewHandler->handle(
- View::create($data, $this->exceptionHandler->getStatusCode(get_class($exception)))
- );
- }
-
- private function getExceptionCode(Exception $exception)
- {
- $moduleExceptionClass = DomainError::class;
-
- return $exception instanceof $moduleExceptionClass ? $this->domainErrorCode($exception) : $exception->getCode();
- }
-
- private function domainErrorCode($error): string
- {
- /** @var DomainError $error */
- return $error->errorCode();
- }
-}
diff --git a/src/Shared/Infrastructure/Api/EventSubscriber/ApiResponseViewSubscriber.php b/src/Shared/Infrastructure/Api/EventSubscriber/ApiResponseViewSubscriber.php
deleted file mode 100644
index 1765d8067..000000000
--- a/src/Shared/Infrastructure/Api/EventSubscriber/ApiResponseViewSubscriber.php
+++ /dev/null
@@ -1,28 +0,0 @@
- ['onKernelView', 200]];
- }
-
- public function onKernelView(GetResponseForControllerResultEvent $event): void
- {
- $result = $event->getControllerResult();
-
- if ($result instanceof ApiHttpResponse) {
- $event->setControllerResult(new View($result->data(), $result->statusCode(), $result->headers()));
- }
- }
-}
diff --git a/src/Shared/Infrastructure/Api/Exception/ApiExceptionsHttpStatusCodeMapping.php b/src/Shared/Infrastructure/Api/Exception/ApiExceptionsHttpStatusCodeMapping.php
deleted file mode 100644
index 36b165579..000000000
--- a/src/Shared/Infrastructure/Api/Exception/ApiExceptionsHttpStatusCodeMapping.php
+++ /dev/null
@@ -1,30 +0,0 @@
- Response::HTTP_BAD_REQUEST,
- ];
-
- public function register($exceptionClass, $statusCode): void
- {
- $this->exceptions[$exceptionClass] = $statusCode;
- }
-
- public function exists($exceptionClass): bool
- {
- return array_key_exists($exceptionClass, $this->exceptions);
- }
-
- public function getStatusCode($exceptionClass)
- {
- return $this->exceptions[$exceptionClass];
- }
-}
diff --git a/src/Shared/Infrastructure/Api/Response/ApiHttpAcceptedResponse.php b/src/Shared/Infrastructure/Api/Response/ApiHttpAcceptedResponse.php
deleted file mode 100644
index 1639cc49d..000000000
--- a/src/Shared/Infrastructure/Api/Response/ApiHttpAcceptedResponse.php
+++ /dev/null
@@ -1,20 +0,0 @@
- sprintf('%s/status/%s', $currentUrl, $requestId->value())], $headers)
- );
- }
-}
diff --git a/src/Shared/Infrastructure/Api/Response/ApiHttpCreatedResponse.php b/src/Shared/Infrastructure/Api/Response/ApiHttpCreatedResponse.php
deleted file mode 100644
index 3af611332..000000000
--- a/src/Shared/Infrastructure/Api/Response/ApiHttpCreatedResponse.php
+++ /dev/null
@@ -1,15 +0,0 @@
-data = $data;
- $this->statusCode = $statusCode;
- $this->headers = $headers;
- }
-
- public function data(): ?array
- {
- return $this->data;
- }
-
- public function statusCode(): int
- {
- return $this->statusCode;
- }
-
- public function headers(): array
- {
- return $this->headers;
- }
-}
diff --git a/src/Shared/Infrastructure/Api/Serializer/ApiSerializerDriver.php b/src/Shared/Infrastructure/Api/Serializer/ApiSerializerDriver.php
deleted file mode 100644
index afe143ca9..000000000
--- a/src/Shared/Infrastructure/Api/Serializer/ApiSerializerDriver.php
+++ /dev/null
@@ -1,35 +0,0 @@
-addResourceFile(__FILE__);
- }
-
- public function getMetadata(): array
- {
- return [
- StudentResponse::class => [
- 'id' => ['type' => 'string'],
- 'name' => ['type' => 'string'],
- 'totalPendingVideos' => ['type' => 'string'],
- ],
- VideoResponse::class => [
- 'id' => ['type' => 'string'],
- 'type' => ['type' => 'string'],
- 'title' => ['type' => 'string'],
- 'url' => ['type' => 'string'],
- 'courseId' => ['type' => 'string'],
- ],
- ];
- }
-}
diff --git a/src/Shared/Infrastructure/Api/Serializer/DateTimeHandler.php b/src/Shared/Infrastructure/Api/Serializer/DateTimeHandler.php
deleted file mode 100644
index c4d3c3b9a..000000000
--- a/src/Shared/Infrastructure/Api/Serializer/DateTimeHandler.php
+++ /dev/null
@@ -1,157 +0,0 @@
-defaultFormat = $defaultFormat;
- $this->defaultTimezone = new DateTimeZone($defaultTimezone);
- $this->xmlCData = $xmlCData;
- }
-
- public static function getSubscribingMethods(): array
- {
- $methods = [];
- $types = ['DateTime', 'DateInterval'];
-
- foreach (['json', 'xml', 'yml'] as $format) {
- $methods[] = [
- 'type' => 'DateTime',
- 'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
- 'format' => $format,
- ];
-
- foreach ($types as $type) {
- $methods[] = [
- 'type' => $type,
- 'format' => $format,
- 'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
- 'method' => 'serialize' . $type,
- ];
- }
- }
-
- return $methods;
- }
-
- public function serializeDateTime(VisitorInterface $visitor, DateTimeInterface $date, array $type, Context $context)
- {
- if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) {
- return $visitor->visitSimpleString($date->format($this->getFormat($type)), $type, $context);
- }
-
- return $visitor->visitString($date->format($this->getFormat($type)), $type, $context);
- }
-
- public function serializeDateInterval(VisitorInterface $visitor, DateInterval $date, array $type, Context $context)
- {
- $iso8601DateIntervalString = $this->format($date);
-
- if ($visitor instanceof XmlSerializationVisitor && false === $this->xmlCData) {
- return $visitor->visitSimpleString($iso8601DateIntervalString, $type, $context);
- }
-
- return $visitor->visitString($iso8601DateIntervalString, $type, $context);
- }
-
- public function format(DateInterval $dateInterval): string
- {
- $format = 'P';
-
- if (0 < $dateInterval->y) {
- $format .= $dateInterval->y . 'Y';
- }
-
- if (0 < $dateInterval->m) {
- $format .= $dateInterval->m . 'M';
- }
-
- if (0 < $dateInterval->d) {
- $format .= $dateInterval->d . 'D';
- }
-
- if (0 < $dateInterval->h || 0 < $dateInterval->i || 0 < $dateInterval->s) {
- $format .= 'T';
- }
-
- if (0 < $dateInterval->h) {
- $format .= $dateInterval->h . 'H';
- }
-
- if (0 < $dateInterval->i) {
- $format .= $dateInterval->i . 'M';
- }
-
- if (0 < $dateInterval->s) {
- $format .= $dateInterval->s . 'S';
- }
-
- return $format;
- }
-
- public function deserializeDateTimeFromXml(XmlDeserializationVisitor $unused, $data, array $type)
- {
- $attributes = $data->attributes('xsi', true);
- if (isset($attributes['nil'][0]) && (string) $attributes['nil'][0] === 'true') {
- return null;
- }
-
- return $this->parseDateTime($data, $type);
- }
-
- public function deserializeDateTimeFromJson(JsonDeserializationVisitor $unused, $data, array $type)
- {
- if (null === $data) {
- return null;
- }
-
- return $this->parseDateTime($data, $type);
- }
-
- /**
- * @param array $type
- *
- * @return string
- *
- */
- private function getFormat(array $type): string
- {
- return $type['params'][0] ?? $this->defaultFormat;
- }
-
- private function parseDateTime($data, array $type)
- {
- $timezone = isset($type['params'][1]) ? new DateTimeZone($type['params'][1]) : $this->defaultTimezone;
- $format = $this->getFormat($type);
- $datetime = DateTime::createFromFormat($format, (string) $data, $timezone);
- if (false === $datetime) {
- throw new RuntimeException(sprintf('Invalid datetime "%s", expected format %s.', $data, $format));
- }
-
- return $datetime;
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/AsyncRequest.php b/src/Shared/Infrastructure/Bus/AsyncRequest.php
deleted file mode 100644
index f7a8e4e5b..000000000
--- a/src/Shared/Infrastructure/Bus/AsyncRequest.php
+++ /dev/null
@@ -1,30 +0,0 @@
-requestId = $requestId;
- $this->status = $status;
- $this->response = $response;
- }
-
- public function toArray(): array
- {
- return [
- 'request_id' => $this->requestId->value(),
- 'status' => $this->status->value(),
- 'response' => $this->response->values(),
- ];
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/AsyncRequestFinder.php b/src/Shared/Infrastructure/Bus/AsyncRequestFinder.php
deleted file mode 100644
index 18710a744..000000000
--- a/src/Shared/Infrastructure/Bus/AsyncRequestFinder.php
+++ /dev/null
@@ -1,38 +0,0 @@
-pendingRequestsFilePath = $pendingRequestsFilePath;
- $this->inProgressRequestsFilePath = $inProgressRequestsFilePath;
- $this->processedRequestsFilePath = $processedRequestsFilePath;
- }
-
- public function __invoke(Uuid $requestId): AsyncRequest
- {
- // Is it in pending?
-
- // Is it in progress?
-
- // Has it been processed?
-
- throw new AsyncRequestNotExists($requestId);
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/AsyncRequestNotExists.php b/src/Shared/Infrastructure/Bus/AsyncRequestNotExists.php
deleted file mode 100644
index ebdcb1a1d..000000000
--- a/src/Shared/Infrastructure/Bus/AsyncRequestNotExists.php
+++ /dev/null
@@ -1,9 +0,0 @@
- is an invalid async request status', $value));
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/AsyncResponse.php b/src/Shared/Infrastructure/Bus/AsyncResponse.php
deleted file mode 100644
index 2a551fadf..000000000
--- a/src/Shared/Infrastructure/Bus/AsyncResponse.php
+++ /dev/null
@@ -1,20 +0,0 @@
-values = $values;
- }
-
- public function values(): array
- {
- return $this->values;
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/CallableFirstParameterExtractor.php b/src/Shared/Infrastructure/Bus/CallableFirstParameterExtractor.php
new file mode 100644
index 000000000..23564a9e1
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/CallableFirstParameterExtractor.php
@@ -0,0 +1,80 @@
+ $parameterExtractor->extract($handler);
+ }
+
+ private static function pipedCallablesReducer(): callable
+ {
+ return static function (array $subscribers, DomainEventSubscriber $subscriber): array {
+ $subscribedEvents = $subscriber::subscribedTo();
+
+ foreach ($subscribedEvents as $subscribedEvent) {
+ $subscribers[$subscribedEvent][] = $subscriber;
+ }
+
+ return $subscribers;
+ };
+ }
+
+ private static function unflatten(): callable
+ {
+ return static fn (mixed $value): array => [$value];
+ }
+
+ public function extract(object $class): ?string
+ {
+ $reflector = new ReflectionClass($class);
+ $method = $reflector->getMethod('__invoke');
+
+ if ($this->hasOnlyOneParameter($method)) {
+ return $this->firstParameterClassFrom($method);
+ }
+
+ return null;
+ }
+
+ private function firstParameterClassFrom(ReflectionMethod $method): string
+ {
+ /** @var ReflectionNamedType|null $fistParameterType */
+ $fistParameterType = $method->getParameters()[0]->getType();
+
+ if ($fistParameterType === null) {
+ throw new LogicException('Missing type hint for the first parameter of __invoke');
+ }
+
+ return $fistParameterType->getName();
+ }
+
+ private function hasOnlyOneParameter(ReflectionMethod $method): bool
+ {
+ return $method->getNumberOfParameters() === 1;
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Command/CommandBusAsync.php b/src/Shared/Infrastructure/Bus/Command/CommandBusAsync.php
deleted file mode 100644
index b2dce83cd..000000000
--- a/src/Shared/Infrastructure/Bus/Command/CommandBusAsync.php
+++ /dev/null
@@ -1,25 +0,0 @@
-pendingRequestsFilePath = $pendingRequestsFilePath;
- }
-
- public function dispatch(Command $command): void
- {
- file_put_contents($this->pendingRequestsFilePath, apply(new MessageSerializer(), [$command]));
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Command/CommandNotRegisteredError.php b/src/Shared/Infrastructure/Bus/Command/CommandNotRegisteredError.php
index 197d74056..fdb18e189 100644
--- a/src/Shared/Infrastructure/Bus/Command/CommandNotRegisteredError.php
+++ b/src/Shared/Infrastructure/Bus/Command/CommandNotRegisteredError.php
@@ -1,30 +1,18 @@
command = $command;
-
- parent::__construct();
- }
-
- public function errorCode(): string
- {
- return 'command_bus_not_registered_error';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The command <%s> has not been registered', get_class($this->command));
- }
+ parent::__construct("The command <$commandClass> hasn't a command handler associated");
+ }
}
diff --git a/src/Shared/Infrastructure/Bus/Command/InMemorySymfonyCommandBus.php b/src/Shared/Infrastructure/Bus/Command/InMemorySymfonyCommandBus.php
new file mode 100644
index 000000000..4f6bbed0e
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Command/InMemorySymfonyCommandBus.php
@@ -0,0 +1,41 @@
+bus = new MessageBus(
+ [
+ new HandleMessageMiddleware(
+ new HandlersLocator(CallableFirstParameterExtractor::forCallables($commandHandlers))
+ ),
+ ]
+ );
+ }
+
+ public function dispatch(Command $command): void
+ {
+ try {
+ $this->bus->dispatch($command);
+ } catch (NoHandlerForMessageException) {
+ throw new CommandNotRegisteredError($command);
+ } catch (HandlerFailedException $error) {
+ throw $error->getPrevious() ?? $error;
+ }
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Command/SymfonySyncCommandBus.php b/src/Shared/Infrastructure/Bus/Command/SymfonySyncCommandBus.php
deleted file mode 100644
index cfd7c6404..000000000
--- a/src/Shared/Infrastructure/Bus/Command/SymfonySyncCommandBus.php
+++ /dev/null
@@ -1,38 +0,0 @@
-bus = new MessageBus(
- [
- new HandleMessageMiddleware(
- new HandlersLocator(CallableFirstParameterExtractor::forCallables($commandHandlers))
- ),
- ]
- );
- }
-
- public function dispatch(Command $command): void
- {
- try {
- $this->bus->dispatch($command);
- } catch (NoHandlerForMessageException $unused) {
- throw new CommandNotRegisteredError($command);
- }
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventJsonDeserializer.php b/src/Shared/Infrastructure/Bus/Event/DomainEventJsonDeserializer.php
new file mode 100644
index 000000000..3d73fa61b
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/DomainEventJsonDeserializer.php
@@ -0,0 +1,27 @@
+mapping->for($eventName);
+
+ return $eventClass::fromPrimitives(
+ $eventData['data']['attributes']['id'],
+ $eventData['data']['attributes'],
+ $eventData['data']['id'],
+ $eventData['data']['occurred_on']
+ );
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventJsonSerializer.php b/src/Shared/Infrastructure/Bus/Event/DomainEventJsonSerializer.php
new file mode 100644
index 000000000..293e5f996
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/DomainEventJsonSerializer.php
@@ -0,0 +1,25 @@
+ [
+ 'id' => $domainEvent->eventId(),
+ 'type' => $domainEvent::eventName(),
+ 'occurred_on' => $domainEvent->occurredOn(),
+ 'attributes' => array_merge($domainEvent->toPrimitives(), ['id' => $domainEvent->aggregateId()]),
+ ],
+ 'meta' => [],
+ ]
+ );
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventMapping.php b/src/Shared/Infrastructure/Bus/Event/DomainEventMapping.php
index f1135e20a..697acad8d 100644
--- a/src/Shared/Infrastructure/Bus/Event/DomainEventMapping.php
+++ b/src/Shared/Infrastructure/Bus/Event/DomainEventMapping.php
@@ -1,44 +1,43 @@
mapping = reduce($this->eventsExtractor(), $mapping);
- }
-
- public function for(string $name)
- {
- return $this->mapping[$name];
- }
-
- public function all()
- {
- return $this->mapping;
- }
-
- private function eventsExtractor(): callable
- {
- return function (array $mapping, DomainEventSubscriber $subscriber) {
- return array_merge($mapping, reindex($this->eventNameExtractor(), $subscriber::subscribedTo()));
- };
- }
-
- private function eventNameExtractor(): callable
- {
- return function (DomainEvent $event): string {
- return $event::eventName();
- };
- }
+ private array $mapping;
+
+ public function __construct(iterable $mapping)
+ {
+ $this->mapping = reduce($this->eventsExtractor(), $mapping, []);
+ }
+
+ public function for(string $name): string
+ {
+ if (!isset($this->mapping[$name])) {
+ throw new RuntimeException("The Domain Event Class for <$name> doesn't exists or have no subscribers");
+ }
+
+ return $this->mapping[$name];
+ }
+
+ private function eventsExtractor(): callable
+ {
+ return fn (array $mapping, DomainEventSubscriber $subscriber): array => array_merge(
+ $mapping,
+ reindex($this->eventNameExtractor(), $subscriber::subscribedTo())
+ );
+ }
+
+ private function eventNameExtractor(): callable
+ {
+ return static fn (string $eventClass): string => $eventClass::eventName();
+ }
}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberConfig.php b/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberConfig.php
deleted file mode 100644
index d8375647b..000000000
--- a/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberConfig.php
+++ /dev/null
@@ -1,66 +0,0 @@
- 1,
- 'priority' => 0,
- 'events_to_process' => 200,
- 'enabled' => true,
- ];
- private $config;
-
- public function __construct(array $config)
- {
- $this->config = array_merge(self::$defaultConfig, $config);
- }
-
- public function name(): string
- {
- return $this->config['name'];
- }
-
- public function processes()
- {
- return $this->config['processes'];
- }
-
- public function priority()
- {
- return $this->config['priority'];
- }
-
- public function eventsToProcess()
- {
- return $this->config['events_to_process'];
- }
-
- public function subscribedEvents(): array
- {
- return $this->config['subscribed_events'];
- }
-
- public function isSubscribedToEvent($eventName): bool
- {
- return in_array($eventName, $this->subscribedEvents(), false);
- }
-
- public function isEnabled(): bool
- {
- return $this->config['enabled'];
- }
-
- public function enabledString(): string
- {
- return $this->isEnabled() ? 'true' : 'false';
- }
-
- public static function blank(): DomainEventSubscriberConfig
- {
- return new self([]);
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberLocator.php b/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberLocator.php
new file mode 100644
index 000000000..d39aa7651
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/DomainEventSubscriberLocator.php
@@ -0,0 +1,50 @@
+mapping = iterator_to_array($mapping);
+ }
+
+ public function allSubscribedTo(string $eventClass): array
+ {
+ $formatted = CallableFirstParameterExtractor::forPipedCallables($this->mapping);
+
+ return $formatted[$eventClass];
+ }
+
+ public function withRabbitMqQueueNamed(string $queueName): callable | DomainEventSubscriber
+ {
+ $subscriber = search(
+ static fn (DomainEventSubscriber $subscriber): bool => RabbitMqQueueNameFormatter::format($subscriber) ===
+ $queueName,
+ $this->mapping
+ );
+
+ if ($subscriber === null) {
+ throw new RuntimeException("There are no subscribers for the <$queueName> queue");
+ }
+
+ return $subscriber;
+ }
+
+ public function all(): array
+ {
+ return $this->mapping;
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/DomainEventSubscribersConfiguration.php b/src/Shared/Infrastructure/Bus/Event/DomainEventSubscribersConfiguration.php
deleted file mode 100644
index a68a19e63..000000000
--- a/src/Shared/Infrastructure/Bus/Event/DomainEventSubscribersConfiguration.php
+++ /dev/null
@@ -1,62 +0,0 @@
-byNameFinder($name), self::$config));
- }
-
- /** @return DomainEventSubscriberConfig[] */
- public function all(): array
- {
- return map($this->domainEventConfigCreator(), self::$config);
- }
-
- /** @return DomainEventSubscriberConfig[] */
- public function allWithEvent(string $name): array
- {
- return map($this->domainEventConfigCreator(), filter($this->containingEvent($name), self::$config));
- }
-
- private function domainEventConfigCreator(): callable
- {
- return function (array $configuration): DomainEventSubscriberConfig {
- return new DomainEventSubscriberConfig($configuration);
- };
- }
-
- private function byNameFinder(string $name): callable
- {
- return function (array $config) use ($name): bool {
- return $name === $config['name'];
- };
- }
-
- private function containingEvent(string $name): callable
- {
- return function (array $config) use ($name): bool {
- return in_array($name, $config['subscribed_events'], false);
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/Guard/DomainEventDataValidator.php b/src/Shared/Infrastructure/Bus/Event/Guard/DomainEventDataValidator.php
deleted file mode 100644
index 45db45ab3..000000000
--- a/src/Shared/Infrastructure/Bus/Event/Guard/DomainEventDataValidator.php
+++ /dev/null
@@ -1,41 +0,0 @@
-', $eventClass));
- }
- }
-
- private static function areAllParametersValid(array $data, array $rules): bool
- {
- return self::hasAllParameters($data, $rules) && all(self::parameterIsValid($data), $rules);
- }
-
- private static function hasAllParameters(array $data, array $rules): bool
- {
- return empty(array_diff_key($rules, $data));
- }
-
- private static function parameterIsValid(array $data): callable
- {
- return function (array $meta, string $attribute) use ($data) {
- return Validator::isValid($data[$attribute], self::extractType($meta));
- };
- }
-
- private static function extractType(array $meta)
- {
- return $meta[0];
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/InMemory/InMemorySymfonyEventBus.php b/src/Shared/Infrastructure/Bus/Event/InMemory/InMemorySymfonyEventBus.php
new file mode 100644
index 000000000..db19cb695
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/InMemory/InMemorySymfonyEventBus.php
@@ -0,0 +1,39 @@
+bus = new MessageBus(
+ [
+ new HandleMessageMiddleware(
+ new HandlersLocator(CallableFirstParameterExtractor::forPipedCallables($subscribers))
+ ),
+ ]
+ );
+ }
+
+ public function publish(DomainEvent ...$events): void
+ {
+ foreach ($events as $event) {
+ try {
+ $this->bus->dispatch($event);
+ } catch (NoHandlerForMessageException) {
+ }
+ }
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineDomainEventsConsumer.php b/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineDomainEventsConsumer.php
new file mode 100644
index 000000000..a07e3b09f
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineDomainEventsConsumer.php
@@ -0,0 +1,68 @@
+connection = $entityManager->getConnection();
+ }
+
+ public function consume(callable $subscribers, int $eventsToConsume): void
+ {
+ $events = $this->connection
+ ->executeQuery("SELECT * FROM domain_events ORDER BY occurred_on ASC LIMIT $eventsToConsume")
+ ->fetchAllAssociative();
+
+ each($this->executeSubscribers($subscribers), $events);
+
+ $ids = implode(', ', map($this->idExtractor(), $events));
+
+ if (!empty($ids)) {
+ $this->connection->executeStatement("DELETE FROM domain_events WHERE id IN ($ids)");
+ }
+ }
+
+ private function executeSubscribers(callable $subscribers): callable
+ {
+ return function (array $rawEvent) use ($subscribers): void {
+ try {
+ $domainEventClass = $this->eventMapping->for($rawEvent['name']);
+ $domainEvent = $domainEventClass::fromPrimitives(
+ $rawEvent['aggregate_id'],
+ Utils::jsonDecode($rawEvent['body']),
+ $rawEvent['id'],
+ $this->formatDate($rawEvent['occurred_on'])
+ );
+
+ $subscribers($domainEvent);
+ } catch (RuntimeException) {
+ }
+ };
+ }
+
+ private function formatDate(mixed $stringDate): string
+ {
+ return Utils::dateToString(new DateTimeImmutable($stringDate));
+ }
+
+ private function idExtractor(): callable
+ {
+ return static fn (array $event): string => "'{$event['id']}'";
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBus.php b/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBus.php
new file mode 100644
index 000000000..2b21c3897
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBus.php
@@ -0,0 +1,49 @@
+connection = $entityManager->getConnection();
+ }
+
+ public function publish(DomainEvent ...$events): void
+ {
+ each($this->publisher(), $events);
+ }
+
+ private function publisher(): callable
+ {
+ return function (DomainEvent $domainEvent): void {
+ $id = $this->connection->quote($domainEvent->eventId());
+ $aggregateId = $this->connection->quote($domainEvent->aggregateId());
+ $name = $this->connection->quote($domainEvent::eventName());
+ $body = $this->connection->quote(Utils::jsonEncode($domainEvent->toPrimitives()));
+ $occurredOn = $this->connection->quote(
+ Utils::stringToDate($domainEvent->occurredOn())->format(self::DATABASE_TIMESTAMP_FORMAT)
+ );
+
+ $this->connection->executeStatement(
+ <<declareExchange($exchangeName);
+ $this->declareExchange($retryExchangeName);
+ $this->declareExchange($deadLetterExchangeName);
+
+ $this->declareQueues($exchangeName, $retryExchangeName, $deadLetterExchangeName, ...$subscribers);
+ }
+
+ private function declareExchange(string $exchangeName): void
+ {
+ $exchange = $this->connection->exchange($exchangeName);
+ $exchange->setType(AMQP_EX_TYPE_TOPIC);
+ $exchange->setFlags(AMQP_DURABLE);
+ $exchange->declareExchange();
+ }
+
+ private function declareQueues(
+ string $exchangeName,
+ string $retryExchangeName,
+ string $deadLetterExchangeName,
+ DomainEventSubscriber ...$subscribers
+ ): void {
+ each($this->queueDeclarator($exchangeName, $retryExchangeName, $deadLetterExchangeName), $subscribers);
+ }
+
+ private function queueDeclarator(
+ string $exchangeName,
+ string $retryExchangeName,
+ string $deadLetterExchangeName
+ ): callable {
+ return function (DomainEventSubscriber $subscriber) use (
+ $exchangeName,
+ $retryExchangeName,
+ $deadLetterExchangeName
+ ): void {
+ $queueName = RabbitMqQueueNameFormatter::format($subscriber);
+ $retryQueueName = RabbitMqQueueNameFormatter::formatRetry($subscriber);
+ $deadLetterQueueName = RabbitMqQueueNameFormatter::formatDeadLetter($subscriber);
+
+ $queue = $this->declareQueue($queueName);
+ $retryQueue = $this->declareQueue($retryQueueName, $exchangeName, $queueName, 1000);
+ $deadLetterQueue = $this->declareQueue($deadLetterQueueName);
+
+ $queue->bind($exchangeName, $queueName);
+ $retryQueue->bind($retryExchangeName, $queueName);
+ $deadLetterQueue->bind($deadLetterExchangeName, $queueName);
+
+ foreach ($subscriber::subscribedTo() as $eventClass) {
+ $queue->bind($exchangeName, $eventClass::eventName());
+ }
+ };
+ }
+
+ private function declareQueue(
+ string $name,
+ string $deadLetterExchange = null,
+ string $deadLetterRoutingKey = null,
+ int $messageTtl = null
+ ): AMQPQueue {
+ $queue = $this->connection->queue($name);
+
+ if ($deadLetterExchange !== null) {
+ $queue->setArgument('x-dead-letter-exchange', $deadLetterExchange);
+ }
+
+ if ($deadLetterRoutingKey !== null) {
+ $queue->setArgument('x-dead-letter-routing-key', $deadLetterRoutingKey);
+ }
+
+ if ($messageTtl !== null) {
+ $queue->setArgument('x-message-ttl', $messageTtl);
+ }
+
+ $queue->setFlags(AMQP_DURABLE);
+ $queue->declareQueue();
+
+ return $queue;
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqConnection.php b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqConnection.php
new file mode 100644
index 000000000..ea3bcb9fd
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqConnection.php
@@ -0,0 +1,68 @@
+channel());
+ $queue->setName($name);
+
+ self::$queues[$name] = $queue;
+ }
+
+ return self::$queues[$name];
+ }
+
+ public function exchange(string $name): AMQPExchange
+ {
+ if (!array_key_exists($name, self::$exchanges)) {
+ $exchange = new AMQPExchange($this->channel());
+ $exchange->setName($name);
+
+ self::$exchanges[$name] = $exchange;
+ }
+
+ return self::$exchanges[$name];
+ }
+
+ private function channel(): AMQPChannel
+ {
+ if (!self::$channel?->isConnected()) {
+ self::$channel = new AMQPChannel($this->connection());
+ }
+
+ return self::$channel;
+ }
+
+ private function connection(): AMQPConnection
+ {
+ if (self::$connection === null) {
+ self::$connection = new AMQPConnection($this->configuration);
+ }
+
+ if (!self::$connection->isConnected()) {
+ self::$connection->pconnect();
+ }
+
+ return self::$connection;
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqDomainEventsConsumer.php b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqDomainEventsConsumer.php
new file mode 100644
index 000000000..ea18ec7ce
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqDomainEventsConsumer.php
@@ -0,0 +1,93 @@
+connection->queue($queueName)->consume($this->consumer($subscriber));
+ } catch (AMQPQueueException) {
+ // We don't want to raise an error if there are no messages in the queue
+ }
+ }
+
+ private function consumer(callable $subscriber): callable
+ {
+ return function (AMQPEnvelope $envelope, AMQPQueue $queue) use ($subscriber): void {
+ $event = $this->deserializer->deserialize($envelope->getBody());
+
+ try {
+ $subscriber($event);
+ } catch (Throwable $error) {
+ $this->handleConsumptionError($envelope, $queue);
+
+ throw $error;
+ }
+
+ $queue->ack($envelope->getDeliveryTag());
+ };
+ }
+
+ private function handleConsumptionError(AMQPEnvelope $envelope, AMQPQueue $queue): void
+ {
+ $this->hasBeenRedeliveredTooMuch($envelope)
+ ? $this->sendToDeadLetter($envelope, $queue)
+ : $this->sendToRetry($envelope, $queue);
+
+ $queue->ack($envelope->getDeliveryTag());
+ }
+
+ private function hasBeenRedeliveredTooMuch(AMQPEnvelope $envelope): bool
+ {
+ return get('redelivery_count', $envelope->getHeaders(), 0) >= $this->maxRetries;
+ }
+
+ private function sendToDeadLetter(AMQPEnvelope $envelope, AMQPQueue $queue): void
+ {
+ $this->sendMessageTo(RabbitMqExchangeNameFormatter::deadLetter($this->exchangeName), $envelope, $queue);
+ }
+
+ private function sendToRetry(AMQPEnvelope $envelope, AMQPQueue $queue): void
+ {
+ $this->sendMessageTo(RabbitMqExchangeNameFormatter::retry($this->exchangeName), $envelope, $queue);
+ }
+
+ private function sendMessageTo(string $exchangeName, AMQPEnvelope $envelope, AMQPQueue $queue): void
+ {
+ $headers = $envelope->getHeaders();
+
+ $this->connection->exchange($exchangeName)->publish(
+ $envelope->getBody(),
+ $queue->getName(),
+ AMQP_NOPARAM,
+ [
+ 'message_id' => $envelope->getMessageId(),
+ 'content_type' => $envelope->getContentType(),
+ 'content_encoding' => $envelope->getContentEncoding(),
+ 'priority' => $envelope->getPriority(),
+ 'headers' => assoc($headers, 'redelivery_count', get('redelivery_count', $headers, 0) + 1),
+ ]
+ );
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBus.php b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBus.php
new file mode 100644
index 000000000..1d7bc1a89
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBus.php
@@ -0,0 +1,56 @@
+publisher(), $events);
+ }
+
+ private function publisher(): callable
+ {
+ return function (DomainEvent $event): void {
+ try {
+ $this->publishEvent($event);
+ } catch (AMQPException) {
+ $this->failoverPublisher->publish($event);
+ }
+ };
+ }
+
+ private function publishEvent(DomainEvent $event): void
+ {
+ $body = DomainEventJsonSerializer::serialize($event);
+ $routingKey = $event::eventName();
+ $messageId = $event->eventId();
+
+ $this->connection->exchange($this->exchangeName)->publish(
+ $body,
+ $routingKey,
+ AMQP_NOPARAM,
+ [
+ 'message_id' => $messageId,
+ 'content_type' => 'application/json',
+ 'content_encoding' => 'utf-8',
+ ]
+ );
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqExchangeNameFormatter.php b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqExchangeNameFormatter.php
new file mode 100644
index 000000000..7e9be1dc9
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqExchangeNameFormatter.php
@@ -0,0 +1,18 @@
+ Utils::toSnakeCase($text);
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Event/Serialize/DomainEventUnserializer.php b/src/Shared/Infrastructure/Bus/Event/Serialize/DomainEventUnserializer.php
deleted file mode 100644
index 6592ddd18..000000000
--- a/src/Shared/Infrastructure/Bus/Event/Serialize/DomainEventUnserializer.php
+++ /dev/null
@@ -1,38 +0,0 @@
-eventMapping = $eventMapping;
- }
-
- public function __invoke(string $serializedEvent): DomainEvent
- {
- $parsedEvent = json_decode($serializedEvent, true);
-
- $eventName = $parsedEvent['type'];
- $eventClass = $this->eventMapping->for($eventName);
-
- return new $eventClass(get('id', $parsedEvent), reindex($this->toCamel(), $parsedEvent));
- }
-
- private function toCamel(): callable
- {
- return function ($unused, $key): string {
- return snake_to_camel($key);
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/SubscribersMapping.php b/src/Shared/Infrastructure/Bus/Event/SubscribersMapping.php
deleted file mode 100644
index 1ea35a5f4..000000000
--- a/src/Shared/Infrastructure/Bus/Event/SubscribersMapping.php
+++ /dev/null
@@ -1,25 +0,0 @@
-events = array_merge($this->events, array_values($domainEvents));
- }
-
- public function publishRecorded(): void
- {
- each($this->eventPublisher(), $this->popEvents());
- }
-
- public function publish(DomainEvent ...$domainEvents): void
- {
- $this->record(...$domainEvents);
-
- $this->publishRecorded();
- }
-
- public function popPublishedEvents(): array
- {
- $events = $this->publishedEvents;
- $this->publishedEvents = [];
-
- return $events;
- }
-
- public function hasEventsToPublish(): bool
- {
- return count($this->publishedEvents) > 0;
- }
-
- private function eventPublisher(): callable
- {
- return function (DomainEvent $event): void {
- $this->publishedEvents[] = $event;
- };
- }
-
- private function popEvents(): array
- {
- $events = $this->events;
- $this->events = [];
-
- return $events;
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/SymfonySyncEventBus.php b/src/Shared/Infrastructure/Bus/Event/SymfonySyncEventBus.php
deleted file mode 100644
index ad4b199de..000000000
--- a/src/Shared/Infrastructure/Bus/Event/SymfonySyncEventBus.php
+++ /dev/null
@@ -1,35 +0,0 @@
-bus = new MessageBus(
- [
- new HandleMessageMiddleware(
- new HandlersLocator(
- CallableFirstParameterExtractor::forPipedCallables($subscribers)
- )
- ),
- ]
- );
- }
-
- public function notify(DomainEvent $event): void
- {
- $this->bus->dispatch($event);
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Event/WithMonitoring/WithPrometheusMonitoringEventBus.php b/src/Shared/Infrastructure/Bus/Event/WithMonitoring/WithPrometheusMonitoringEventBus.php
new file mode 100644
index 000000000..c94edfdcc
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Event/WithMonitoring/WithPrometheusMonitoringEventBus.php
@@ -0,0 +1,34 @@
+monitor->registry()->getOrRegisterCounter(
+ $this->appName,
+ 'domain_event',
+ 'Domain Events',
+ ['name']
+ );
+
+ each(fn (DomainEvent $event) => $counter->inc(['name' => $event::eventName()]), $events);
+
+ $this->bus->publish(...$events);
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Middleware/MessageLoggerMiddleware.php b/src/Shared/Infrastructure/Bus/Middleware/MessageLoggerMiddleware.php
deleted file mode 100644
index 9299538ac..000000000
--- a/src/Shared/Infrastructure/Bus/Middleware/MessageLoggerMiddleware.php
+++ /dev/null
@@ -1,36 +0,0 @@
-logger = $logger;
- }
-
- public function __invoke(Message $message, callable $handler): ?callable
- {
- $this->logger->debug(
- 'New message dispatched',
- [
- 'type' => $message->messageType(),
- 'name' => $this->nameOf($message),
- ]
- );
-
- return $handler($message);
- }
-
- private function nameOf(Message $message): string
- {
- return get_class($message);
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Middleware/Middleware.php b/src/Shared/Infrastructure/Bus/Middleware/Middleware.php
deleted file mode 100644
index 03228bdc8..000000000
--- a/src/Shared/Infrastructure/Bus/Middleware/Middleware.php
+++ /dev/null
@@ -1,12 +0,0 @@
-handlers[$key][] = $handler;
- }
-
- public function find($key): array
- {
- return $this->handlers[$key];
- }
-}
diff --git a/src/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBus.php b/src/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBus.php
new file mode 100644
index 000000000..4812214d0
--- /dev/null
+++ b/src/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBus.php
@@ -0,0 +1,41 @@
+bus = new MessageBus(
+ [
+ new HandleMessageMiddleware(new HandlersLocator(CallableFirstParameterExtractor::forCallables($queryHandlers))),
+ ]
+ );
+ }
+
+ public function ask(Query $query): ?Response
+ {
+ try {
+ /** @var HandledStamp $stamp */
+ $stamp = $this->bus->dispatch($query)->last(HandledStamp::class);
+
+ return $stamp->getResult();
+ } catch (NoHandlerForMessageException) {
+ throw new QueryNotRegisteredError($query);
+ }
+ }
+}
diff --git a/src/Shared/Infrastructure/Bus/Query/QueryNotRegisteredError.php b/src/Shared/Infrastructure/Bus/Query/QueryNotRegisteredError.php
index 30306fc46..c79d4859c 100644
--- a/src/Shared/Infrastructure/Bus/Query/QueryNotRegisteredError.php
+++ b/src/Shared/Infrastructure/Bus/Query/QueryNotRegisteredError.php
@@ -1,30 +1,18 @@
query = $query;
-
- parent::__construct();
- }
-
- public function errorCode(): string
- {
- return 'query_bus_not_registered_error';
- }
-
- protected function errorMessage(): string
- {
- return sprintf('The query <%s> has not been registered', get_class($this->query));
- }
+ parent::__construct("The query <$queryClass> has no associated query handler");
+ }
}
diff --git a/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBus.php b/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBus.php
deleted file mode 100644
index 458c0e471..000000000
--- a/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBus.php
+++ /dev/null
@@ -1,43 +0,0 @@
-bus = new MessageBus(
- [
- new HandleMessageMiddleware(
- new HandlersLocator(CallableFirstParameterExtractor::forCallables($queryHandlers))
- ),
- ]
- );
- }
-
- public function ask(Query $query): ?Response
- {
- try {
- /** @var HandledStamp $stamp */
- $stamp = $this->bus->dispatch($query)->last(HandledStamp::class);
-
- return $stamp->getResult();
- } catch (NoHandlerForMessageException $unused) {
- throw new QueryNotRegisteredError($query);
- }
- }
-}
diff --git a/src/Shared/Infrastructure/Cdc/DatabaseMutationAction.php b/src/Shared/Infrastructure/Cdc/DatabaseMutationAction.php
new file mode 100644
index 000000000..fdad67057
--- /dev/null
+++ b/src/Shared/Infrastructure/Cdc/DatabaseMutationAction.php
@@ -0,0 +1,12 @@
+ CourseIdType::class,
- LessonIdType::NAME => LessonIdType::class,
- QuizStepQuestionsType::NAME => QuizStepQuestionsType::class,
- StudentIdType::NAME => StudentIdType::class,
- StepIdType::NAME => StepIdType::class,
- VideoIdType::NAME => VideoIdType::class,
- ];
-
- public static function register(): void
- {
- if (!self::$initialized) {
- each(self::registerType(), self::$types);
-
- self::$initialized = true;
- }
- }
-
- private static function registerType(): callable
- {
- return function ($class, $name): void {
- Type::addType($name, $class);
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Doctrine/DatabaseCleaner.php b/src/Shared/Infrastructure/Doctrine/DatabaseCleaner.php
deleted file mode 100644
index 0088df3bf..000000000
--- a/src/Shared/Infrastructure/Doctrine/DatabaseCleaner.php
+++ /dev/null
@@ -1,42 +0,0 @@
-getConnection();
-
- $tables = $this->tables($connection);
- $truncateTablesSql = $this->truncateDatabaseSql($tables);
-
- $connection->exec($truncateTablesSql);
- }
-
- private function truncateDatabaseSql(array $tables): string
- {
- $truncateTables = map($this->truncateTableSql(), $tables);
-
- return sprintf('SET FOREIGN_KEY_CHECKS = 0; %s SET FOREIGN_KEY_CHECKS = 1;', implode(' ', $truncateTables));
- }
-
- private function truncateTableSql(): callable
- {
- return function (array $table): string {
- return sprintf('TRUNCATE TABLE `%s`;', first($table));
- };
- }
-
- private function tables(Connection $connection): array
- {
- return $connection->query('SHOW TABLES')->fetchAll();
- }
-}
diff --git a/src/Shared/Infrastructure/Doctrine/DatabaseConnections.php b/src/Shared/Infrastructure/Doctrine/DatabaseConnections.php
index f69d71acb..86b62015a 100644
--- a/src/Shared/Infrastructure/Doctrine/DatabaseConnections.php
+++ b/src/Shared/Infrastructure/Doctrine/DatabaseConnections.php
@@ -1,55 +1,32 @@
connections[$name] = $entityManager;
- }
-
- public function clear(): void
- {
- each($this->clearer(), $this->connections);
- }
-
- public function allConnectionsClearer(): callable
- {
- return function (): void {
- $this->clear();
- };
- }
-
- public function truncate(): void
- {
- apply(new DatabaseCleaner(), array_values($this->connections));
- }
-
- public function testConnections(): void
- {
- each($this->connectionTester(), $this->connections);
- }
-
- private function clearer(): callable
- {
- return function (EntityManager $entityManager) {
- $entityManager->clear();
- };
- }
-
- private function connectionTester(): callable
- {
- return function (EntityManager $entityManager) {
- $entityManager->getConnection()->connect();
- };
- }
+ private readonly array $connections;
+
+ public function __construct(iterable $connections)
+ {
+ $this->connections = Utils::iterableToArray($connections);
+ }
+
+ public function clear(): void
+ {
+ each(fn (EntityManager $entityManager) => $entityManager->clear(), $this->connections);
+ }
+
+ public function truncate(): void
+ {
+ apply(new MySqlDatabaseCleaner(), array_values($this->connections));
+ }
}
diff --git a/src/Shared/Infrastructure/Doctrine/Dbal/DbalCustomTypesRegistrar.php b/src/Shared/Infrastructure/Doctrine/Dbal/DbalCustomTypesRegistrar.php
new file mode 100644
index 000000000..e76a46c3b
--- /dev/null
+++ b/src/Shared/Infrastructure/Doctrine/Dbal/DbalCustomTypesRegistrar.php
@@ -0,0 +1,32 @@
+criteria = $criteria;
- $this->criteriaToDoctrineFields = $criteriaToDoctrineFields;
- $this->hydrators = $hydrators;
- }
-
- public static function convert(
- Criteria $criteria,
- array $criteriaToDoctrineFields = [],
- array $hydrators = []
- ): DoctrineCriteria {
- $converter = new self($criteria, $criteriaToDoctrineFields, $hydrators);
-
- return $converter->convertToDoctrineCriteria();
- }
-
- public static function convertToCount(
- Criteria $criteria,
- array $criteriaToDoctrineFields = [],
- array $hydrators = []
- ): DoctrineCriteria {
- $converter = new self($criteria, $criteriaToDoctrineFields, $hydrators);
-
- return $converter->convertToDoctrineCriteriaToCount();
- }
-
- private function convertToDoctrineCriteria(): DoctrineCriteria
- {
- return new DoctrineCriteria(
- $this->buildExpression($this->criteria),
- $this->formatOrder($this->criteria),
- $this->criteria->offset(),
- $this->criteria->limit()
- );
- }
-
- private function convertToDoctrineCriteriaToCount(): DoctrineCriteria
- {
- return new DoctrineCriteria($this->buildExpression($this->criteria), $this->formatOrder($this->criteria));
- }
-
- private function buildExpression(Criteria $criteria): ?CompositeExpression
- {
- if ($criteria->hasFilters()) {
- return new CompositeExpression(
- CompositeExpression::TYPE_AND,
- array_map($this->buildComparison(), $criteria->plainFilters())
- );
- }
-
- return null;
- }
-
- private function buildComparison(): callable
- {
- return function (Filter $filter): Comparison {
- $field = $this->mapFieldValue($filter->field());
- $value = $this->existsHydratorFor($field) ?
- $this->hydrate($field, $filter->value()->value()) :
- $filter->value()->value();
-
- return new Comparison($field, $filter->operator()->value(), $value);
- };
- }
-
- private function mapFieldValue(FilterField $field)
- {
- return array_key_exists($field->value(), $this->criteriaToDoctrineFields) ?
- $this->criteriaToDoctrineFields[$field->value()] :
- $field->value();
- }
-
- private function formatOrder(Criteria $criteria): ?array
- {
- if (!$criteria->hasOrder()) {
- return null;
- }
-
- return [$this->mapOrderBy($criteria->order()->orderBy()) => $criteria->order()->orderType()];
- }
-
- private function mapOrderBy(OrderBy $field)
- {
- return array_key_exists($field->value(), $this->criteriaToDoctrineFields) ?
- $this->criteriaToDoctrineFields[$field->value()] :
- $field->value();
- }
-
- private function existsHydratorFor($field): bool
- {
- return array_key_exists($field, $this->hydrators);
- }
-
- private function hydrate($field, $value)
- {
- return $this->hydrators[$field]($value);
- }
-}
diff --git a/src/Shared/Infrastructure/Doctrine/DoctrineEntityManagerFactory.php b/src/Shared/Infrastructure/Doctrine/DoctrineEntityManagerFactory.php
index c50e40efb..a19a5609e 100644
--- a/src/Shared/Infrastructure/Doctrine/DoctrineEntityManagerFactory.php
+++ b/src/Shared/Infrastructure/Doctrine/DoctrineEntityManagerFactory.php
@@ -1,75 +1,91 @@
'CodelyTv\Shared\Domain',
- ];
-
- public static function create(array $parameters, array $prefixes, $isDevMode, $schemaFile): EntityManagerInterface
- {
- if (true === $isDevMode) {
- static::generateDatabaseIfNotExists($parameters, $schemaFile);
- }
-
- DbalTypesRegistrar::register();
-
- return EntityManager::create($parameters, self::createConfiguration($prefixes, $isDevMode));
- }
-
- private static function generateDatabaseIfNotExists(array $parameters, $schemaFile): void
- {
- self::ensureSchemaFileExists($schemaFile);
-
- $databaseName = $parameters['dbname'];
- $parametersWithoutDatabaseName = dissoc($parameters, 'dbname');
- $connection = DriverManager::getConnection($parametersWithoutDatabaseName);
- $schemaManager = new MySqlSchemaManager($connection);
-
- if (!self::databaseExists($databaseName, $schemaManager)) {
- $schemaManager->createDatabase($databaseName);
- $connection->exec(sprintf('USE %s', $databaseName));
- $connection->exec(file_get_contents(realpath($schemaFile)));
- }
-
- $connection->close();
- }
-
- /** @fixme add ApcuCache config to configuration */
- private static function createConfiguration(array $prefixes, $isDevMode): Configuration
- {
- $config = Setup::createConfiguration($isDevMode, null, new ArrayCache());
-
- $config->setMetadataDriverImpl(new SimplifiedYamlDriver(array_merge(self::$sharedPrefixes, $prefixes)));
-
- return $config;
- }
-
- private static function databaseExists($databaseName, MySqlSchemaManager $schemaManager): bool
- {
- return in_array($databaseName, $schemaManager->listDatabases(), true);
- }
-
- private static function ensureSchemaFileExists(string $schemaFile): void
- {
- if (!file_exists($schemaFile)) {
- throw new RuntimeException(sprintf('The file <%s> does not exist', $schemaFile));
- }
- }
+ private static array $sharedPrefixes = [
+ __DIR__ . '/../../../Shared/Infrastructure/Persistence/Mappings' => 'CodelyTv\Shared\Domain',
+ ];
+
+ public static function create(
+ array $parameters,
+ array $contextPrefixes,
+ bool $isDevMode,
+ string $schemaFile,
+ array $dbalCustomTypesClasses
+ ): EntityManager {
+ if ($isDevMode) {
+ self::generateDatabaseIfNotExists($parameters, $schemaFile);
+ }
+
+ DbalCustomTypesRegistrar::register($dbalCustomTypesClasses);
+
+ $config = self::createConfiguration($contextPrefixes, $isDevMode);
+ $eventManager = new EventManager();
+
+ return new EntityManager(
+ DriverManager::getConnection($parameters, $config, $eventManager),
+ $config,
+ $eventManager
+ );
+ }
+
+ private static function generateDatabaseIfNotExists(array $parameters, string $schemaFile): void
+ {
+ self::ensureSchemaFileExists($schemaFile);
+
+ $databaseName = $parameters['dbname'];
+ $parametersWithoutDatabaseName = dissoc($parameters, 'dbname');
+ $connection = DriverManager::getConnection($parametersWithoutDatabaseName);
+ $platform = new MariaDBPlatform();
+ $schemaManager = new MySQLSchemaManager($connection, $platform);
+
+ if (!self::databaseExists($databaseName, $schemaManager)) {
+ $schemaManager->createDatabase($databaseName);
+
+ $connection->executeStatement(sprintf('USE %s', $databaseName));
+ $connection->executeStatement(file_get_contents(realpath($schemaFile)));
+ }
+
+ $connection->close();
+ }
+
+ private static function databaseExists(string $databaseName, MySQLSchemaManager $schemaManager): bool
+ {
+ return in_array($databaseName, $schemaManager->listDatabases(), true);
+ }
+
+ private static function ensureSchemaFileExists(string $schemaFile): void
+ {
+ if (!file_exists($schemaFile)) {
+ throw new RuntimeException(sprintf('The file <%s> does not exist', $schemaFile));
+ }
+ }
+
+ private static function createConfiguration(array $contextPrefixes, bool $isDevMode): Configuration
+ {
+ $config = ORMSetup::createConfiguration($isDevMode);
+
+ $config->setMetadataDriverImpl(new SimplifiedXmlDriver(array_merge(self::$sharedPrefixes, $contextPrefixes)));
+ $config->setSchemaManagerFactory(new DefaultSchemaManagerFactory());
+
+ return $config;
+ }
}
diff --git a/src/Shared/Infrastructure/Doctrine/DoctrineRepository.php b/src/Shared/Infrastructure/Doctrine/DoctrineRepository.php
deleted file mode 100644
index 863882abb..000000000
--- a/src/Shared/Infrastructure/Doctrine/DoctrineRepository.php
+++ /dev/null
@@ -1,61 +0,0 @@
-entityManager = $entityManager;
- }
-
- protected function entityManager(): EntityManager
- {
- return $this->entityManager;
- }
-
- protected function persist(AggregateRoot $entity): void
- {
- $this->entityManager()->persist($entity);
- $this->entityManager()->flush($entity);
- }
-
- protected function remove(AggregateRoot $entity): void
- {
- $this->entityManager()->remove($entity);
- $this->entityManager()->flush($entity);
- }
-
- protected function persister(): callable
- {
- return function (AggregateRoot $entity): void {
- $this->persist($entity);
- };
- }
-
- protected function remover(): callable
- {
- return function (AggregateRoot $entity): void {
- $this->remove($entity);
- };
- }
-
- protected function repository($entityClass): EntityRepository
- {
- return $this->entityManager->getRepository($entityClass);
- }
-
- protected function queryBuilder(): QueryBuilder
- {
- return $this->entityManager->createQueryBuilder();
- }
-}
diff --git a/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClient.php b/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClient.php
new file mode 100644
index 000000000..41480e009
--- /dev/null
+++ b/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClient.php
@@ -0,0 +1,33 @@
+client->index(
+ [
+ 'index' => sprintf('%s_%s', $this->indexPrefix, $aggregateName),
+ 'id' => $identifier,
+ 'body' => $plainBody,
+ ]
+ );
+ }
+
+ public function client(): Client
+ {
+ return $this->client;
+ }
+
+ public function indexPrefix(): string
+ {
+ return $this->indexPrefix;
+ }
+}
diff --git a/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClientFactory.php b/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClientFactory.php
new file mode 100644
index 000000000..a5472afb9
--- /dev/null
+++ b/src/Shared/Infrastructure/Elasticsearch/ElasticsearchClientFactory.php
@@ -0,0 +1,60 @@
+setHosts([$host])->build();
+
+ $this->generateIndexIfNotExists($client, $indexPrefix, $schemasFolder, $environment);
+
+ return new ElasticsearchClient($client, $indexPrefix);
+ }
+
+ private function generateIndexIfNotExists(
+ Client $client,
+ string $indexPrefix,
+ string $schemasFolder,
+ string $environment
+ ): void {
+ if ($environment !== 'prod') {
+ return;
+ }
+
+ $indexes = Utils::filesIn($schemasFolder, '.json');
+
+ foreach ($indexes as $index) {
+ $indexName = str_replace('.json', '', sprintf('%s_%s', $indexPrefix, $index));
+
+ if (!$this->indexExists($client, $indexName)) {
+ $indexBody = Utils::jsonDecode(file_get_contents("$schemasFolder/$index"));
+
+ $client->indices()->create(['index' => $indexName, 'body' => $indexBody]);
+ }
+ }
+ }
+
+ private function indexExists(Client $client, string $indexName): bool
+ {
+ try {
+ $client->indices()->getSettings(['index' => $indexName]);
+
+ return true;
+ } catch (Missing404Exception) {
+ return false;
+ }
+ }
+}
diff --git a/src/Shared/Infrastructure/Jms/CodelyTvSerializerDriver.php b/src/Shared/Infrastructure/Jms/CodelyTvSerializerDriver.php
deleted file mode 100644
index 6a0137d39..000000000
--- a/src/Shared/Infrastructure/Jms/CodelyTvSerializerDriver.php
+++ /dev/null
@@ -1,85 +0,0 @@
-getBaseMetadata(), $this->getMetadata());
- }
-
- public function getBaseMetadata(): array
- {
- return $this->baseMetadata;
- }
-
- public function loadMetadataForClass(ReflectionClass $refClass)
- {
- $metadata = $this->getClassConfiguration($refClass);
-
- return $this->createMetadata($refClass->getName(), $metadata);
- }
-
- protected function addResourceFile($file): void
- {
- $this->fileResources[] = $file;
- }
-
- private function getClassConfiguration(ReflectionClass $refClass)
- {
- $metadata = $this->getDriverMetadata();
-
- if (!isset($metadata[$refClass->getName()])) {
- throw new InvalidArgumentException(
- sprintf('The serializer configuration for the class "%s" does not exist.', $refClass->getName())
- );
- }
-
- return $metadata[$refClass->getName()];
- }
-
- private function createMetadata($className, array $config): ClassMetadata
- {
- $metadata = new ClassMetadata($className);
-
- $this->addThisFileAsMetadataResourceToBeInvalidatedOnChanges($metadata);
- $this->addPropertiesToMetadata($config, $metadata);
-
- return $metadata;
- }
-
- private function addThisFileAsMetadataResourceToBeInvalidatedOnChanges(ClassMetadata $metadata): void
- {
- $metadata->fileResources = array_merge($metadata->fileResources, $this->fileResources);
- }
-
- private function addPropertiesToMetadata(array $config, ClassMetadata $metadata): void
- {
- foreach ($config as $propertyName => $propertyAttributes) {
- $propertyMetadata = new PropertyMetadata($metadata->name, $propertyName);
- $metadata->addPropertyMetadata($propertyMetadata);
-
- foreach ($propertyAttributes as $attribute => $value) {
- if ('type' === $attribute) {
- $propertyMetadata->setType($value);
- } else {
- $propertyMetadata->$attribute = $value;
- }
- }
- }
- }
-}
diff --git a/src/Shared/Infrastructure/Logger/MonologLogger.php b/src/Shared/Infrastructure/Logger/MonologLogger.php
new file mode 100644
index 000000000..1e0928028
--- /dev/null
+++ b/src/Shared/Infrastructure/Logger/MonologLogger.php
@@ -0,0 +1,27 @@
+logger->info($message, $context);
+ }
+
+ public function warning(string $message, array $context = []): void
+ {
+ $this->logger->warning($message, $context);
+ }
+
+ public function critical(string $message, array $context = []): void
+ {
+ $this->logger->critical($message, $context);
+ }
+}
diff --git a/src/Shared/Infrastructure/Monitoring/PrometheusMonitor.php b/src/Shared/Infrastructure/Monitoring/PrometheusMonitor.php
new file mode 100644
index 000000000..162c0482e
--- /dev/null
+++ b/src/Shared/Infrastructure/Monitoring/PrometheusMonitor.php
@@ -0,0 +1,23 @@
+registry = new CollectorRegistry(new APC());
+ }
+
+ public function registry(): CollectorRegistry
+ {
+ return $this->registry;
+ }
+}
diff --git a/src/Shared/Infrastructure/Monolog/Formatter/LogstashFormatter.php b/src/Shared/Infrastructure/Monolog/Formatter/LogstashFormatter.php
deleted file mode 100644
index 9b99dc805..000000000
--- a/src/Shared/Infrastructure/Monolog/Formatter/LogstashFormatter.php
+++ /dev/null
@@ -1,64 +0,0 @@
-formatLogstash(parent::format($record));
-
- return $this->toJson($message) . PHP_EOL;
- }
-
- private function formatLogstash(array $record): array
- {
- $message = [
- '@timestamp' => $record['datetime'],
- '@version' => 1,
- 'host' => gethostname(),
- 'tags' => ['codelytv', $record['channel']],
- 'message' => $record['message'],
- 'severity' => $record['level_name'],
- ];
-
- if (!empty($record['extra'])) {
- foreach ($record['extra'] as $key => $val) {
- $message[$key] = $val;
- }
- }
-
- if (!empty($record['context'])) {
- foreach ($record['context'] as $key => $val) {
- $message[$key] = $val;
- }
- }
-
- $message['type'] = md5(implode('', array_keys($message)));
-
- return $message;
- }
-
- /** @param Exception $exception */
- protected function normalizeException($exception): array
- {
- return [
- 'class' => get_class($exception),
- 'file' => $exception->getFile(),
- 'line' => $exception->getLine(),
- 'code' => method_exists($exception, 'errorCode') ? $exception->errorCode() : $exception->getCode(),
- 'trace' => $exception->getTraceAsString(),
- 'message' => $exception->getMessage(),
- ];
- }
-}
diff --git a/src/Shared/Infrastructure/Monolog/Processor/CodelyTvRequestProcessor.php b/src/Shared/Infrastructure/Monolog/Processor/CodelyTvRequestProcessor.php
deleted file mode 100644
index 9dfb9d831..000000000
--- a/src/Shared/Infrastructure/Monolog/Processor/CodelyTvRequestProcessor.php
+++ /dev/null
@@ -1,73 +0,0 @@
-requestStack = $requestStack;
- }
-
- public function __invoke(array $record)
- {
- $request = $this->requestStack->getMasterRequest();
-
- return $request ? $this->addRequestInfo($record, $request) : $record;
- }
-
- private function addRequestInfo(array $record, Request $request): array
- {
- $record['extra']['request']['method'] = $request->getMethod();
- $record['extra']['request']['url'] = $request->getUri();
- $record['extra']['request']['ip'] = $request->getClientIp();
- $record['extra']['request']['content'] = $this->hashToString($request->request->all());
- $record['extra']['request']['attributes'] = $this->hashToString($request->attributes->all());
- $record['extra']['request']['headers'] = $this->hashToString(array_filter($request->headers->all()));
-
- return $record;
- }
-
- private function hashToString(array $hash, $format = '%s: %s'): string
- {
- $elements = [];
-
- foreach ($hash as $key => $values) {
- $elements[] = $this->elementAsString($format, $key, $values);
- }
-
- return implode(', ', $elements);
- }
-
- private function elementAsString($format, $key, $values): string
- {
- return sprintf($format, $key, is_array($values) ? $this->arrayElementAsString($values) : $values);
- }
-
- private function arrayElementAsString(array $values)
- {
- return $this->containsAnArray($values) ?
- sprintf('[%s]', $this->hashToString($values, '#%s: %s')) :
- implode(', ', $values);
- }
-
- private function containsAnArray(array $values): bool
- {
- return any($this->isArray(), $values);
- }
-
- private function isArray(): callable
- {
- return function ($value): bool {
- return is_array($value);
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Persistence/Course/CourseIdType.php b/src/Shared/Infrastructure/Persistence/Course/CourseIdType.php
deleted file mode 100644
index c83b741be..000000000
--- a/src/Shared/Infrastructure/Persistence/Course/CourseIdType.php
+++ /dev/null
@@ -1,31 +0,0 @@
-value();
- }
-}
-
diff --git a/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineCriteriaConverter.php b/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineCriteriaConverter.php
new file mode 100644
index 000000000..88bd57083
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineCriteriaConverter.php
@@ -0,0 +1,99 @@
+convertToDoctrineCriteria();
+ }
+
+ private function convertToDoctrineCriteria(): DoctrineCriteria
+ {
+ return new DoctrineCriteria(
+ $this->buildExpression($this->criteria),
+ $this->formatOrder($this->criteria),
+ $this->criteria->offset(),
+ $this->criteria->limit()
+ );
+ }
+
+ private function buildExpression(Criteria $criteria): ?CompositeExpression
+ {
+ if ($criteria->hasFilters()) {
+ return new CompositeExpression(
+ CompositeExpression::TYPE_AND,
+ array_map($this->buildComparison(), $criteria->plainFilters())
+ );
+ }
+
+ return null;
+ }
+
+ private function buildComparison(): callable
+ {
+ return function (Filter $filter): Comparison {
+ $field = $this->mapFieldValue($filter->field());
+ $value = $this->existsHydratorFor($field)
+ ? $this->hydrate($field, $filter->value()->value())
+ : $filter->value()->value();
+
+ return new Comparison($field, $filter->operator()->value, $value);
+ };
+ }
+
+ private function mapFieldValue(FilterField $field): mixed
+ {
+ return array_key_exists($field->value(), $this->criteriaToDoctrineFields)
+ ? $this->criteriaToDoctrineFields[$field->value()]
+ : $field->value();
+ }
+
+ private function formatOrder(Criteria $criteria): ?array
+ {
+ if (!$criteria->hasOrder()) {
+ return null;
+ }
+
+ return [$this->mapOrderBy($criteria->order()->orderBy()) => $criteria->order()->orderType()];
+ }
+
+ private function mapOrderBy(OrderBy $field): mixed
+ {
+ return array_key_exists($field->value(), $this->criteriaToDoctrineFields)
+ ? $this->criteriaToDoctrineFields[$field->value()]
+ : $field->value();
+ }
+
+ private function existsHydratorFor(mixed $field): bool
+ {
+ return array_key_exists($field, $this->hydrators);
+ }
+
+ private function hydrate(mixed $field, string $value): mixed
+ {
+ return $this->hydrators[$field]($value);
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineRepository.php b/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineRepository.php
new file mode 100644
index 000000000..dc6cdd9bb
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Doctrine/DoctrineRepository.php
@@ -0,0 +1,46 @@
+entityManager;
+ }
+
+ protected function persist(AggregateRoot $entity): void
+ {
+ $this->entityManager()->persist($entity);
+ $this->entityManager()->flush($entity);
+ }
+
+ protected function remove(AggregateRoot $entity): void
+ {
+ $this->entityManager()->remove($entity);
+ $this->entityManager()->flush($entity);
+ }
+
+ /**
+ * @template T of object
+ *
+ * @psalm-param class-string $entityClass
+ *
+ * @psalm-return EntityRepository
+ *
+ * @throws NotSupported
+ */
+ protected function repository(string $entityClass): EntityRepository
+ {
+ return $this->entityManager->getRepository($entityClass);
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Doctrine/UuidType.php b/src/Shared/Infrastructure/Persistence/Doctrine/UuidType.php
new file mode 100644
index 000000000..1ef8213bc
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Doctrine/UuidType.php
@@ -0,0 +1,41 @@
+typeClassName();
+
+ return new $className($value);
+ }
+
+ final public function convertToDatabaseValue($value, AbstractPlatform $platform): string
+ {
+ /** @var Uuid $value */
+ return $value->value();
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticQueryGenerator.php b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticQueryGenerator.php
new file mode 100644
index 000000000..885066f5e
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticQueryGenerator.php
@@ -0,0 +1,52 @@
+typeFor($filter->operator());
+ $termLevel = $this->termLevelFor($filter->operator());
+ $valueTemplate = $filter->operator()->isContaining() ? '*%s*' : '%s';
+
+ return array_merge_recursive(
+ $query,
+ [
+ $type => [
+ $termLevel => [
+ $filter->field()->value() => sprintf($valueTemplate, strtolower($filter->value()->value())),
+ ],
+ ],
+ ]
+ );
+ }
+
+ private function typeFor(FilterOperator $operator): string
+ {
+ return in_array($operator->value, self::$mustNotFields, true) ? self::MUST_NOT_TYPE : self::MUST_TYPE;
+ }
+
+ private function termLevelFor(FilterOperator $operator): string
+ {
+ return match ($operator) {
+ FilterOperator::EQUAL => self::TERM_TERM,
+ FilterOperator::NOT_EQUAL => '!=',
+ FilterOperator::GT, FilterOperator::LT => self::TERM_RANGE,
+ FilterOperator::CONTAINS, FilterOperator::NOT_CONTAINS => self::TERM_WILDCARD,
+ };
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchCriteriaConverter.php b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchCriteriaConverter.php
new file mode 100644
index 000000000..257e531b3
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchCriteriaConverter.php
@@ -0,0 +1,53 @@
+ array_merge(
+ ['from' => $criteria->offset() ?: 0, 'size' => $criteria->limit() ?: 1000],
+ $this->formatQuery($criteria),
+ $this->formatSort($criteria)
+ ),
+ ];
+ }
+
+ private function formatQuery(Criteria $criteria): array
+ {
+ if ($criteria->hasFilters()) {
+ return [
+ 'query' => [
+ 'bool' => reduce(new ElasticQueryGenerator(), $criteria->filters(), []),
+ ],
+ ];
+ }
+
+ return [];
+ }
+
+ private function formatSort(Criteria $criteria): array
+ {
+ if ($criteria->hasOrder()) {
+ $order = $criteria->order();
+
+ return [
+ 'sort' => [
+ $order->orderBy()->value() => [
+ 'order' => $order->orderType()->value,
+ ],
+ ],
+ ];
+ }
+
+ return [];
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchRepository.php b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchRepository.php
new file mode 100644
index 000000000..3236dd248
--- /dev/null
+++ b/src/Shared/Infrastructure/Persistence/Elasticsearch/ElasticsearchRepository.php
@@ -0,0 +1,61 @@
+convert($criteria);
+
+ return $this->searchRawElasticsearchQuery($query);
+ }
+
+ protected function persist(string $id, array $plainBody): void
+ {
+ $this->client->persist($this->aggregateName(), $id, $plainBody);
+ }
+
+ protected function searchAllInElastic(): array
+ {
+ return $this->searchRawElasticsearchQuery([]);
+ }
+
+ protected function searchRawElasticsearchQuery(array $params): array
+ {
+ try {
+ $result = $this->client->client()->search(array_merge(['index' => $this->indexName()], $params));
+
+ $hits = (array) get_in(['hits', 'hits'], $result, []);
+
+ return map($this->elasticValuesExtractor(), $hits);
+ } catch (Missing404Exception) {
+ return [];
+ }
+ }
+
+ protected function indexName(): string
+ {
+ return sprintf('%s_%s', $this->client->indexPrefix(), $this->aggregateName());
+ }
+
+ private function elasticValuesExtractor(): callable
+ {
+ return static fn (array $elasticValues): array => $elasticValues['_source'];
+ }
+}
diff --git a/src/Shared/Infrastructure/Persistence/Lesson/LessonIdType.php b/src/Shared/Infrastructure/Persistence/Lesson/LessonIdType.php
deleted file mode 100644
index ca6b746f2..000000000
--- a/src/Shared/Infrastructure/Persistence/Lesson/LessonIdType.php
+++ /dev/null
@@ -1,30 +0,0 @@
-value();
- }
-}
diff --git a/src/Shared/Infrastructure/PhpRandomNumberGenerator.php b/src/Shared/Infrastructure/PhpRandomNumberGenerator.php
new file mode 100644
index 000000000..b32a8be34
--- /dev/null
+++ b/src/Shared/Infrastructure/PhpRandomNumberGenerator.php
@@ -0,0 +1,15 @@
+configuration = $configuration;
- }
-
- public function queue(string $name): AMQPQueue
- {
- if (!array_key_exists($name, self::$queues)) {
- $queue = new AMQPQueue($this->channel());
- $queue->setName($name);
-
- self::$queues[$name] = $queue;
- }
-
- return self::$queues[$name];
- }
-
- public function queueBinder(AMQPQueue $queue): callable
- {
- return function (string $exchange, string $routingKey) use ($queue) {
- $queue->bind($exchange, $routingKey);
- };
- }
-
- private function channel(): AMQPChannel
- {
- return self::$channel =
- self::$channel && self::$channel->isConnected() ? self::$channel : new AMQPChannel($this->connection());
- }
-
- private function connection(): AMQPConnection
- {
- self::$connection = self::$connection ?: new AMQPConnection($this->configuration);
- self::$connection->isConnected() ?: self::$connection->pconnect();
-
- return self::$connection;
- }
-}
diff --git a/src/Shared/Infrastructure/RabbitMQ/RabbitMQConsumer.php b/src/Shared/Infrastructure/RabbitMQ/RabbitMQConsumer.php
deleted file mode 100644
index c7588b4a9..000000000
--- a/src/Shared/Infrastructure/RabbitMQ/RabbitMQConsumer.php
+++ /dev/null
@@ -1,107 +0,0 @@
-logger = $logger;
- $this->consumer = pipe(new DomainEventUnserializer($eventMapping), $consumer);
- }
-
- public function __invoke(AMQPEnvelope $envelope, AMQPQueue $queue)
- {
- $queueName = $queue->getName();
-
- try {
- apply($this->consumer, [$envelope->getBody()]);
-
- $this->log('Message consumed', $envelope, $queueName, LogLevel::DEBUG);
- } catch (Exception $exception) {
- $level = $this->hasBeenRedeliveredTooMuch($envelope) ? LogLevel::ERROR : LogLevel::DEBUG;
- $this->log('Message consumption failed', $envelope, $queueName, $level, $exception);
- // $this->requeue($envelope, $queue, $exception);
- }
-
- $this->ack($envelope, $queue);
- }
-
- private function ack(AMQPEnvelope $envelope, AMQPQueue $queue): void
- {
- try {
- $ack = $queue->ack($envelope->getDeliveryTag());
-
- if (false === $ack) {
- $this->log('Message has not been acknowledged', $envelope, $queue->getName());
- }
- } catch (Exception $exception) {
- $this->log('Message has not been acknowledged', $envelope, $queue->getName(), LogLevel::ERROR, $exception);
- }
- }
-
- private function hasBeenRedeliveredTooMuch(AMQPEnvelope $envelope): bool
- {
- return get('redelivery_count', $envelope->getHeaders(), 0) > 500;
- }
-
- private function log(
- string $message,
- AMQPEnvelope $envelope,
- string $queueName,
- string $level = LogLevel::ERROR,
- Exception $exception = null
- ): void {
- $this->logger->log(
- $level,
- $message,
- [
- 'envelope' => [
- 'app_id' => $envelope->getAppId(),
- 'body' => $envelope->getBody(),
- 'content_encoding' => $envelope->getContentEncoding(),
- 'content_type' => $envelope->getContentType(),
- 'correlation_id' => $envelope->getCorrelationId(),
- 'delivery_mode' => $envelope->getDeliveryMode(),
- 'delivery_tag' => $envelope->getDeliveryTag(),
- 'exchange_name' => $envelope->getExchangeName(),
- 'expiration' => $envelope->getExpiration(),
- 'headers' => $envelope->getHeaders(),
- 'message_id' => $envelope->getMessageId(),
- 'priority' => $envelope->getPriority(),
- 'reply_to' => $envelope->getReplyTo(),
- 'routing_key' => $envelope->getRoutingKey(),
- 'timestamp' => $envelope->getTimestamp(),
- 'type' => $envelope->getType(),
- 'user_id' => $envelope->getUserId(),
- 'is_redelivery' => $envelope->isRedelivery(),
- ],
- 'queue' => $queueName,
- 'exception' => $exception ?
- [
- 'error' => $exception->getMessage(),
- 'file' => $exception->getFile(),
- 'line' => $exception->getLine(),
- 'trace' => $exception->getTraceAsString(),
- ] :
- null,
- ]
- );
- }
-}
diff --git a/src/Shared/Infrastructure/RabbitMQ/RabbitMQDomainEventConsumeConnectionFailed.php b/src/Shared/Infrastructure/RabbitMQ/RabbitMQDomainEventConsumeConnectionFailed.php
deleted file mode 100644
index 5bed5e92c..000000000
--- a/src/Shared/Infrastructure/RabbitMQ/RabbitMQDomainEventConsumeConnectionFailed.php
+++ /dev/null
@@ -1,16 +0,0 @@
-connection = $connection;
- $this->mapping = $mapping;
- $this->logger = $logger;
- }
-
- public function __invoke(callable $subscriber, string $name)
- {
- $queueName = RabbitMQQueueNameFormatter::format($name);
- $queue = $this->queue($queueName);
-
- $queue->consume(
- new RabbitMQConsumer($subscriber, $this->mapping, $this->logger)
- );
- }
-
- private function queue(string $queueName): ?AMQPQueue
- {
- try {
- return $this->connection->queue($queueName);
- } catch (Exception $exception) {
- $this->logger->error(
- 'Domain Event consumption failed at opening a channel',
- ['queue' => $queueName, 'exception' => $exception]
- );
-
- throw new RabbitMQDomainEventConsumeConnectionFailed(
- 'Domain Event consumption failed at opening a channel',
- $exception
- );
- }
- }
-}
diff --git a/src/Shared/Infrastructure/RabbitMQ/RabbitMQQueueNameFormatter.php b/src/Shared/Infrastructure/RabbitMQ/RabbitMQQueueNameFormatter.php
deleted file mode 100644
index d3d9ae6cc..000000000
--- a/src/Shared/Infrastructure/RabbitMQ/RabbitMQQueueNameFormatter.php
+++ /dev/null
@@ -1,15 +0,0 @@
-toString();
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/AddJsonBodyToRequestListener.php b/src/Shared/Infrastructure/Symfony/AddJsonBodyToRequestListener.php
new file mode 100644
index 000000000..0930af5ee
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/AddJsonBodyToRequestListener.php
@@ -0,0 +1,40 @@
+getRequest();
+ $requestContents = $request->getContent();
+
+ if (!empty($requestContents) && $this->containsHeader($request, 'Content-Type', 'application/json')) {
+ $jsonData = json_decode($requestContents, true, 512, JSON_THROW_ON_ERROR);
+ if (!$jsonData) {
+ throw new HttpException(Response::HTTP_BAD_REQUEST, 'Invalid json data');
+ }
+ $jsonDataLowerCase = [];
+ foreach ($jsonData as $key => $value) {
+ $jsonDataLowerCase[preg_replace_callback(
+ '/_(.)/',
+ static fn ($matches): string => strtoupper((string) $matches[1]),
+ (string) $key
+ )] = $value;
+ }
+ $request->request->replace($jsonDataLowerCase);
+ }
+ }
+
+ private function containsHeader(Request $request, string $name, string $value): bool
+ {
+ return str_starts_with((string) $request->headers->get($name), $value);
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/ApiController.php b/src/Shared/Infrastructure/Symfony/ApiController.php
new file mode 100644
index 000000000..09dd9be51
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/ApiController.php
@@ -0,0 +1,39 @@
+ $exceptionHandler->register($exceptionClass, $httpCode),
+ $this->exceptions()
+ );
+ }
+
+ abstract protected function exceptions(): array;
+
+ protected function ask(Query $query): ?Response
+ {
+ return $this->queryBus->ask($query);
+ }
+
+ protected function dispatch(Command $command): void
+ {
+ $this->commandBus->dispatch($command);
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/ApiExceptionListener.php b/src/Shared/Infrastructure/Symfony/ApiExceptionListener.php
new file mode 100644
index 000000000..d913d8766
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/ApiExceptionListener.php
@@ -0,0 +1,48 @@
+getThrowable();
+
+ $event->setResponse(
+ new JsonResponse(
+ [
+ 'code' => $this->exceptionCodeFor($exception),
+ 'message' => $exception->getMessage(),
+ ],
+ $this->exceptionHandler->statusCodeFor($exception::class)
+ )
+ );
+ }
+
+ private function exceptionCodeFor(Throwable $error): string
+ {
+ $domainErrorClass = DomainError::class;
+
+ return $error instanceof $domainErrorClass
+ ? $error->errorCode()
+ : Utils::toSnakeCase($this->extractClassName($error));
+ }
+
+ private function extractClassName(object $object): string
+ {
+ $reflect = new ReflectionClass($object);
+
+ return $reflect->getShortName();
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/ApiExceptionsHttpStatusCodeMapping.php b/src/Shared/Infrastructure/Symfony/ApiExceptionsHttpStatusCodeMapping.php
new file mode 100644
index 000000000..8b1ad8a11
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/ApiExceptionsHttpStatusCodeMapping.php
@@ -0,0 +1,36 @@
+ Response::HTTP_BAD_REQUEST,
+ NotFoundHttpException::class => Response::HTTP_NOT_FOUND,
+ ];
+
+ public function register(string $exceptionClass, int $statusCode): void
+ {
+ $this->exceptions[$exceptionClass] = $statusCode;
+ }
+
+ public function statusCodeFor(string $exceptionClass): int
+ {
+ $statusCode = get($exceptionClass, $this->exceptions, self::DEFAULT_STATUS_CODE);
+
+ if ($statusCode === null) {
+ throw new InvalidArgumentException("There are no status code mapping for <$exceptionClass>");
+ }
+
+ return $statusCode;
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/BasicHttpAuthMiddleware.php b/src/Shared/Infrastructure/Symfony/BasicHttpAuthMiddleware.php
new file mode 100644
index 000000000..0f3ad3aa8
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/BasicHttpAuthMiddleware.php
@@ -0,0 +1,62 @@
+getRequest()->attributes->get('auth', false);
+
+ if ($shouldAuthenticate) {
+ $user = $event->getRequest()->headers->get('php-auth-user');
+ $pass = $event->getRequest()->headers->get('php-auth-pw');
+
+ $this->hasIntroducedCredentials($user)
+ ? $this->authenticate($user, $pass, $event)
+ : $this->askForCredentials($event);
+ }
+ }
+
+ private function hasIntroducedCredentials(?string $user): bool
+ {
+ return $user !== null;
+ }
+
+ private function authenticate(string $user, string $pass, RequestEvent $event): void
+ {
+ try {
+ $this->bus->dispatch(new AuthenticateUserCommand($user, $pass));
+
+ $this->addUserDataToRequest($user, $event);
+ } catch (InvalidAuthCredentials | InvalidAuthUsername) {
+ $event->setResponse(new JsonResponse(['error' => 'Invalid credentials'], Response::HTTP_FORBIDDEN));
+ }
+ }
+
+ private function addUserDataToRequest(string $user, RequestEvent $event): void
+ {
+ $event->getRequest()->attributes->set('authenticated_username', $user);
+ }
+
+ private function askForCredentials(RequestEvent $event): void
+ {
+ $event->setResponse(
+ new Response('', Response::HTTP_UNAUTHORIZED, [
+ 'WWW-Authenticate' => 'Basic realm="CodelyTV"',
+ ])
+ );
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/CodelyTvInfrastructureBundle.php b/src/Shared/Infrastructure/Symfony/Bundle/CodelyTvInfrastructureBundle.php
deleted file mode 100644
index 58fdf18fb..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/CodelyTvInfrastructureBundle.php
+++ /dev/null
@@ -1,11 +0,0 @@
-load('infrastructure_extension.yml');
- $loader->load(sprintf('infrastructure_config_%s.yml', $container->getParameter('kernel.environment')));
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/CallableFirstParameterExtractor.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/CallableFirstParameterExtractor.php
deleted file mode 100644
index 1ec90e59d..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/CallableFirstParameterExtractor.php
+++ /dev/null
@@ -1,74 +0,0 @@
-getMethod('__invoke');
-
- if ($this->hasOnlyOneParameter($method)) {
- return $this->firstParameterClassFrom($method);
- }
-
- return null;
- }
-
- public static function forCallables(iterable $callables): array
- {
- return map(self::unflatten(), reindex(self::classExtractor(new self()), $callables));
- }
-
- public static function forPipedCallables(iterable $callables): array
- {
- return reduce(self::pipedCallablesReducer(), $callables);
- }
-
- private function firstParameterClassFrom(ReflectionMethod $method): string
- {
- return $method->getParameters()[0]->getClass()->getName();
- }
-
- private function hasOnlyOneParameter(ReflectionMethod $method): bool
- {
- return $method->getNumberOfParameters() === 1;
- }
-
- private static function classExtractor(CallableFirstParameterExtractor $parameterExtractor): callable
- {
- return function (callable $handler) use ($parameterExtractor): string {
- return $parameterExtractor->extract($handler);
- };
- }
-
- private static function pipedCallablesReducer(): callable
- {
- return function ($subscribers, DomainEventSubscriber $subscriber): array {
- $subscribedEvents = $subscriber::subscribedTo();
-
- foreach ($subscribedEvents as $subscribedEvent) {
- $subscribers[$subscribedEvent][] = $subscriber;
- }
-
- return $subscribers;
- };
- }
-
- private static function unflatten(): callable
- {
- return function ($value) {
- return [$value];
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DatabasesConnectionCompilerPass.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DatabasesConnectionCompilerPass.php
deleted file mode 100644
index 4d8c710ee..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DatabasesConnectionCompilerPass.php
+++ /dev/null
@@ -1,41 +0,0 @@
-tag = $tag;
- }
-
- public function process(ContainerBuilder $container): void
- {
- $databasesConnectionsService = $container->findDefinition(self::DATABASE_CONNECTIONS_SERVICE);
- $databasesConnectionsIds = $container->findTaggedServiceIds($this->tag);
-
- each($this->addDatabasesConnections($databasesConnectionsService), $databasesConnectionsIds);
- }
-
- private function addDatabasesConnections(Definition $connectionsService): callable
- {
- return function (array $unused, string $databaseConnectionServiceId) use ($connectionsService): void {
- $connectionsService->addMethodCall(
- 'set',
- [$databaseConnectionServiceId, new Reference($databaseConnectionServiceId)]
- );
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DomainEventSubscribersConfigurationCompilerPass.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DomainEventSubscribersConfigurationCompilerPass.php
deleted file mode 100644
index 9a886e8d1..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/DomainEventSubscribersConfigurationCompilerPass.php
+++ /dev/null
@@ -1,84 +0,0 @@
-tag = $tag;
- }
-
- public function process(ContainerBuilder $container): void
- {
- $domainEventConfiguration = $container->findDefinition(self::DOMAIN_EVENT_CONFIGURATION_SERVICE);
- $subscribersMapping = $container->findDefinition(self::SUBSCRIBERS_MAPPING_SERVICE);
- $subscribersIds = $container->findTaggedServiceIds($this->tag);
-
- each(
- $this->addSubscriberConfiguration($domainEventConfiguration, $subscribersMapping, $container),
- $subscribersIds
- );
- }
-
- private function addSubscriberConfiguration(
- Definition $domainEventConfiguration,
- Definition $subscribersMapping,
- ContainerBuilder $container
- ): callable {
- return function (
- array $attributes,
- string $subscriberServiceId
- ) use (
- $domainEventConfiguration,
- $subscribersMapping,
- $container
- ): void {
- $subscriber = $container->findDefinition($subscriberServiceId);
-
- $subscriberName = $this->extractSubscriberName($subscriberServiceId);
- $subscriberClass = $subscriber->getClass();
- $events = $subscriberClass::subscribedTo();
-
- $config = array_merge(
- get(0, $attributes, []),
- [
- 'name' => $subscriberName,
- 'subscribed_events' => map($this->eventNameExtractor(), $events),
- ]
- );
-
- $domainEventConfiguration->addMethodCall('set', [$subscriberClass, $config]);
- $subscribersMapping->addMethodCall('add', [$subscriberName, new Reference($subscriberServiceId)]);
- };
- }
-
- private function extractSubscriberName(string $subscriberServiceId)
- {
- return last(explode('.', $subscriberServiceId));
- }
-
- private function eventNameExtractor(): callable
- {
- return function (string $eventClass) {
- return $eventClass::eventName();
- };
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceByTagNotDefined.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceByTagNotDefined.php
deleted file mode 100644
index fe046c83f..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceByTagNotDefined.php
+++ /dev/null
@@ -1,15 +0,0 @@
- transactional definition', $service));
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceCompilerPass.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceCompilerPass.php
deleted file mode 100644
index 9294145c4..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalServiceCompilerPass.php
+++ /dev/null
@@ -1,50 +0,0 @@
-domainEventPublisherTag = $domainEventPublisherTag;
- }
-
- public function process(ContainerBuilder $container): void
- {
- $servicesToBeTransactional = $container->findTaggedServiceIds(self::TRANSACTIONAL_TAG);
-
- each($this->serviceDecorator($container), $servicesToBeTransactional);
- }
-
- private function serviceDecorator(ContainerBuilder $container): callable
- {
- return function (array $tags, string $serviceToBeTransactional) use ($container): void {
- $this->ensureByTagExists($tags, $serviceToBeTransactional);
-
- $container->register($serviceToBeTransactional . '.transactional', TransactionalWrapper::class)
- ->addArgument(new Reference($tags[0][self::BY_TAG]))
- ->addArgument(new Reference($this->domainEventPublisherTag))
- ->addArgument(new Reference($serviceToBeTransactional . '.transactional.inner'))
- ->setDecoratedService($serviceToBeTransactional)
- ->setPublic(false);
- };
- }
-
- private function ensureByTagExists(array $tags, string $serviceToBeTransactional): void
- {
- if (!array_key_exists(self::BY_TAG, $tags[0])) {
- throw new TransactionalServiceByTagNotDefined($serviceToBeTransactional);
- }
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalWrapper.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalWrapper.php
deleted file mode 100644
index 799629800..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/TransactionalWrapper.php
+++ /dev/null
@@ -1,51 +0,0 @@
-entityManager = $entityManager;
- $this->publisher = $publisher;
- $this->service = $service;
- }
-
- public function __invoke(...$args): ?Response
- {
- $result = null;
-
- $this->entityManager->beginTransaction();
-
- try {
- $result = apply($this->service, $args);
-
- $this->entityManager->flush();
- $this->entityManager->commit();
- } catch (Exception $exception) {
- $this->entityManager->close();
- $this->entityManager->rollback();
-
- throw new WrongTransaction($exception);
- }
-
- $this->publisher->publishRecorded();
-
- return $result;
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/WrongTransaction.php b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/WrongTransaction.php
deleted file mode 100644
index c52d986a8..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Compiler/WrongTransaction.php
+++ /dev/null
@@ -1,25 +0,0 @@
-originalException = $originalException;
-
- parent::__construct(sprintf('Transaction ended with <%s> exception', get_class($originalException)));
- }
-
- public function originalException(): Exception
- {
- return $this->originalException;
- }
-}
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config.yml
deleted file mode 100644
index 313460a33..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-parameters:
-
- rabbitmq_connection_parameters:
- host: '%rabbitmq_host%'
- port: '%rabbitmq_port%'
- vhost: '%rabbitmq_vhost%'
- login: '%rabbitmq_login%'
- password: '%rabbitmq_password%'
- read_timeout: 60
- write_timeout: 5
- connect_timeout: 1
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_dev.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_dev.yml
deleted file mode 100644
index 923fcf0bf..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_dev.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-imports:
- - { resource: infrastructure_config.yml }
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_prod.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_prod.yml
deleted file mode 100644
index b1931557f..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_prod.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-imports:
- - { resource: infrastructure_config.yml }
-
-services:
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_test.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_test.yml
deleted file mode 100644
index adfc15dc1..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_config_test.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-imports:
- - { resource: infrastructure_config_dev.yml }
-
-parameters:
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_extension.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_extension.yml
deleted file mode 100644
index 922da643a..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_extension.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-imports:
- - { resource: infrastructure_parameters.yml }
- - { resource: infrastructure_services.yml }
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_parameters.yml.dist b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_parameters.yml.dist
deleted file mode 100644
index 7c5a935f0..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_parameters.yml.dist
+++ /dev/null
@@ -1,9 +0,0 @@
-parameters:
- best_youtube_channel_ever: 'CodelyTv'
- async_command_bus_pending_requests_file_path: '/path/to/the/codelytv_pending_requests.dat'
-
- rabbitmq_host: 'localhost'
- rabbitmq_port: 5672
- rabbitmq_vhost: '/'
- rabbitmq_login: 'codelytv'
- rabbitmq_password: 'c0d3ly'
diff --git a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_services.yml b/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_services.yml
deleted file mode 100644
index 9764ef7cf..000000000
--- a/src/Shared/Infrastructure/Symfony/Bundle/DependencyInjection/Resources/infrastructure_services.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-services:
- _defaults:
- autoconfigure: true
- autowire: true
-
- CodelyTv\Shared\:
- resource: '../../../../../*'
- exclude:
- - '../../../../../utils.php'
- - '../../../../../Infrastructure/Api/*'
-
- CodelyTv\Shared\Infrastructure\Bus\Event\DomainEventMapping:
- arguments: [!tagged codely.mooc.subscriber]
-
- CodelyTv\Shared\Infrastructure\RabbitMQ\RabbitMQConnection:
- arguments:
- - '%rabbitmq_connection_parameters%'
-
- codely.infrastructure.async_command_bus:
- class: CodelyTv\Shared\Infrastructure\Bus\Command\CommandBusAsync
- arguments:
- $pendingRequestsFilePath: '%async_command_bus_pending_requests_file_path%'
- lazy: true
diff --git a/src/Shared/Infrastructure/Symfony/FlashSession.php b/src/Shared/Infrastructure/Symfony/FlashSession.php
new file mode 100644
index 000000000..61bc6a523
--- /dev/null
+++ b/src/Shared/Infrastructure/Symfony/FlashSession.php
@@ -0,0 +1,42 @@
+getSession()->getFlashBag()->all());
+ }
+
+ public function get(string $key, $default = null)
+ {
+ if (array_key_exists($key, self::$flashes)) {
+ return self::$flashes[$key];
+ }
+
+ if (array_key_exists($key . '.0', self::$flashes)) {
+ return self::$flashes[$key . '.0'];
+ }
+
+ if (array_key_exists($key . '.0.0', self::$flashes)) {
+ return self::$flashes[$key . '.0.0'];
+ }
+
+ return $default;
+ }
+
+ public function has(string $key): bool
+ {
+ return array_key_exists($key, self::$flashes)
+ || array_key_exists($key . '.0', self::$flashes)
+ || array_key_exists($key . '.0.0', self::$flashes);
+ }
+}
diff --git a/src/Shared/Infrastructure/Symfony/KernelCache.php b/src/Shared/Infrastructure/Symfony/KernelCache.php
deleted file mode 100644
index 9e14d8cfa..000000000
--- a/src/Shared/Infrastructure/Symfony/KernelCache.php
+++ /dev/null
@@ -1,11 +0,0 @@
-twig->render($templatePath, $arguments));
+ }
+
+ final public function redirect(string $routeName): RedirectResponse
+ {
+ return new RedirectResponse($this->router->generate($routeName), 302);
+ }
+
+ final public function redirectWithMessage(string $routeName, string $message): RedirectResponse
+ {
+ $this->addFlashFor('message', [$message]);
+
+ return $this->redirect($routeName);
+ }
+
+ final public function redirectWithErrors(
+ string $routeName,
+ ConstraintViolationListInterface $errors,
+ Request $request
+ ): RedirectResponse {
+ $this->addFlashFor('errors', $this->formatFlashErrors($errors));
+ $this->addFlashFor('inputs', $request->request->all());
+
+ return new RedirectResponse($this->router->generate($routeName), 302);
+ }
+
+ private function formatFlashErrors(ConstraintViolationListInterface $violations): array
+ {
+ $errors = [];
+ foreach ($violations as $violation) {
+ $errors[str_replace(['[', ']'], ['', ''], $violation->getPropertyPath())] = $violation->getMessage();
+ }
+
+ return $errors;
+ }
+
+ private function addFlashFor(string $prefix, array $messages): void
+ {
+ foreach ($messages as $key => $message) {
+ $this->requestStack->getSession()->getFlashBag()->set($prefix . '.' . $key, $message);
+ }
+ }
+}
diff --git a/src/Shared/Infrastructure/Uuid/UuidGenerator.php b/src/Shared/Infrastructure/Uuid/UuidGenerator.php
deleted file mode 100644
index f5f9aece5..000000000
--- a/src/Shared/Infrastructure/Uuid/UuidGenerator.php
+++ /dev/null
@@ -1,15 +0,0 @@
-toString();
- }
-}
diff --git a/src/Shared/utils.php b/src/Shared/utils.php
deleted file mode 100644
index ce6c2d463..000000000
--- a/src/Shared/utils.php
+++ /dev/null
@@ -1,50 +0,0 @@
-getTimestamp();
- $microseconds = $date->format('u');
- $millisecondsOnASecond = 1000;
-
- return (string) (((float) ($timestamp . '.' . $microseconds)) * $millisecondsOnASecond);
-}
-
-function string_to_date($milliseconds): DateTimeImmutable
-{
- $millisecondsOnASecond = 1000;
- $asSeconds = (int) floor($milliseconds / $millisecondsOnASecond);
- $dateTime = new DateTimeImmutable('@' . ((string) $asSeconds), new DateTimeZone('UTC'));
-
- return new DateTimeImmutable(
- $dateTime->format('Y-m-d\TH:i:s') .
- '.' .
- sprintf('%03d', $milliseconds % $millisecondsOnASecond) .
- '000' .
- $dateTime->format('O')
- );
-}
-
-function snake_to_camel($word)
-{
- return lcfirst(str_replace('_', '', ucwords($word, '_')));
-}
-
-function camel_to_snake($word)
-{
- return ctype_lower($word) ? $word : strtolower(preg_replace('/([^A-Z\s])([A-Z])/', '$1_$2', $word));
-}
-
-function map_no_null(callable $fn, $coll)
-{
- return filter_null(map($fn, $coll));
-}
diff --git a/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandlerTest.php b/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandlerTest.php
new file mode 100644
index 000000000..25787a7db
--- /dev/null
+++ b/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandHandlerTest.php
@@ -0,0 +1,62 @@
+handler = new AuthenticateUserCommandHandler(new UserAuthenticator($this->repository()));
+ }
+
+ /** @test */
+ public function it_should_authenticate_a_valid_user(): void
+ {
+ $command = AuthenticateUserCommandMother::create();
+ $authUser = AuthUserMother::fromCommand($command);
+
+ $this->shouldSearch($authUser->username(), $authUser);
+
+ $this->dispatch($command, $this->handler);
+ }
+
+ /** @test */
+ public function it_should_throw_an_exception_when_the_user_does_not_exist(): void
+ {
+ $this->expectException(InvalidAuthUsername::class);
+
+ $command = AuthenticateUserCommandMother::create();
+ $username = AuthUsernameMother::create($command->username());
+
+ $this->shouldSearch($username);
+
+ $this->dispatch($command, $this->handler);
+ }
+
+ /** @test */
+ public function it_should_throw_an_exception_when_the_password_does_not_math(): void
+ {
+ $this->expectException(InvalidAuthCredentials::class);
+
+ $command = AuthenticateUserCommandMother::create();
+ $authUser = AuthUserMother::create(username: AuthUsernameMother::create($command->username()));
+
+ $this->shouldSearch($authUser->username(), $authUser);
+
+ $this->dispatch($command, $this->handler);
+ }
+}
diff --git a/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandMother.php b/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandMother.php
new file mode 100644
index 000000000..4418e2b9f
--- /dev/null
+++ b/tests/Backoffice/Auth/Application/Authenticate/AuthenticateUserCommandMother.php
@@ -0,0 +1,24 @@
+value() ?? AuthUsernameMother::create()->value(),
+ $password?->value() ?? AuthPasswordMother::create()->value()
+ );
+ }
+}
diff --git a/tests/Backoffice/Auth/AuthModuleUnitTestCase.php b/tests/Backoffice/Auth/AuthModuleUnitTestCase.php
new file mode 100644
index 000000000..4a7ad4a7c
--- /dev/null
+++ b/tests/Backoffice/Auth/AuthModuleUnitTestCase.php
@@ -0,0 +1,30 @@
+repository()
+ ->shouldReceive('search')
+ ->with($this->similarTo($username))
+ ->once()
+ ->andReturn($authUser);
+ }
+
+ protected function repository(): AuthRepository | MockInterface
+ {
+ return $this->repository ??= $this->mock(AuthRepository::class);
+ }
+}
diff --git a/tests/Backoffice/Auth/Domain/AuthPasswordMother.php b/tests/Backoffice/Auth/Domain/AuthPasswordMother.php
new file mode 100644
index 000000000..9426c01c6
--- /dev/null
+++ b/tests/Backoffice/Auth/Domain/AuthPasswordMother.php
@@ -0,0 +1,16 @@
+username()),
+ AuthPasswordMother::create($command->password())
+ );
+ }
+}
diff --git a/tests/Backoffice/Auth/Domain/AuthUsernameMother.php b/tests/Backoffice/Auth/Domain/AuthUsernameMother.php
new file mode 100644
index 000000000..988cedff5
--- /dev/null
+++ b/tests/Backoffice/Auth/Domain/AuthUsernameMother.php
@@ -0,0 +1,16 @@
+service(EntityManager::class));
+ }
+
+ protected function elasticRepository(): ElasticsearchBackofficeCourseRepository
+ {
+ return $this->service(ElasticsearchBackofficeCourseRepository::class);
+ }
+}
diff --git a/tests/Backoffice/Courses/Domain/BackofficeCourseCriteriaMother.php b/tests/Backoffice/Courses/Domain/BackofficeCourseCriteriaMother.php
new file mode 100644
index 000000000..58e38d029
--- /dev/null
+++ b/tests/Backoffice/Courses/Domain/BackofficeCourseCriteriaMother.php
@@ -0,0 +1,26 @@
+ 'name',
+ 'operator' => 'CONTAINS',
+ 'value' => $text,
+ ])
+ )
+ );
+ }
+}
diff --git a/tests/Backoffice/Courses/Domain/BackofficeCourseMother.php b/tests/Backoffice/Courses/Domain/BackofficeCourseMother.php
new file mode 100644
index 000000000..9d2ffbe35
--- /dev/null
+++ b/tests/Backoffice/Courses/Domain/BackofficeCourseMother.php
@@ -0,0 +1,22 @@
+value(),
+ $name ?? CourseNameMother::create()->value(),
+ $duration ?? CourseDurationMother::create()->value()
+ );
+ }
+}
diff --git a/tests/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepositoryTest.php b/tests/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepositoryTest.php
new file mode 100644
index 000000000..a45718666
--- /dev/null
+++ b/tests/Backoffice/Courses/Infrastructure/Persistence/ElasticsearchBackofficeCourseRepositoryTest.php
@@ -0,0 +1,66 @@
+elasticRepository()->save(BackofficeCourseMother::create());
+ }
+
+ /** @test */
+ public function it_should_search_all_existing_courses(): void
+ {
+ $existingCourse = BackofficeCourseMother::create();
+ $anotherExistingCourse = BackofficeCourseMother::create();
+ $existingCourses = [$existingCourse, $anotherExistingCourse];
+
+ $this->elasticRepository()->save($existingCourse);
+ $this->elasticRepository()->save($anotherExistingCourse);
+
+ $this->eventually(fn () => $this->assertSimilar($existingCourses, $this->elasticRepository()->searchAll()));
+ }
+
+ /** @test */
+ public function it_should_search_all_existing_courses_with_an_empty_criteria(): void
+ {
+ $existingCourse = BackofficeCourseMother::create();
+ $anotherExistingCourse = BackofficeCourseMother::create();
+ $existingCourses = [$existingCourse, $anotherExistingCourse];
+
+ $this->elasticRepository()->save($existingCourse);
+ $this->elasticRepository()->save($anotherExistingCourse);
+
+ $this->eventually(
+ fn () => $this->assertSimilar($existingCourses, $this->elasticRepository()->matching(CriteriaMother::empty()))
+ );
+ }
+
+ /** @test */
+ public function it_should_filter_by_criteria(): void
+ {
+ $dddInPhpCourse = BackofficeCourseMother::create(name: 'DDD en PHP');
+ $dddInJavaCourse = BackofficeCourseMother::create(name: 'DDD en Java');
+ $intellijCourse = BackofficeCourseMother::create(name: 'Exprimiendo Intellij');
+ $dddCourses = [$dddInPhpCourse, $dddInJavaCourse];
+
+ $nameContainsDddCriteria = BackofficeCourseCriteriaMother::nameContains('DDD');
+
+ $this->elasticRepository()->save($dddInJavaCourse);
+ $this->elasticRepository()->save($dddInPhpCourse);
+ $this->elasticRepository()->save($intellijCourse);
+
+ $this->eventually(
+ fn () => $this->assertSimilar($dddCourses, $this->elasticRepository()->matching($nameContainsDddCriteria))
+ );
+ }
+}
diff --git a/tests/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepositoryTest.php b/tests/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepositoryTest.php
new file mode 100644
index 000000000..300d01d99
--- /dev/null
+++ b/tests/Backoffice/Courses/Infrastructure/Persistence/MySqlBackofficeCourseRepositoryTest.php
@@ -0,0 +1,64 @@
+mySqlRepository()->save(BackofficeCourseMother::create());
+ }
+
+ /** @test */
+ public function it_should_search_all_existing_courses(): void
+ {
+ $existingCourse = BackofficeCourseMother::create();
+ $anotherExistingCourse = BackofficeCourseMother::create();
+ $existingCourses = [$existingCourse, $anotherExistingCourse];
+
+ $this->mySqlRepository()->save($existingCourse);
+ $this->mySqlRepository()->save($anotherExistingCourse);
+
+ $this->assertSimilar($existingCourses, $this->mySqlRepository()->searchAll());
+ }
+
+ /** @test */
+ public function it_should_search_all_existing_courses_with_an_empty_criteria(): void
+ {
+ $existingCourse = BackofficeCourseMother::create();
+ $anotherExistingCourse = BackofficeCourseMother::create();
+ $existingCourses = [$existingCourse, $anotherExistingCourse];
+
+ $this->mySqlRepository()->save($existingCourse);
+ $this->mySqlRepository()->save($anotherExistingCourse);
+ $this->clearUnitOfWork();
+
+ $this->assertSimilar($existingCourses, $this->mySqlRepository()->matching(CriteriaMother::empty()));
+ }
+
+ /** @test */
+ public function it_should_filter_by_criteria(): void
+ {
+ $dddInPhpCourse = BackofficeCourseMother::create(name: 'DDD en PHP');
+ $dddInJavaCourse = BackofficeCourseMother::create(name: 'DDD en Java');
+ $intellijCourse = BackofficeCourseMother::create(name: 'Exprimiendo Intellij');
+ $dddCourses = [$dddInPhpCourse, $dddInJavaCourse];
+
+ $nameContainsDddCriteria = BackofficeCourseCriteriaMother::nameContains('DDD');
+
+ $this->mySqlRepository()->save($dddInJavaCourse);
+ $this->mySqlRepository()->save($dddInPhpCourse);
+ $this->mySqlRepository()->save($intellijCourse);
+ $this->clearUnitOfWork();
+
+ $this->assertSimilar($dddCourses, $this->mySqlRepository()->matching($nameContainsDddCriteria));
+ }
+}
diff --git a/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeContextInfrastructureTestCase.php b/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeContextInfrastructureTestCase.php
new file mode 100644
index 000000000..0292a6623
--- /dev/null
+++ b/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeContextInfrastructureTestCase.php
@@ -0,0 +1,30 @@
+service(ElasticsearchClient::class),
+ $this->service(EntityManager::class)
+ );
+
+ $arranger->arrange();
+ }
+
+ protected function kernelClass(): string
+ {
+ return BackofficeBackendKernel::class;
+ }
+}
diff --git a/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeEnvironmentArranger.php b/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeEnvironmentArranger.php
new file mode 100644
index 000000000..33a33ea05
--- /dev/null
+++ b/tests/Backoffice/Shared/Infraestructure/PhpUnit/BackofficeEnvironmentArranger.php
@@ -0,0 +1,26 @@
+elasticsearchClient]);
+ apply(new MySqlDatabaseCleaner(), [$this->entityManager]);
+ }
+
+ public function close(): void {}
+}
diff --git a/tests/Mooc/Courses/Application/Create/CreateCourseCommandHandlerTest.php b/tests/Mooc/Courses/Application/Create/CreateCourseCommandHandlerTest.php
new file mode 100644
index 000000000..4fe82e139
--- /dev/null
+++ b/tests/Mooc/Courses/Application/Create/CreateCourseCommandHandlerTest.php
@@ -0,0 +1,37 @@
+handler = new CreateCourseCommandHandler(new CourseCreator($this->repository(), $this->eventBus()));
+ }
+
+ /** @test */
+ public function it_should_create_a_valid_course(): void
+ {
+ $command = CreateCourseCommandMother::create();
+
+ $course = CourseMother::fromRequest($command);
+ $domainEvent = CourseCreatedDomainEventMother::fromCourse($course);
+
+ $this->shouldSave($course);
+ $this->shouldPublishDomainEvent($domainEvent);
+
+ $this->dispatch($command, $this->handler);
+ }
+}
diff --git a/tests/Mooc/Courses/Application/Create/CreateCourseCommandMother.php b/tests/Mooc/Courses/Application/Create/CreateCourseCommandMother.php
new file mode 100644
index 000000000..9d4b31fea
--- /dev/null
+++ b/tests/Mooc/Courses/Application/Create/CreateCourseCommandMother.php
@@ -0,0 +1,28 @@
+value() ?? CourseIdMother::create()->value(),
+ $name?->value() ?? CourseNameMother::create()->value(),
+ $duration?->value() ?? CourseDurationMother::create()->value()
+ );
+ }
+}
diff --git a/tests/Mooc/Courses/Application/Update/CourseRenamerTest.php b/tests/Mooc/Courses/Application/Update/CourseRenamerTest.php
new file mode 100644
index 000000000..7890b36f7
--- /dev/null
+++ b/tests/Mooc/Courses/Application/Update/CourseRenamerTest.php
@@ -0,0 +1,51 @@
+renamer = new CourseRenamer($this->repository(), $this->eventBus());
+ }
+
+ /** @test */
+ public function it_should_rename_an_existing_course(): void
+ {
+ $course = CourseMother::create();
+ $newName = CourseNameMother::create();
+ $renamedCourse = DuplicatorMother::with($course, ['name' => $newName]);
+
+ $this->shouldSearch($course->id(), $course);
+ $this->shouldSave($renamedCourse);
+ $this->shouldNotPublishDomainEvent();
+
+ $this->renamer->__invoke($course->id(), $newName);
+ }
+
+ /** @test */
+ public function it_should_throw_an_exception_when_the_course_not_exist(): void
+ {
+ $this->expectException(CourseNotExist::class);
+
+ $id = CourseIdMother::create();
+
+ $this->shouldSearch($id, null);
+
+ $this->renamer->__invoke($id, CourseNameMother::create());
+ }
+}
diff --git a/tests/Mooc/Courses/CoursesModuleInfrastructureTestCase.php b/tests/Mooc/Courses/CoursesModuleInfrastructureTestCase.php
new file mode 100644
index 000000000..67ad24223
--- /dev/null
+++ b/tests/Mooc/Courses/CoursesModuleInfrastructureTestCase.php
@@ -0,0 +1,16 @@
+service(CourseRepository::class);
+ }
+}
diff --git a/tests/Mooc/Courses/CoursesModuleUnitTestCase.php b/tests/Mooc/Courses/CoursesModuleUnitTestCase.php
new file mode 100644
index 000000000..b4d269546
--- /dev/null
+++ b/tests/Mooc/Courses/CoursesModuleUnitTestCase.php
@@ -0,0 +1,39 @@
+repository()
+ ->shouldReceive('save')
+ ->with($this->similarTo($course))
+ ->once()
+ ->andReturnNull();
+ }
+
+ protected function shouldSearch(CourseId $id, ?Course $course): void
+ {
+ $this->repository()
+ ->shouldReceive('search')
+ ->with($this->similarTo($id))
+ ->once()
+ ->andReturn($course);
+ }
+
+ protected function repository(): CourseRepository | MockInterface
+ {
+ return $this->repository ??= $this->mock(CourseRepository::class);
+ }
+}
diff --git a/tests/Mooc/Courses/Domain/CourseCreatedDomainEventMother.php b/tests/Mooc/Courses/Domain/CourseCreatedDomainEventMother.php
new file mode 100644
index 000000000..b04f7109d
--- /dev/null
+++ b/tests/Mooc/Courses/Domain/CourseCreatedDomainEventMother.php
@@ -0,0 +1,31 @@
+value() ?? CourseIdMother::create()->value(),
+ $name?->value() ?? CourseNameMother::create()->value(),
+ $duration?->value() ?? CourseDurationMother::create()->value()
+ );
+ }
+
+ public static function fromCourse(Course $course): CourseCreatedDomainEvent
+ {
+ return self::create($course->id(), $course->name(), $course->duration());
+ }
+}
diff --git a/tests/Mooc/Courses/Domain/CourseDurationMother.php b/tests/Mooc/Courses/Domain/CourseDurationMother.php
new file mode 100644
index 000000000..2cfc68c06
--- /dev/null
+++ b/tests/Mooc/Courses/Domain/CourseDurationMother.php
@@ -0,0 +1,26 @@
+id()),
+ CourseNameMother::create($request->name()),
+ CourseDurationMother::create($request->duration())
+ );
+ }
+}
diff --git a/tests/Mooc/Courses/Domain/CourseNameMother.php b/tests/Mooc/Courses/Domain/CourseNameMother.php
new file mode 100644
index 000000000..72c4e7e02
--- /dev/null
+++ b/tests/Mooc/Courses/Domain/CourseNameMother.php
@@ -0,0 +1,16 @@
+repository()->save($course);
+ }
+
+ /** @test */
+ public function it_should_return_an_existing_course(): void
+ {
+ $course = CourseMother::create();
+
+ $this->repository()->save($course);
+
+ $this->assertEquals($course, $this->repository()->search($course->id()));
+ }
+
+ /** @test */
+ public function it_should_not_return_a_non_existing_course(): void
+ {
+ $this->assertNull($this->repository()->search(CourseIdMother::create()));
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Application/Find/CoursesCounterResponseMother.php b/tests/Mooc/CoursesCounter/Application/Find/CoursesCounterResponseMother.php
new file mode 100644
index 000000000..07a588148
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Application/Find/CoursesCounterResponseMother.php
@@ -0,0 +1,17 @@
+value() ?? CoursesCounterTotalMother::create()->value());
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQueryHandlerTest.php b/tests/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQueryHandlerTest.php
new file mode 100644
index 000000000..2c8bc2ef5
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Application/Find/FindCoursesCounterQueryHandlerTest.php
@@ -0,0 +1,46 @@
+handler = new FindCoursesCounterQueryHandler(new CoursesCounterFinder($this->repository()));
+ }
+
+ /** @test */
+ public function it_should_find_an_existing_courses_counter(): void
+ {
+ $counter = CoursesCounterMother::create();
+ $query = new FindCoursesCounterQuery();
+ $response = CoursesCounterResponseMother::create($counter->total());
+
+ $this->shouldSearch($counter);
+
+ $this->assertAskResponse($response, $query, $this->handler);
+ }
+
+ /** @test */
+ public function it_should_throw_an_exception_when_courses_counter_does_not_exists(): void
+ {
+ $query = new FindCoursesCounterQuery();
+
+ $this->shouldSearch(null);
+
+ $this->assertAskThrowsException(CoursesCounterNotExist::class, $query, $this->handler);
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreatedTest.php b/tests/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreatedTest.php
new file mode 100644
index 000000000..b81642fc2
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Application/Increment/IncrementCoursesCounterOnCourseCreatedTest.php
@@ -0,0 +1,74 @@
+subscriber = new IncrementCoursesCounterOnCourseCreated(
+ new CoursesCounterIncrementer($this->repository(), $this->uuidGenerator(), $this->eventBus())
+ );
+ }
+
+ /** @test */
+ public function it_should_initialize_a_new_counter(): void
+ {
+ $event = CourseCreatedDomainEventMother::create();
+
+ $courseId = CourseIdMother::create($event->aggregateId());
+ $newCounter = CoursesCounterMother::withOne($courseId);
+ $domainEvent = CoursesCounterIncrementedDomainEventMother::fromCounter($newCounter);
+
+ $this->shouldSearch(null);
+ $this->shouldGenerateUuid($newCounter->id()->value());
+ $this->shouldSave($newCounter);
+ $this->shouldPublishDomainEvent($domainEvent);
+
+ $this->notify($event, $this->subscriber);
+ }
+
+ /** @test */
+ public function it_should_increment_an_existing_counter(): void
+ {
+ $event = CourseCreatedDomainEventMother::create();
+
+ $courseId = CourseIdMother::create($event->aggregateId());
+ $existingCounter = CoursesCounterMother::create();
+ $incrementedCounter = CoursesCounterMother::incrementing($existingCounter, $courseId);
+ $domainEvent = CoursesCounterIncrementedDomainEventMother::fromCounter($incrementedCounter);
+
+ $this->shouldSearch($existingCounter);
+ $this->shouldSave($incrementedCounter);
+ $this->shouldPublishDomainEvent($domainEvent);
+
+ $this->notify($event, $this->subscriber);
+ }
+
+ /** @test */
+ public function it_should_not_increment_an_already_incremented_course(): void
+ {
+ $event = CourseCreatedDomainEventMother::create();
+
+ $courseId = CourseIdMother::create($event->aggregateId());
+ $existingCounter = CoursesCounterMother::withOne($courseId);
+
+ $this->shouldSearch($existingCounter);
+
+ $this->notify($event, $this->subscriber);
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/CoursesCounterModuleUnitTestCase.php b/tests/Mooc/CoursesCounter/CoursesCounterModuleUnitTestCase.php
new file mode 100644
index 000000000..6937e3902
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/CoursesCounterModuleUnitTestCase.php
@@ -0,0 +1,37 @@
+repository()
+ ->shouldReceive('save')
+ ->once()
+ ->with($this->similarTo($course))
+ ->andReturnNull();
+ }
+
+ protected function shouldSearch(?CoursesCounter $counter): void
+ {
+ $this->repository()
+ ->shouldReceive('search')
+ ->once()
+ ->andReturn($counter);
+ }
+
+ protected function repository(): CoursesCounterRepository | MockInterface
+ {
+ return $this->repository ??= $this->mock(CoursesCounterRepository::class);
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Domain/CoursesCounterIdMother.php b/tests/Mooc/CoursesCounter/Domain/CoursesCounterIdMother.php
new file mode 100644
index 000000000..98bf659a1
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Domain/CoursesCounterIdMother.php
@@ -0,0 +1,16 @@
+value() ?? CoursesCounterIdMother::create()->value(),
+ $total?->value() ?? CoursesCounterTotalMother::create()->value()
+ );
+ }
+
+ public static function fromCounter(CoursesCounter $counter): CoursesCounterIncrementedDomainEvent
+ {
+ return self::create($counter->id(), $counter->total());
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Domain/CoursesCounterMother.php b/tests/Mooc/CoursesCounter/Domain/CoursesCounterMother.php
new file mode 100644
index 000000000..d5200a5cd
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Domain/CoursesCounterMother.php
@@ -0,0 +1,41 @@
+ CourseIdMother::create())
+ );
+ }
+
+ public static function withOne(CourseId $courseId): CoursesCounter
+ {
+ return self::create(CoursesCounterIdMother::create(), CoursesCounterTotalMother::one(), $courseId);
+ }
+
+ public static function incrementing(CoursesCounter $existingCounter, CourseId $courseId): CoursesCounter
+ {
+ return self::create(
+ $existingCounter->id(),
+ CoursesCounterTotalMother::create($existingCounter->total()->value() + 1),
+ ...array_merge($existingCounter->existingCourses(), [$courseId])
+ );
+ }
+}
diff --git a/tests/Mooc/CoursesCounter/Domain/CoursesCounterTotalMother.php b/tests/Mooc/CoursesCounter/Domain/CoursesCounterTotalMother.php
new file mode 100644
index 000000000..0c29d090a
--- /dev/null
+++ b/tests/Mooc/CoursesCounter/Domain/CoursesCounterTotalMother.php
@@ -0,0 +1,26 @@
+classes(Selector::inNamespace('/^CodelyTv\\\\Mooc\\\\.+\\\\Domain/', true))
+ ->canOnlyDependOn()
+ ->classes(...array_merge(ArchitectureTest::languageClasses(), [
+ // Itself
+ Selector::inNamespace('/^CodelyTv\\\\Mooc\\\\.+\\\\Domain/', true),
+ // Shared
+ Selector::inNamespace('CodelyTv\Shared\Domain'),
+ ]))
+ ->because('mooc domain can only import itself and shared domain');
+ }
+
+ public function test_mooc_application_should_only_import_itself_and_domain(): Rule
+ {
+ return PHPat::rule()
+ ->classes(Selector::inNamespace('/^CodelyTv\\\\Mooc\\\\.+\\\\Application/', true))
+ ->canOnlyDependOn()
+ ->classes(...array_merge(ArchitectureTest::languageClasses(), [
+ // Itself
+ Selector::inNamespace('/^CodelyTv\\\\Mooc\\\\.+\\\\Application/', true),
+ Selector::inNamespace('/^CodelyTv\\\\Mooc\\\\.+\\\\Domain/', true),
+ // Shared
+ Selector::inNamespace('CodelyTv\Shared'),
+ ]))
+ ->because('mooc application can only import itself and shared');
+ }
+
+ public function test_mooc_infrastructure_should_not_import_other_contexts_beside_shared(): Rule
+ {
+ return PHPat::rule()
+ ->classes(Selector::inNamespace('CodelyTv\Mooc'))
+ ->shouldNotDependOn()
+ ->classes(Selector::inNamespace('CodelyTv'))
+ ->excluding(
+ // Itself
+ Selector::inNamespace('CodelyTv\Mooc'),
+ // Shared
+ Selector::inNamespace('CodelyTv\Shared'),
+ );
+ }
+}
diff --git a/tests/Mooc/Shared/Domain/.gitkeep b/tests/Mooc/Shared/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocContextInfrastructureTestCase.php b/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocContextInfrastructureTestCase.php
new file mode 100644
index 000000000..fb4bef7bf
--- /dev/null
+++ b/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocContextInfrastructureTestCase.php
@@ -0,0 +1,35 @@
+service(EntityManager::class));
+
+ $arranger->arrange();
+ }
+
+ protected function tearDown(): void
+ {
+ $arranger = new MoocEnvironmentArranger($this->service(EntityManager::class));
+
+ $arranger->close();
+
+ parent::tearDown();
+ }
+
+ protected function kernelClass(): string
+ {
+ return MoocBackendKernel::class;
+ }
+}
diff --git a/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocEnvironmentArranger.php b/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocEnvironmentArranger.php
new file mode 100644
index 000000000..39ddf5ef5
--- /dev/null
+++ b/tests/Mooc/Shared/Infrastructure/PhpUnit/MoocEnvironmentArranger.php
@@ -0,0 +1,23 @@
+entityManager]);
+ }
+
+ public function close(): void {}
+}
diff --git a/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php
new file mode 100644
index 000000000..eac56c22f
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/Exercise/ExerciseStepContentMother.php
@@ -0,0 +1,16 @@
+ QuizStepQuestionMother::create()
+ ) : $questions;
+
+ return new QuizStep(
+ $id ?? StepIdMother::create(),
+ $title ?? StepTitleMother::create(),
+ $duration ?? StepDurationMother::create(),
+ ...$stepQuestions
+ );
+ }
+}
diff --git a/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php
new file mode 100644
index 000000000..04fcd8005
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/Quiz/QuizStepQuestionMother.php
@@ -0,0 +1,20 @@
+ WordMother::create())
+ );
+ }
+}
diff --git a/tests/Mooc/Steps/Domain/StepDurationMother.php b/tests/Mooc/Steps/Domain/StepDurationMother.php
new file mode 100644
index 000000000..73ce6842d
--- /dev/null
+++ b/tests/Mooc/Steps/Domain/StepDurationMother.php
@@ -0,0 +1,16 @@
+repository()->save($step);
+ }
+
+ /**
+ * @test
+ * @dataProvider steps
+ */
+ public function it_should_search_an_existing_step(Step $step): void
+ {
+ $this->repository()->save($step);
+
+ $this->assertEquals($step, $this->repository()->search($step->id));
+ }
+
+ /**
+ * @test
+ * @dataProvider steps
+ */
+ public function it_should_delete_an_existing_step(Step $step): void
+ {
+ $this->repository()->save($step);
+ $this->repository()->delete($step);
+
+ $this->assertNull($this->repository()->search($step->id));
+ }
+
+ public function steps(): array
+ {
+ return [
+ 'video' => [VideoStepMother::create()],
+ 'exercise' => [ExerciseStepMother::create()],
+ 'quiz' => [QuizStepMother::create()],
+ ];
+ }
+}
diff --git a/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php
new file mode 100644
index 000000000..8d0eb52ca
--- /dev/null
+++ b/tests/Mooc/Steps/StepsModuleInfrastructureTestCase.php
@@ -0,0 +1,16 @@
+service(StepRepository::class);
+ }
+}
diff --git a/tests/Mooc/Videos/Application/.gitkeep b/tests/Mooc/Videos/Application/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/Mooc/Videos/Domain/.gitkeep b/tests/Mooc/Videos/Domain/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/Mooc/Videos/Infrastructure/.gitkeep b/tests/Mooc/Videos/Infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/Shared/Domain/Criteria/CriteriaMother.php b/tests/Shared/Domain/Criteria/CriteriaMother.php
new file mode 100644
index 000000000..b46d45089
--- /dev/null
+++ b/tests/Shared/Domain/Criteria/CriteriaMother.php
@@ -0,0 +1,26 @@
+getName()])) {
+ $property->setAccessible(true);
+ $property->setValue($duplicated, $newParams[$property->getName()]);
+ }
+ },
+ $reflection->getProperties()
+ );
+
+ return $duplicated;
+ }
+}
diff --git a/tests/Shared/Domain/IntegerMother.php b/tests/Shared/Domain/IntegerMother.php
new file mode 100644
index 000000000..910a08cc8
--- /dev/null
+++ b/tests/Shared/Domain/IntegerMother.php
@@ -0,0 +1,23 @@
+numberBetween($min, $max);
+ }
+
+ public static function lessThan(int $max): int
+ {
+ return self::between(1, $max);
+ }
+}
diff --git a/tests/Shared/Domain/MotherCreator.php b/tests/Shared/Domain/MotherCreator.php
new file mode 100644
index 000000000..f2da13923
--- /dev/null
+++ b/tests/Shared/Domain/MotherCreator.php
@@ -0,0 +1,18 @@
+randomElement($elements);
+ }
+}
diff --git a/tests/Shared/Domain/Repeater.php b/tests/Shared/Domain/Repeater.php
new file mode 100644
index 000000000..19781e14f
--- /dev/null
+++ b/tests/Shared/Domain/Repeater.php
@@ -0,0 +1,20 @@
+evaluate($actual, '', true);
+ }
+
+ public static function assertSimilar(mixed $expected, mixed $actual): void
+ {
+ $constraint = new CodelyTvConstraintIsSimilar($expected);
+
+ $constraint->evaluate($actual);
+ }
+
+ public static function similarTo(mixed $value, float $delta = 0.0): CodelyTvMatcherIsSimilar
+ {
+ return new CodelyTvMatcherIsSimilar($value, $delta);
+ }
+}
diff --git a/tests/Shared/Domain/UuidMother.php b/tests/Shared/Domain/UuidMother.php
new file mode 100644
index 000000000..20bd3516c
--- /dev/null
+++ b/tests/Shared/Domain/UuidMother.php
@@ -0,0 +1,13 @@
+unique()->uuid;
+ }
+}
diff --git a/tests/Shared/Domain/WordMother.php b/tests/Shared/Domain/WordMother.php
new file mode 100644
index 000000000..4bf988e35
--- /dev/null
+++ b/tests/Shared/Domain/WordMother.php
@@ -0,0 +1,13 @@
+word;
+ }
+}
diff --git a/tests/Shared/Infrastructure/ArchitectureTest.php b/tests/Shared/Infrastructure/ArchitectureTest.php
new file mode 100644
index 000000000..6a82b2b18
--- /dev/null
+++ b/tests/Shared/Infrastructure/ArchitectureTest.php
@@ -0,0 +1,40 @@
+sessionHelper = new MinkHelper($this->minkSession);
+ $this->request = new MinkSessionRequestHelper(new MinkHelper($minkSession));
+ }
+
+ /**
+ * @Given I send a :method request to :url
+ */
+ public function iSendARequestTo(string $method, string $url): void
+ {
+ $this->request->sendRequest($method, $this->locatePath($url));
+ }
+
+ /**
+ * @Given I send a :method request to :url with body:
+ */
+ public function iSendARequestToWithBody(string $method, string $url, PyStringNode $body): void
+ {
+ $this->request->sendRequestWithPyStringNode($method, $this->locatePath($url), $body);
+ }
+
+ /**
+ * @Then the response content should be:
+ */
+ public function theResponseContentShouldBe(PyStringNode $expectedResponse): void
+ {
+ $expected = $this->sanitizeOutput($expectedResponse->getRaw());
+ $actual = $this->sanitizeOutput($this->sessionHelper->getResponse());
+
+ if ($expected === false || $actual === false) {
+ throw new RuntimeException('The outputs could not be parsed as JSON');
+ }
+
+ if ($expected !== $actual) {
+ throw new RuntimeException(
+ sprintf("The outputs does not match!\n\n-- Expected:\n%s\n\n-- Actual:\n%s", $expected, $actual)
+ );
+ }
+ }
+
+ /**
+ * @Then the response should be empty
+ */
+ public function theResponseShouldBeEmpty(): void
+ {
+ $actual = trim($this->sessionHelper->getResponse());
+
+ if (!empty($actual)) {
+ throw new RuntimeException(sprintf("The outputs is not empty, Actual:\n%s", $actual));
+ }
+ }
+
+ /**
+ * @Then print last api response
+ */
+ public function printApiResponse(): void
+ {
+ print_r($this->sessionHelper->getResponse());
+ }
+
+ /**
+ * @Then print response headers
+ */
+ public function printResponseHeaders(): void
+ {
+ print_r($this->sessionHelper->getResponseHeaders());
+ }
+
+ /**
+ * @Then the response status code should be :expectedResponseCode
+ */
+ public function theResponseStatusCodeShouldBe(mixed $expectedResponseCode): void
+ {
+ if ($this->minkSession->getStatusCode() !== (int) $expectedResponseCode) {
+ throw new RuntimeException(
+ sprintf(
+ 'The status code <%s> does not match the expected <%s>',
+ $this->minkSession->getStatusCode(),
+ $expectedResponseCode
+ )
+ );
+ }
+ }
+
+ private function sanitizeOutput(string $output): false | string
+ {
+ return json_encode(json_decode(trim($output), true, 512, JSON_THROW_ON_ERROR), JSON_THROW_ON_ERROR);
+ }
+}
diff --git a/tests/Shared/Infrastructure/Behat/ApplicationFeatureContext.php b/tests/Shared/Infrastructure/Behat/ApplicationFeatureContext.php
new file mode 100644
index 000000000..29d6788a8
--- /dev/null
+++ b/tests/Shared/Infrastructure/Behat/ApplicationFeatureContext.php
@@ -0,0 +1,37 @@
+connections->clear();
+ $this->connections->truncate();
+ }
+
+ /**
+ * @Given /^I send an event to the event bus:$/
+ */
+ public function iSendAnEventToTheEventBus(PyStringNode $event): void
+ {
+ $domainEvent = $this->deserializer->deserialize($event->getRaw());
+
+ $this->bus->publish($domainEvent);
+ }
+}
diff --git a/tests/Shared/Infrastructure/Bus/Command/FakeCommand.php b/tests/Shared/Infrastructure/Bus/Command/FakeCommand.php
new file mode 100644
index 000000000..d009d2a79
--- /dev/null
+++ b/tests/Shared/Infrastructure/Bus/Command/FakeCommand.php
@@ -0,0 +1,9 @@
+commandBus = new InMemorySymfonyCommandBus([$this->commandHandler()]);
+ }
+
+ /** @test */
+ public function it_should_be_able_to_handle_a_command(): void
+ {
+ $this->expectException(RuntimeException::class);
+
+ $this->commandBus->dispatch(new FakeCommand());
+ }
+
+ /** @test */
+ public function it_should_raise_an_exception_dispatching_a_non_registered_command(): void
+ {
+ $this->expectException(CommandNotRegisteredError::class);
+
+ $this->commandBus->dispatch($this->command());
+ }
+
+ private function commandHandler(): object
+ {
+ return new class() {
+ public function __invoke(FakeCommand $command): never
+ {
+ throw new RuntimeException('This works fine!');
+ }
+ };
+ }
+
+ private function command(): Command | MockInterface
+ {
+ return $this->mock(Command::class);
+ }
+}
diff --git a/tests/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBusTest.php b/tests/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBusTest.php
new file mode 100644
index 000000000..ca17d6ceb
--- /dev/null
+++ b/tests/Shared/Infrastructure/Bus/Event/MySql/MySqlDoctrineEventBusTest.php
@@ -0,0 +1,51 @@
+bus = new MySqlDoctrineEventBus($this->service(EntityManager::class));
+ $this->consumer = new MySqlDoctrineDomainEventsConsumer(
+ $this->service(EntityManager::class),
+ $this->service(DomainEventMapping::class)
+ );
+ }
+
+ /** @test */
+ public function it_should_publish_and_consume_domain_events_from_msql(): void
+ {
+ $domainEvent = CourseCreatedDomainEventMother::create();
+ $anotherDomainEvent = CoursesCounterIncrementedDomainEventMother::create();
+
+ $this->bus->publish($domainEvent, $anotherDomainEvent);
+
+ $this->consumer->consume(
+ subscribers: fn (DomainEvent ...$expectedEvents) => $this->assertContainsEquals($domainEvent, $expectedEvents),
+ eventsToConsume: 2
+ );
+ }
+
+ protected function kernelClass(): string
+ {
+ return MoocBackendKernel::class;
+ }
+}
diff --git a/tests/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBusTest.php b/tests/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBusTest.php
new file mode 100644
index 000000000..b3d5b09e8
--- /dev/null
+++ b/tests/Shared/Infrastructure/Bus/Event/RabbitMq/RabbitMqEventBusTest.php
@@ -0,0 +1,181 @@
+connection = $this->service(RabbitMqConnection::class);
+
+ $this->exchangeName = 'test_domain_events';
+ $this->configurer = new RabbitMqConfigurer($this->connection);
+ $this->publisher = new RabbitMqEventBus(
+ $this->connection,
+ $this->exchangeName,
+ $this->service(MySqlDoctrineEventBus::class)
+ );
+ $this->consumer = new RabbitMqDomainEventsConsumer(
+ $this->connection,
+ $this->service(DomainEventJsonDeserializer::class),
+ $this->exchangeName,
+ $maxRetries = 1
+ );
+ $this->fakeSubscriber = new TestAllWorksOnRabbitMqEventsPublished();
+ $this->consumerHasBeenExecuted = false;
+
+ $this->cleanEnvironment($this->connection);
+ }
+
+ /** @test */
+ public function it_should_publish_and_consume_domain_events_from_rabbitmq(): void
+ {
+ $domainEvent = CourseCreatedDomainEventMother::create();
+
+ $this->configurer->configure($this->exchangeName, $this->fakeSubscriber);
+
+ $this->publisher->publish($domainEvent);
+
+ $this->consumer->consume(
+ $this->assertConsumer($domainEvent),
+ RabbitMqQueueNameFormatter::format($this->fakeSubscriber)
+ );
+
+ $this->assertTrue($this->consumerHasBeenExecuted);
+ }
+
+ /** @test */
+ public function it_should_throw_an_exception_consuming_non_existing_domain_events(): void
+ {
+ $this->expectException(RuntimeException::class);
+
+ $domainEvent = CoursesCounterIncrementedDomainEventMother::create();
+
+ $this->configurer->configure($this->exchangeName, $this->fakeSubscriber);
+
+ $this->publisher->publish($domainEvent);
+
+ $this->consumer->consume(
+ $this->assertConsumer($domainEvent),
+ RabbitMqQueueNameFormatter::format($this->fakeSubscriber)
+ );
+
+ $this->assertTrue($this->consumerHasBeenExecuted);
+ }
+
+ /** @test */
+ public function it_should_retry_failed_domain_events(): void
+ {
+ $domainEvent = CourseCreatedDomainEventMother::create();
+
+ $this->configurer->configure($this->exchangeName, $this->fakeSubscriber);
+
+ $this->publisher->publish($domainEvent);
+
+ $this->simulateErrorConsuming();
+
+ sleep(1);
+
+ $this->consumer->consume(
+ $this->assertConsumer($domainEvent),
+ RabbitMqQueueNameFormatter::format($this->fakeSubscriber)
+ );
+
+ $this->assertTrue($this->consumerHasBeenExecuted);
+ }
+
+ /** @test */
+ public function it_should_send_events_to_dead_letter_after_retry_failed_domain_events(): void
+ {
+ $domainEvent = CourseCreatedDomainEventMother::create();
+
+ $this->configurer->configure($this->exchangeName, $this->fakeSubscriber);
+
+ $this->publisher->publish($domainEvent);
+
+ $this->simulateErrorConsuming();
+
+ sleep(1);
+
+ $this->simulateErrorConsuming();
+
+ $this->assertDeadLetterContainsEvent(1);
+ }
+
+ protected function kernelClass(): string
+ {
+ return MoocBackendKernel::class;
+ }
+
+ private function assertConsumer(DomainEvent ...$expectedDomainEvents): callable
+ {
+ return function (DomainEvent $domainEvent) use ($expectedDomainEvents): void {
+ $this->assertContainsEquals($domainEvent, $expectedDomainEvents);
+
+ $this->consumerHasBeenExecuted = true;
+ };
+ }
+
+ private function failingConsumer(): callable
+ {
+ return static function (DomainEvent $domainEvent): never {
+ throw new RuntimeException('To test');
+ };
+ }
+
+ private function simulateErrorConsuming(): void
+ {
+ try {
+ $this->consumer->consume($this->failingConsumer(), RabbitMqQueueNameFormatter::format($this->fakeSubscriber));
+ } catch (Throwable $error) {
+ $this->assertInstanceOf(RuntimeException::class, $error);
+ }
+ }
+
+ private function cleanEnvironment(RabbitMqConnection $connection): void
+ {
+ $connection->queue(RabbitMqQueueNameFormatter::format($this->fakeSubscriber))->delete();
+ $connection->queue(RabbitMqQueueNameFormatter::formatRetry($this->fakeSubscriber))->delete();
+ $connection->queue(RabbitMqQueueNameFormatter::formatDeadLetter($this->fakeSubscriber))->delete();
+ }
+
+ private function assertDeadLetterContainsEvent(int $expectedNumberOfEvents): void
+ {
+ $totalEventsInDeadLetter = 0;
+
+ while ($this->connection->queue(RabbitMqQueueNameFormatter::formatDeadLetter($this->fakeSubscriber))->get(
+ AMQP_AUTOACK
+ )) {
+ $totalEventsInDeadLetter++;
+ }
+
+ $this->assertSame($expectedNumberOfEvents, $totalEventsInDeadLetter);
+ }
+}
diff --git a/tests/Shared/Infrastructure/Bus/Event/RabbitMq/TestAllWorksOnRabbitMqEventsPublished.php b/tests/Shared/Infrastructure/Bus/Event/RabbitMq/TestAllWorksOnRabbitMqEventsPublished.php
new file mode 100644
index 000000000..937f28e08
--- /dev/null
+++ b/tests/Shared/Infrastructure/Bus/Event/RabbitMq/TestAllWorksOnRabbitMqEventsPublished.php
@@ -0,0 +1,19 @@
+number;
+ }
+}
diff --git a/tests/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBusTest.php b/tests/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBusTest.php
new file mode 100644
index 000000000..dc3f2095b
--- /dev/null
+++ b/tests/Shared/Infrastructure/Bus/Query/InMemorySymfonyQueryBusTest.php
@@ -0,0 +1,55 @@
+queryBus = new InMemorySymfonyQueryBus([$this->queryHandler()]);
+ }
+
+ /** @test */
+ public function it_should_return_a_response_successfully(): void
+ {
+ $this->expectException(RuntimeException::class);
+
+ $this->queryBus->ask(new FakeQuery());
+ }
+
+ /** @test */
+ public function it_should_raise_an_exception_dispatching_a_non_registered_query(): void
+ {
+ $this->expectException(QueryNotRegisteredError::class);
+
+ $this->queryBus->ask($this->query());
+ }
+
+ private function queryHandler(): object
+ {
+ return new class() {
+ public function __invoke(FakeQuery $query): never
+ {
+ throw new RuntimeException('This works fine!');
+ }
+ };
+ }
+
+ private function query(): MockInterface | Query
+ {
+ return $this->mock(Query::class);
+ }
+}
diff --git a/tests/Shared/Infrastructure/ConstantRandomNumberGenerator.php b/tests/Shared/Infrastructure/ConstantRandomNumberGenerator.php
new file mode 100644
index 000000000..810e216cc
--- /dev/null
+++ b/tests/Shared/Infrastructure/ConstantRandomNumberGenerator.php
@@ -0,0 +1,15 @@
+getConnection();
+
+ $tables = $this->tables($connection);
+ $truncateTablesSql = $this->truncateDatabaseSql($tables);
+
+ $connection->executeQuery($truncateTablesSql);
+ }
+
+ private function truncateDatabaseSql(array $tables): string
+ {
+ $truncateTables = map($this->truncateTableSql(), $tables);
+
+ return sprintf('SET FOREIGN_KEY_CHECKS = 0; %s SET FOREIGN_KEY_CHECKS = 1;', implode(' ', $truncateTables));
+ }
+
+ private function truncateTableSql(): callable
+ {
+ return fn (array $table): string => sprintf('TRUNCATE TABLE `%s`;', (string) first($table));
+ }
+
+ private function tables(Connection $connection): array
+ {
+ return $connection->executeQuery('SHOW TABLES')->fetchAllAssociative();
+ }
+}
diff --git a/tests/Shared/Infrastructure/Elastic/ElasticDatabaseCleaner.php b/tests/Shared/Infrastructure/Elastic/ElasticDatabaseCleaner.php
new file mode 100644
index 000000000..293d5284a
--- /dev/null
+++ b/tests/Shared/Infrastructure/Elastic/ElasticDatabaseCleaner.php
@@ -0,0 +1,27 @@
+client()->cat()->indices();
+
+ each(
+ static function (array $index) use ($client): void {
+ $indexName = $index['index'];
+
+ $client->client()->indices()->delete(['index' => $indexName]);
+ $client->client()->indices()->create(['index' => $indexName]);
+ },
+ $indices
+ );
+ }
+}
diff --git a/tests/Shared/Infrastructure/Mink/MinkHelper.php b/tests/Shared/Infrastructure/Mink/MinkHelper.php
new file mode 100644
index 000000000..ea443d6e1
--- /dev/null
+++ b/tests/Shared/Infrastructure/Mink/MinkHelper.php
@@ -0,0 +1,80 @@
+ [],
+ 'files' => [],
+ 'server' => ['HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
+ 'content' => null,
+ 'changeHistory' => true,
+ ];
+
+ $optionalParams = array_merge($defaultOptionalParams, $optionalParams);
+
+ $crawler = $this->getClient()->request(
+ $method,
+ $url,
+ $optionalParams['parameters'],
+ $optionalParams['files'],
+ $optionalParams['server'],
+ $optionalParams['content'],
+ $optionalParams['changeHistory']
+ );
+
+ return $crawler;
+ }
+
+ public function getResponse(): string
+ {
+ return $this->getSession()->getPage()->getContent();
+ }
+
+ public function getResponseHeaders(): array
+ {
+ return $this->normalizeHeaders(array_change_key_case($this->getSession()->getResponseHeaders(), CASE_LOWER));
+ }
+
+ public function resetServerParameters(): void
+ {
+ $this->getClient()->setServerParameters([]);
+ }
+
+ public function getRequest(): object
+ {
+ return $this->getClient()->getRequest();
+ }
+
+ private function getSession(): Session
+ {
+ return $this->session;
+ }
+
+ private function getDriver(): DriverInterface
+ {
+ return $this->getSession()->getDriver();
+ }
+
+ private function getClient(): AbstractBrowser
+ {
+ return $this->getDriver()->getClient();
+ }
+
+ private function normalizeHeaders(array $headers): array
+ {
+ return array_map('implode', array_filter($headers));
+ }
+}
diff --git a/tests/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php b/tests/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php
new file mode 100644
index 000000000..df914dd98
--- /dev/null
+++ b/tests/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php
@@ -0,0 +1,28 @@
+request($method, $url, $optionalParams);
+ }
+
+ public function sendRequestWithPyStringNode($method, $url, PyStringNode $body): void
+ {
+ $this->request($method, $url, ['content' => $body->getRaw()]);
+ }
+
+ public function request(string $method, string $url, array $optionalParams = []): Crawler
+ {
+ return $this->sessionHelper->sendRequest($method, $url, $optionalParams);
+ }
+}
diff --git a/tests/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php b/tests/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php
new file mode 100644
index 000000000..1737b7adb
--- /dev/null
+++ b/tests/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php
@@ -0,0 +1,29 @@
+constraint = new CodelyTvConstraintIsSimilar($value, $delta);
+ }
+
+ public function match(&$actual): bool
+ {
+ return $this->constraint->evaluate($actual, '', true);
+ }
+
+ public function __toString(): string
+ {
+ return 'Is similar';
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootArraySimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootArraySimilarComparator.php
new file mode 100644
index 000000000..22ee1fccf
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootArraySimilarComparator.php
@@ -0,0 +1,49 @@
+contains($expected, $actual) || count($expected) !== count($actual)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting the collection of AGs contains all the expected elements.'
+ );
+ }
+ }
+
+ private function contains(array $expectedArray, array $actualArray): bool
+ {
+ $exists = fn (AggregateRoot $expected): bool => any(
+ fn (AggregateRoot $actual): bool => TestUtils::isSimilar($expected, $actual),
+ $actualArray
+ );
+
+ return all($exists, $expectedArray);
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootSimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootSimilarComparator.php
new file mode 100644
index 000000000..aefd86a36
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/AggregateRootSimilarComparator.php
@@ -0,0 +1,74 @@
+pullDomainEvents();
+
+ if (!$this->aggregateRootsAreSimilar($expected, $actualEntity)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting the aggregate roots are equal.'
+ );
+ }
+ }
+
+ private function aggregateRootsAreSimilar(AggregateRoot $expected, AggregateRoot $actual): bool
+ {
+ if (!$this->aggregateRootsAreTheSameClass($expected, $actual)) {
+ return false;
+ }
+
+ return $this->aggregateRootPropertiesAreSimilar($expected, $actual);
+ }
+
+ private function aggregateRootsAreTheSameClass(AggregateRoot $expected, AggregateRoot $actual): bool
+ {
+ return $expected::class === $actual::class;
+ }
+
+ private function aggregateRootPropertiesAreSimilar(AggregateRoot $expected, AggregateRoot $actual): bool
+ {
+ $expectedReflected = new ReflectionObject($expected);
+ $actualReflected = new ReflectionObject($actual);
+
+ foreach ($expectedReflected->getProperties() as $expectedReflectedProperty) {
+ $actualReflectedProperty = $actualReflected->getProperty($expectedReflectedProperty->getName());
+
+ $expectedReflectedProperty->setAccessible(true);
+ $actualReflectedProperty->setAccessible(true);
+
+ $expectedProperty = $expectedReflectedProperty->getValue($expected);
+ $actualProperty = $actualReflectedProperty->getValue($actual);
+
+ if (!TestUtils::isSimilar($expectedProperty, $actualProperty)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeSimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeSimilarComparator.php
new file mode 100644
index 000000000..67d3b5605
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeSimilarComparator.php
@@ -0,0 +1,50 @@
+sub($intervalWithDelta) || $actual > $expectedUpper->add($intervalWithDelta)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->dateTimeToString($expected),
+ $this->dateTimeToString($actual),
+ false,
+ 'Failed asserting that two DateTime objects are equal.'
+ );
+ }
+ }
+
+ protected function dateTimeToString(DateTimeInterface $datetime): string
+ {
+ return $datetime->format(DateTime::ATOM) ?: 'Invalid DateTime object';
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeStringSimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeStringSimilarComparator.php
new file mode 100644
index 000000000..546c75cb9
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/DateTimeStringSimilarComparator.php
@@ -0,0 +1,71 @@
+isValidDateTimeString($expected)
+ && $this->isValidDateTimeString($actual);
+ }
+
+ public function assertEquals(
+ $expected,
+ $actual,
+ $delta = 0.0,
+ $canonicalize = false,
+ $ignoreCase = false,
+ array &$processed = []
+ ): void {
+ $expectedDate = new DateTimeImmutable($expected);
+ $actualDate = new DateTimeImmutable($actual);
+
+ $normalizedDelta = $delta === 0.0 ? 10 : $delta;
+ $intervalWithDelta = new DateInterval(sprintf('PT%sS', abs($normalizedDelta)));
+
+ if ($actualDate < $expectedDate->sub($intervalWithDelta)
+ || $actualDate > $expectedDate->add($intervalWithDelta)) {
+ throw new ComparisonFailure(
+ $expectedDate,
+ $actualDate,
+ $this->dateTimeToString($expectedDate),
+ $this->dateTimeToString($actualDate),
+ false,
+ 'Failed asserting that two DateTime strings are equal.'
+ );
+ }
+ }
+
+ protected function dateTimeToString(DateTimeInterface $datetime): string
+ {
+ $string = $datetime->format(DateTime::ATOM);
+
+ return $string ?: 'Invalid DateTime object';
+ }
+
+ private function isValidDateTimeString(string $expected): bool
+ {
+ $isValid = true;
+
+ try {
+ new DateTimeImmutable($expected);
+ } catch (Throwable) {
+ $isValid = false;
+ }
+
+ return $isValid;
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventArraySimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventArraySimilarComparator.php
new file mode 100644
index 000000000..c191f7fb0
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventArraySimilarComparator.php
@@ -0,0 +1,49 @@
+contains($expected, $actual) || count($expected) !== count($actual)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting the collection of Events contains all the expected elements.'
+ );
+ }
+ }
+
+ private function contains(array $expectedArray, array $actualArray): bool
+ {
+ $exists = static fn (DomainEvent $expected): bool => any(
+ static fn (DomainEvent $actual): bool => TestUtils::isSimilar($expected, $actual),
+ $actualArray
+ );
+
+ return all($exists, $expectedArray);
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventSimilarComparator.php b/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventSimilarComparator.php
new file mode 100644
index 000000000..f14cb6a77
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Comparator/DomainEventSimilarComparator.php
@@ -0,0 +1,75 @@
+areSimilar($expected, $actual)) {
+ throw new ComparisonFailure(
+ $expected,
+ $actual,
+ $this->exporter->export($expected),
+ $this->exporter->export($actual),
+ false,
+ 'Failed asserting the events are equal.'
+ );
+ }
+ }
+
+ private function areSimilar(DomainEvent $expected, DomainEvent $actual): bool
+ {
+ if (!$this->areTheSameClass($expected, $actual)) {
+ return false;
+ }
+
+ return $this->propertiesAreSimilar($expected, $actual);
+ }
+
+ private function areTheSameClass(DomainEvent $expected, DomainEvent $actual): bool
+ {
+ return $expected::class === $actual::class;
+ }
+
+ private function propertiesAreSimilar(DomainEvent $expected, DomainEvent $actual): bool
+ {
+ $expectedReflected = new ReflectionObject($expected);
+ $actualReflected = new ReflectionObject($actual);
+
+ foreach ($expectedReflected->getProperties() as $expectedReflectedProperty) {
+ if (!in_array($expectedReflectedProperty->getName(), self::$ignoredAttributes, false)) {
+ $actualReflectedProperty = $actualReflected->getProperty($expectedReflectedProperty->getName());
+
+ $expectedReflectedProperty->setAccessible(true);
+ $actualReflectedProperty->setAccessible(true);
+
+ $expectedProperty = $expectedReflectedProperty->getValue($expected);
+ $actualProperty = $actualReflectedProperty->getValue($actual);
+
+ if (!TestUtils::isSimilar($expectedProperty, $actualProperty)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/Constraint/CodelyTvConstraintIsSimilar.php b/tests/Shared/Infrastructure/PhpUnit/Constraint/CodelyTvConstraintIsSimilar.php
new file mode 100644
index 000000000..e5b4ca53a
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/Constraint/CodelyTvConstraintIsSimilar.php
@@ -0,0 +1,75 @@
+value === $other) {
+ return true;
+ }
+
+ $isValid = true;
+ $comparatorFactory = new Factory();
+
+ $comparatorFactory->register(new AggregateRootArraySimilarComparator());
+ $comparatorFactory->register(new AggregateRootSimilarComparator());
+ $comparatorFactory->register(new DomainEventArraySimilarComparator());
+ $comparatorFactory->register(new DomainEventSimilarComparator());
+ $comparatorFactory->register(new DateTimeSimilarComparator());
+ $comparatorFactory->register(new DateTimeStringSimilarComparator());
+
+ try {
+ $comparator = $comparatorFactory->getComparatorFor($other, $this->value);
+
+ $comparator->assertEquals($this->value, $other, $this->delta);
+ } catch (ComparisonFailure $f) {
+ if (!$returnResult) {
+ throw new ExpectationFailedException(trim($description . "\n" . $f->getMessage()), $f);
+ }
+
+ $isValid = false;
+ }
+
+ return $isValid;
+ }
+
+ public function toString(): string
+ {
+ $delta = '';
+
+ if (is_string($this->value)) {
+ if (str_contains($this->value, "\n")) {
+ return 'is equal to ';
+ }
+
+ return sprintf("is equal to '%s'", $this->value);
+ }
+
+ if ($this->delta !== 0) {
+ $delta = sprintf(' with delta <%F>', $this->delta);
+ }
+
+ return sprintf('is equal to %s%s', $this->exporter()->export($this->value), $delta);
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/InfrastructureTestCase.php b/tests/Shared/Infrastructure/PhpUnit/InfrastructureTestCase.php
new file mode 100644
index 000000000..52438a8f0
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/InfrastructureTestCase.php
@@ -0,0 +1,64 @@
+kernelClass();
+
+ self::bootKernel(['environment' => 'test']);
+
+ parent::setUp();
+ }
+
+ protected function assertSimilar(mixed $expected, mixed $actual): void
+ {
+ TestUtils::assertSimilar($expected, $actual);
+ }
+
+ protected function service(string $id): mixed
+ {
+ return self::getContainer()->get($id);
+ }
+
+ protected function parameter(string $parameter): mixed
+ {
+ return self::getContainer()->getParameter($parameter);
+ }
+
+ protected function clearUnitOfWork(): void
+ {
+ $this->service(EntityManager::class)->clear();
+ }
+
+ /** @param int<0, max> $timeToWaitOnErrorInSeconds */
+ protected function eventually(
+ callable $fn,
+ int $totalRetries = 3,
+ int $timeToWaitOnErrorInSeconds = 1,
+ int $attempt = 0
+ ): void {
+ try {
+ $fn();
+ } catch (Throwable $error) {
+ if ($totalRetries === $attempt) {
+ throw $error;
+ }
+
+ sleep($timeToWaitOnErrorInSeconds);
+
+ $this->eventually($fn, $totalRetries, $timeToWaitOnErrorInSeconds, $attempt + 1);
+ }
+ }
+}
diff --git a/tests/Shared/Infrastructure/PhpUnit/UnitTestCase.php b/tests/Shared/Infrastructure/PhpUnit/UnitTestCase.php
new file mode 100644
index 000000000..599f2005d
--- /dev/null
+++ b/tests/Shared/Infrastructure/PhpUnit/UnitTestCase.php
@@ -0,0 +1,104 @@
+eventBus()
+ ->shouldReceive('publish')
+ ->with($this->similarTo($domainEvent))
+ ->andReturnNull();
+ }
+
+ protected function shouldNotPublishDomainEvent(): void
+ {
+ $this->eventBus()
+ ->shouldReceive('publish')
+ ->withNoArgs()
+ ->andReturnNull();
+ }
+
+ protected function eventBus(): EventBus | MockInterface
+ {
+ return $this->eventBus ??= $this->mock(EventBus::class);
+ }
+
+ protected function shouldGenerateUuid(string $uuid): void
+ {
+ $this->uuidGenerator()
+ ->shouldReceive('generate')
+ ->once()
+ ->withNoArgs()
+ ->andReturn($uuid);
+ }
+
+ protected function uuidGenerator(): MockInterface | UuidGenerator
+ {
+ return $this->uuidGenerator ??= $this->mock(UuidGenerator::class);
+ }
+
+ protected function notify(DomainEvent $event, callable $subscriber): void
+ {
+ $subscriber($event);
+ }
+
+ protected function dispatch(Command $command, callable $commandHandler): void
+ {
+ $commandHandler($command);
+ }
+
+ protected function assertAskResponse(Response $expected, Query $query, callable $queryHandler): void
+ {
+ $actual = $queryHandler($query);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+ /** @param class-string $expectedErrorClass */
+ protected function assertAskThrowsException(string $expectedErrorClass, Query $query, callable $queryHandler): void
+ {
+ $this->expectException($expectedErrorClass);
+
+ $queryHandler($query);
+ }
+
+ protected function isSimilar(mixed $expected, mixed $actual): bool
+ {
+ return TestUtils::isSimilar($expected, $actual);
+ }
+
+ protected function assertSimilar(mixed $expected, mixed $actual): void
+ {
+ TestUtils::assertSimilar($expected, $actual);
+ }
+
+ protected function similarTo(mixed $value, float $delta = 0.0): CodelyTvMatcherIsSimilar
+ {
+ return TestUtils::similarTo($value, $delta);
+ }
+}
diff --git a/tests/Shared/SharedArchitectureTest.php b/tests/Shared/SharedArchitectureTest.php
new file mode 100644
index 000000000..da8b1e751
--- /dev/null
+++ b/tests/Shared/SharedArchitectureTest.php
@@ -0,0 +1,62 @@
+classes(Selector::inNamespace('CodelyTv\Shared\Domain'))
+ ->canOnlyDependOn()
+ ->classes(...array_merge(ArchitectureTest::languageClasses(), [
+ // Itself
+ Selector::inNamespace('CodelyTv\Shared\Domain'),
+ // Dependencies treated as domain
+ Selector::classname(Uuid::class),
+ ]))
+ ->because('shared domain cannot import from outside');
+ }
+
+ public function test_shared_infrastructure_should_not_import_from_other_contexts(): Rule
+ {
+ return PHPat::rule()
+ ->classes(Selector::inNamespace('CodelyTv\Shared\Infrastructure'))
+ ->shouldNotDependOn()
+ ->classes(Selector::inNamespace('CodelyTv'))
+ ->excluding(
+ // Itself
+ Selector::inNamespace('CodelyTv\Shared'),
+ // This need to be refactored
+ Selector::classname(MySqlDatabaseCleaner::class),
+ Selector::classname(AuthenticateUserCommand::class),
+ Selector::inNamespace('CodelyTv\Backoffice\Auth'),
+ );
+ }
+
+ public function test_all_use_cases_can_only_have_one_public_method(): Rule
+ {
+ return PHPat::rule()
+ ->classes(
+ Selector::classname('/^CodelyTv\\\\.+\\\\.+\\\\Application\\\\.+\\\\(?!.*(?:Command|Query)$).*$/', true)
+ )
+ ->excluding(
+ Selector::implements(Response::class),
+ Selector::implements(DomainEventSubscriber::class),
+ Selector::inNamespace('/.*\\\\Tests\\\\.*/', true)
+ )
+ ->shouldHaveOnlyOnePublicMethod();
+ }
+}
diff --git a/tests/applications/mooc_backend/features/student/student_get.feature b/tests/applications/mooc_backend/features/student/student_get.feature
deleted file mode 100644
index b77cc038c..000000000
--- a/tests/applications/mooc_backend/features/student/student_get.feature
+++ /dev/null
@@ -1,33 +0,0 @@
-Feature: Find a student
- In order to learn from CodelyTV Pro courses
- As an authenticated student
- I want to view my profile details
-
- Background:
- Given there is an student:
- | id | fe7017d0-9e8f-4952-99d1-e047e36b1694 |
- | total_pending_videos | 5 |
- | name | VicenΓ§ |
-
- Scenario: Find an existing student
- Given I send a GET request to "/students/fe7017d0-9e8f-4952-99d1-e047e36b1694"
- Then the response status code should be 200
- And the response content should be:
- """
- {
- "id": "fe7017d0-9e8f-4952-99d1-e047e36b1694",
- "name": "VicenΓ§",
- "total_pending_videos": 5
- }
- """
-
- Scenario: Not find a non existing video
- Given I send a GET request to "/students/05ed7eb7-7888-4730-b9e9-0c16cfa80b80"
- Then the response status code should be 404
- And the response content should be:
- """
- {
- "code": "student_not_exist",
- "message": "The student <05ed7eb7-7888-4730-b9e9-0c16cfa80b80> does not exists"
- }
- """
diff --git a/tests/applications/mooc_backend/features/student/student_put.feature b/tests/applications/mooc_backend/features/student/student_put.feature
deleted file mode 100644
index 0d3cb770a..000000000
--- a/tests/applications/mooc_backend/features/student/student_put.feature
+++ /dev/null
@@ -1,14 +0,0 @@
-Feature: Sign up a student
- In order to learn from CodelyTV Pro courses
- As an anonymous student
- I want to sign up to the platform
-
- Scenario: Sign up a new student
- Given I send a PUT request to "/students/0ca24fc4-bdc8-48d0-9c5f-94183a627adc" with body:
- """
- {
- "name": "javi"
- }
- """
- Then the response status code should be 201
- And the response should be empty
diff --git a/tests/applications/mooc_backend/features/video/video_get.feature b/tests/applications/mooc_backend/features/video/video_get.feature
deleted file mode 100644
index deef80c60..000000000
--- a/tests/applications/mooc_backend/features/video/video_get.feature
+++ /dev/null
@@ -1,44 +0,0 @@
-Feature: Find a video
- In order to be the best youtuber ever
- As a codelyver
- I want to find a video
-
- Background:
- Given I send a POST request to "/video" with body:
- """
- {
- "request_id": "170cfccd-869d-414b-a521-9cce9e0e67a2",
- "id": "465892a1-5a77-4cee-9450-46ecd6b68f69",
- "title": "Exprimiendo los tipos de PHP7",
- "url": "https://codely.tv/screencasts/tipos-php-7/",
- "type": "screencast",
- "course_id": "9c8a481a-0fe2-49cf-ab8a-79bcc2965d00"
- }
- """
- Then the response should be empty
- And the response status code should be 201
-
- Scenario: Find an existing video
- Given I send a GET request to "/video/465892a1-5a77-4cee-9450-46ecd6b68f69"
- Then the response status code should be 200
- And the response content should be:
- """
- {
- "id": "465892a1-5a77-4cee-9450-46ecd6b68f69",
- "title": "Exprimiendo los tipos de PHP7",
- "url": "https://codely.tv/screencasts/tipos-php-7/",
- "type": "screencast",
- "course_id": "9c8a481a-0fe2-49cf-ab8a-79bcc2965d00"
- }
- """
-
- Scenario: Not find a non existing video
- Given I send a GET request to "/video/09acb178-0831-4d86-a364-bff0e19d8f19"
- Then the response status code should be 404
- And the response content should be:
- """
- {
- "code": "video_not_found",
- "message": "The video <09acb178-0831-4d86-a364-bff0e19d8f19> has not been found"
- }
- """
diff --git a/tests/applications/mooc_backend/features/video/video_post.feature b/tests/applications/mooc_backend/features/video/video_post.feature
deleted file mode 100644
index f0d1b3319..000000000
--- a/tests/applications/mooc_backend/features/video/video_post.feature
+++ /dev/null
@@ -1,34 +0,0 @@
-Feature: Create video
- In order to be the best youtuber ever
- As a codelyver
- I want to create a video
-
- Scenario: Create an screencast video
- Given I send a POST request to "/video" with body:
- """
- {
- "request_id": "170cfccd-869d-414b-a521-9cce9e0e67a2",
- "id": "465892a1-5a77-4cee-9450-46ecd6b68f69",
- "title": "Exprimiendo los tipos de PHP7",
- "url": "https://codely.tv/screencasts/tipos-php-7/",
- "type": "screencast",
- "course_id": "9c8a481a-0fe2-49cf-ab8a-79bcc2965d00"
- }
- """
- Then the response should be empty
- And the response status code should be 201
-
- Scenario: Create an interview video
- Given I send a POST request to "/video" with body:
- """
- {
- "request_id": "6ee07c6b-a1e7-4cfa-abf5-cbfd4884cd75",
- "id": "87cf6e20-a79b-4f0e-bf26-4a69de0cafe1",
- "title": "Entrevista RaΓΊl Raja - CTO 47 Degrees",
- "url": "https://codely.tv/entrevistas/raul-raja-cto-47-degrees/",
- "type": "interview",
- "course_id": "48c2c2ea-bd93-4248-9f71-81ad37ad5647"
- }
- """
- Then the response should be empty
- And the response status code should be 201
diff --git a/tests/applications/mooc_backend/mooc_backend.yml b/tests/applications/mooc_backend/mooc_backend.yml
deleted file mode 100644
index fb3755e70..000000000
--- a/tests/applications/mooc_backend/mooc_backend.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-mooc_backend:
- extensions:
- FriendsOfBehat\SymfonyExtension:
- kernel:
- class: CodelyTv\MoocBackend\MoocBackendKernel
- Behat\MinkExtension:
- sessions:
- symfony:
- symfony: ~
- base_url: 'http://localhost'
-
- suites:
- status:
- paths: [ tests/applications/mooc_backend/features/status ]
- contexts:
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiFeatureContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiRequestContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiResponseContext
- video:
- paths: [ tests/applications/mooc_backend/features/video ]
- contexts:
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiFeatureContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiRequestContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiResponseContext
- student:
- paths: [ tests/applications/mooc_backend/features/student ]
- contexts:
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiFeatureContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiRequestContext
- - CodelyTv\Test\Shared\Infrastructure\Behat\ApiContext\ApiResponseContext
- - CodelyTv\Test\Mooc\Students\StudentModuleBehatContext
diff --git a/tests/src/Backoffice/README.md b/tests/src/Backoffice/README.md
deleted file mode 100644
index c639cd6d2..000000000
--- a/tests/src/Backoffice/README.md
+++ /dev/null
@@ -1 +0,0 @@
-Here we'll have our Backoffice tests :)
diff --git a/tests/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreatedTest.php b/tests/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreatedTest.php
deleted file mode 100644
index 6097f4814..000000000
--- a/tests/src/Mooc/Notifications/Application/Create/CreateNotificationOnVideoCreatedTest.php
+++ /dev/null
@@ -1,20 +0,0 @@
-service('codely.mooc.notifications.repository');
- }
-}
diff --git a/tests/src/Mooc/Notifications/NotificationModuleUnitTestCase.php b/tests/src/Mooc/Notifications/NotificationModuleUnitTestCase.php
deleted file mode 100644
index 0eb2e8564..000000000
--- a/tests/src/Mooc/Notifications/NotificationModuleUnitTestCase.php
+++ /dev/null
@@ -1,20 +0,0 @@
-repository = $this->repository ?: $this->mock(NotificationRepository::class);
- }
-}
diff --git a/tests/src/Mooc/Shared/Domain/Courses/CourseIdMother.php b/tests/src/Mooc/Shared/Domain/Courses/CourseIdMother.php
deleted file mode 100644
index b1e226850..000000000
--- a/tests/src/Mooc/Shared/Domain/Courses/CourseIdMother.php
+++ /dev/null
@@ -1,21 +0,0 @@
-service(MoocEnvironmentArranger::class),
- ];
- }
-}
diff --git a/tests/src/Mooc/Shared/Infrastructure/MoocContextUnitTestCase.php b/tests/src/Mooc/Shared/Infrastructure/MoocContextUnitTestCase.php
deleted file mode 100644
index 65fbfec45..000000000
--- a/tests/src/Mooc/Shared/Infrastructure/MoocContextUnitTestCase.php
+++ /dev/null
@@ -1,11 +0,0 @@
-entityManager = $entityManager;
- }
-
- public function arrange(): void
- {
- apply(new DatabaseCleaner(), [$this->entityManager]);
- }
-
- public function close(): void
- {
- }
-}
diff --git a/tests/src/Mooc/Steps/Domain/Challenge/ChallengeStepMother.php b/tests/src/Mooc/Steps/Domain/Challenge/ChallengeStepMother.php
deleted file mode 100644
index aa9a37aa3..000000000
--- a/tests/src/Mooc/Steps/Domain/Challenge/ChallengeStepMother.php
+++ /dev/null
@@ -1,48 +0,0 @@
-repository()->save($step);
- }
-
- public function validSteps(): array
- {
- return [
- ['challenge step' => ChallengeStepMother::random()],
- ['quiz step' => QuizStepMother::random()],
- ['video step' => VideoStepMother::random()],
- ];
- }
-
- private function repository(): StepRepository
- {
- return $this->service(StepRepositoryMySql::class);
- }
-}
diff --git a/tests/src/Mooc/Steps/StepsModuleFunctionalTestCase.php b/tests/src/Mooc/Steps/StepsModuleFunctionalTestCase.php
deleted file mode 100644
index 2e276d771..000000000
--- a/tests/src/Mooc/Steps/StepsModuleFunctionalTestCase.php
+++ /dev/null
@@ -1,11 +0,0 @@
-value());
- }
-
- public static function random(): FindStudentQuery
- {
- return self::create(StudentIdMother::random());
- }
-}
diff --git a/tests/src/Mooc/Students/Application/Find/FindStudentTest.php b/tests/src/Mooc/Students/Application/Find/FindStudentTest.php
deleted file mode 100644
index 3b04f1e2f..000000000
--- a/tests/src/Mooc/Students/Application/Find/FindStudentTest.php
+++ /dev/null
@@ -1,55 +0,0 @@
-repository());
-
- $this->handler = new FindStudentQueryHandler($finder);
- }
-
- /** @test */
- public function it_should_find_an_existing_student(): void
- {
- $query = FindStudentQueryMother::random();
-
- $id = StudentIdMother::create($query->id());
- $student = StudentMother::withId($id);
-
- $response = StudentResponseMother::create($student->id(), $student->name(), $student->totalVideosCreated());
-
- $this->shouldSearchStudent($id, $student);
-
- $this->assertAskResponse($query, $response, $this->handler);
- }
-
- /** @test */
- public function it_should_throw_an_exception_finding_a_non_existing_student(): void
- {
- $query = FindStudentQueryMother::random();
-
- $id = StudentIdMother::create($query->id());
-
- $this->shouldSearchStudent($id);
-
- $this->assertAskThrowsException(StudentNotExist::class, $query, $this->handler);
- }
-}
diff --git a/tests/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentPendingVideosOnVideoPublishedTest.php b/tests/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentPendingVideosOnVideoPublishedTest.php
deleted file mode 100644
index 441d3db0c..000000000
--- a/tests/src/Mooc/Students/Application/IncreasePendingVideos/IncreaseStudentPendingVideosOnVideoPublishedTest.php
+++ /dev/null
@@ -1,52 +0,0 @@
-repository());
-
- $this->subscriber = new IncreaseStudentTotalVideosCreatedOnVideoCreated($increaser);
- }
-
- /** @test */
- public function it_should_increase_student_total_videos_created_on_scala_video_created(): void
- {
- $event = ScalaVideoCreatedDomainEventMother::random();
-
- $id = StudentIdMother::create($event->creatorId());
- $student = StudentMother::withId($id);
-
- $updatedStudent = DuplicatorMother::with(
- $student,
- [
- 'totalVideosCreated' => StudentTotalVideosCreatedMother::create(
- $student->totalVideosCreated()->value() + 1
- ),
- ]
- );
-
- $this->shouldSearchStudent($id, $student);
- $this->shouldSaveStudent($updatedStudent);
-
- $this->notify($event, $this->subscriber);
- }
-}
diff --git a/tests/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEventMother.php b/tests/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEventMother.php
deleted file mode 100644
index 7e8989f9e..000000000
--- a/tests/src/Mooc/Students/Domain/ScalaVideoCreatedDomainEventMother.php
+++ /dev/null
@@ -1,23 +0,0 @@
-value(), ['creatorId' => $userId->value()]);
- }
-
- public static function random(): ScalaVideoCreatedDomainEvent
- {
- return self::create(VideoIdMother::random(), StudentIdMother::random());
- }
-}
diff --git a/tests/src/Mooc/Students/Domain/StudentIdMother.php b/tests/src/Mooc/Students/Domain/StudentIdMother.php
deleted file mode 100644
index fcfcddf52..000000000
--- a/tests/src/Mooc/Students/Domain/StudentIdMother.php
+++ /dev/null
@@ -1,21 +0,0 @@
-value(), $name->value(), $totalPendingVideos->value());
- }
-
- public static function random(): StudentResponse
- {
- return self::create(
- StudentIdMother::random(),
- StudentNameMother::random(),
- StudentTotalVideosCreatedMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/Students/Domain/StudentTotalVideosCreatedMother.php b/tests/src/Mooc/Students/Domain/StudentTotalVideosCreatedMother.php
deleted file mode 100644
index fc43e7344..000000000
--- a/tests/src/Mooc/Students/Domain/StudentTotalVideosCreatedMother.php
+++ /dev/null
@@ -1,21 +0,0 @@
-repository()->save(StudentMother::random());
- }
-
- /** @test */
- public function it_should_find_an_existing_video(): void
- {
- $student = StudentMother::random();
-
- $this->repository()->save($student);
- $this->clearUnitOfWork();
-
- $this->assertSimilar($student, $this->repository()->search($student->id()));
- }
-
- /** @test */
- public function it_should_find_multiples_video(): void
- {
- $student = StudentMother::random();
- $another = StudentMother::random();
- $students = StudentsMother::create($student, $another);
-
- $this->repository()->saveAll($students);
- $this->clearUnitOfWork();
-
- $this->assertSimilar($students, $this->repository()->all());
- }
-
- /** @test */
- public function it_should_not_find_a_non_existing_video(): void
- {
- $this->assertNull($this->repository()->search(StudentIdMother::random()));
- }
-
- private function repository(): StudentRepository
- {
- return $this->service(StudentRepositoryMySql::class);
- }
-}
diff --git a/tests/src/Mooc/Students/StudentModuleBehatContext.php b/tests/src/Mooc/Students/StudentModuleBehatContext.php
deleted file mode 100644
index 311bf45eb..000000000
--- a/tests/src/Mooc/Students/StudentModuleBehatContext.php
+++ /dev/null
@@ -1,38 +0,0 @@
-repository = $repository;
- }
-
- /**
- * @Given /^there is an student:$/
- */
- public function thereIsAnStudent(TableNode $table): void
- {
- apply($this->creator(), [$table->getRowsHash()]);
- }
-
- private function creator(): callable
- {
- return function (array $student) {
- $this->repository->save(
- StudentMother::withValues($student['id'], $student['name'], (int) $student['total_pending_videos'])
- );
- };
- }
-}
diff --git a/tests/src/Mooc/Students/StudentModuleFunctionalTestCase.php b/tests/src/Mooc/Students/StudentModuleFunctionalTestCase.php
deleted file mode 100644
index 0295e29bb..000000000
--- a/tests/src/Mooc/Students/StudentModuleFunctionalTestCase.php
+++ /dev/null
@@ -1,11 +0,0 @@
-repository = $this->repository ?: $this->mock(StudentRepository::class);
- }
-
- protected function shouldSaveStudent(Student $student): void
- {
- $this->repository()
- ->shouldReceive('save')
- ->with(similarTo($student))
- ->once()
- ->andReturnNull();
- }
-
- protected function shouldSearchStudent(StudentId $id, Student $student = null): void
- {
- $this->repository()
- ->shouldReceive('search')
- ->with(equalTo($id))
- ->once()
- ->andReturn($student);
- }
-}
diff --git a/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandMother.php b/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandMother.php
deleted file mode 100644
index 80412eb9e..000000000
--- a/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentCommandMother.php
+++ /dev/null
@@ -1,37 +0,0 @@
-value(), $videoId->value(), $content->value());
- }
-
- public static function random(): PublishVideoCommentCommand
- {
- return self::create(
- new Uuid(UuidMother::random()),
- VideoCommentIdMother::random(),
- VideoIdMother::random(),
- VideoCommentContentMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentTest.php b/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentTest.php
deleted file mode 100644
index 4a8807a69..000000000
--- a/tests/src/Mooc/VideoComments/Application/Publish/PublishVideoCommentTest.php
+++ /dev/null
@@ -1,85 +0,0 @@
-repository(), $this->queryBus(), $this->domainEventPublisher());
-
- $this->handler = new PublishVideoCommentCommandHandler($publisher);
- }
-
- /** @test */
- public function it_should_publish_a_video_comment(): void
- {
- $command = PublishVideoCommentCommandMother::random();
-
- $id = VideoCommentIdMother::create($command->id());
- $videoId = VideoIdMother::create($command->videoId());
- $content = VideoCommentContentMother::create($command->content());
-
- $comment = VideoCommentMother::create($id, $videoId, $content);
-
- $domainEvent = VideoCommentPublishedDomainEventMother::create($id, $videoId, $content);
-
- $this->shouldAsk(FindVideoQueryMother::create($videoId), VideoResponseMother::withId($videoId));
- $this->shouldSaveVideoComment($comment);
- $this->shouldPublishDomainEvents($domainEvent);
-
- $this->dispatch($command, $this->handler);
- }
-
- /** @test */
- public function it_should_not_publish_a_video_comment_when_the_video_not_exist(): void
- {
- $this->expectException(VideoNotFound::class);
-
- $command = PublishVideoCommentCommandMother::random();
-
- $videoId = VideoIdMother::create($command->videoId());
-
- $this->shouldAskThrowingException(FindVideoQueryMother::create($videoId), new VideoNotFound($videoId));
-
- $this->dispatch($command, $this->handler);
- }
-
- /** @return VideoCommentRepository|MockInterface */
- private function repository()
- {
- return $this->repository = $this->repository ?: $this->mock(VideoCommentRepository::class);
- }
-
- private function shouldSaveVideoComment(VideoComment $comment): void
- {
- $this->repository()
- ->shouldReceive('save')
- ->once()
- ->with(similarTo($comment))
- ->andReturnNull();
- }
-}
diff --git a/tests/src/Mooc/VideoComments/Domain/VideoCommentContentMother.php b/tests/src/Mooc/VideoComments/Domain/VideoCommentContentMother.php
deleted file mode 100644
index b72d9f1b6..000000000
--- a/tests/src/Mooc/VideoComments/Domain/VideoCommentContentMother.php
+++ /dev/null
@@ -1,23 +0,0 @@
-value(),
- [
- 'videoId' => $videoId->value(),
- 'content' => $content->value(),
- ]
- );
- }
-
- public static function random(): VideoCommentPublishedDomainEvent
- {
- return self::create(
- VideoCommentIdMother::random(),
- VideoIdMother::random(),
- VideoCommentContentMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandlerTest.php b/tests/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandlerTest.php
deleted file mode 100644
index d900c766c..000000000
--- a/tests/src/Mooc/VideoHighlights/Application/Create/CreateVideoHighlightCommandHandlerTest.php
+++ /dev/null
@@ -1,20 +0,0 @@
-service('codely.mooc.video_highlights.repository');
- }
-}
diff --git a/tests/src/Mooc/VideoHighlights/VideoHighlightModuleUnitTestCase.php b/tests/src/Mooc/VideoHighlights/VideoHighlightModuleUnitTestCase.php
deleted file mode 100644
index 55b85d154..000000000
--- a/tests/src/Mooc/VideoHighlights/VideoHighlightModuleUnitTestCase.php
+++ /dev/null
@@ -1,20 +0,0 @@
-repository = $this->repository ?: $this->mock(VideoHighlightRepository::class);
- }
-}
diff --git a/tests/src/Mooc/Videos/Application/Create/CreateVideoCommandMother.php b/tests/src/Mooc/Videos/Application/Create/CreateVideoCommandMother.php
deleted file mode 100644
index 433a97c74..000000000
--- a/tests/src/Mooc/Videos/Application/Create/CreateVideoCommandMother.php
+++ /dev/null
@@ -1,52 +0,0 @@
-value(),
- $type->value(),
- $title->value(),
- $url->value(),
- $courseId->value()
- );
- }
-
- public static function random(): CreateVideoCommand
- {
- return self::create(
- new Uuid(UuidMother::random()),
- VideoIdMother::random(),
- VideoTypeMother::random(),
- VideoTitleMother::random(),
- VideoUrlMother::random(),
- CourseIdMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/Videos/Application/Create/CreateVideoTest.php b/tests/src/Mooc/Videos/Application/Create/CreateVideoTest.php
deleted file mode 100644
index bf093bb8b..000000000
--- a/tests/src/Mooc/Videos/Application/Create/CreateVideoTest.php
+++ /dev/null
@@ -1,52 +0,0 @@
-repository(), $this->domainEventPublisher());
-
- $this->handler = new CreateVideoCommandHandler($creator);
- }
-
- /** @test */
- public function it_should_create_a_video(): void
- {
- $command = CreateVideoCommandMother::random();
-
- $id = VideoIdMother::create($command->id());
- $type = VideoTypeMother::create($command->type());
- $title = VideoTitleMother::create($command->title());
- $url = VideoUrlMother::create($command->url());
- $courseId = CourseIdMother::create($command->courseId());
-
- $video = VideoMother::create($id, $type, $title, $url, $courseId);
-
- $domainEvent = VideoCreatedDomainEventMother::create($id, $type, $title, $url, $courseId);
-
- $this->shouldSaveVideo($video);
- $this->shouldPublishDomainEvents($domainEvent);
-
- $this->dispatch($command, $this->handler);
- }
-}
diff --git a/tests/src/Mooc/Videos/Application/Find/FindVideoQueryMother.php b/tests/src/Mooc/Videos/Application/Find/FindVideoQueryMother.php
deleted file mode 100644
index 663d6b397..000000000
--- a/tests/src/Mooc/Videos/Application/Find/FindVideoQueryMother.php
+++ /dev/null
@@ -1,22 +0,0 @@
-value());
- }
-
- public static function random(): FindVideoQuery
- {
- return self::create(VideoIdMother::random());
- }
-}
diff --git a/tests/src/Mooc/Videos/Application/Find/FindVideoTest.php b/tests/src/Mooc/Videos/Application/Find/FindVideoTest.php
deleted file mode 100644
index d4062a997..000000000
--- a/tests/src/Mooc/Videos/Application/Find/FindVideoTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
-repository());
-
- $this->handler = new FindVideoQueryHandler($finder);
- }
-
- /** @test */
- public function it_should_find_an_existing_video(): void
- {
- $query = FindVideoQueryMother::random();
-
- $id = VideoIdMother::create($query->id());
- $video = VideoMother::withId($id);
-
- $response = VideoResponseMother::create(
- $video->id(),
- $video->type(),
- $video->title(),
- $video->url(),
- $video->courseId()
- );
-
- $this->shouldSearchVideo($id, $video);
-
- $this->assertAskResponse($query, $response, $this->handler);
- }
-
- /** @test */
- public function it_should_throw_an_exception_finding_a_non_existing_video(): void
- {
- $query = FindVideoQueryMother::random();
-
- $id = VideoIdMother::create($query->id());
-
- $this->shouldSearchVideo($id);
-
- $this->assertAskThrowsException(VideoNotFound::class, $query, $this->handler);
- }
-}
diff --git a/tests/src/Mooc/Videos/Application/Find/VideoResponseMother.php b/tests/src/Mooc/Videos/Application/Find/VideoResponseMother.php
deleted file mode 100644
index f0fc13599..000000000
--- a/tests/src/Mooc/Videos/Application/Find/VideoResponseMother.php
+++ /dev/null
@@ -1,47 +0,0 @@
-value(), $type->value(), $title->value(), $url->value(), $courseId->value());
- }
-
- public static function withId(VideoId $id): VideoResponse
- {
- return DuplicatorMother::with(self::random(), ['id' => $id->value()]);
- }
-
- public static function random(): VideoResponse
- {
- return self::create(
- VideoIdMother::random(),
- VideoTypeMother::random(),
- VideoTitleMother::random(),
- VideoUrlMother::random(),
- CourseIdMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/Videos/Domain/VideoCreatedDomainEventMother.php b/tests/src/Mooc/Videos/Domain/VideoCreatedDomainEventMother.php
deleted file mode 100644
index 7e6891689..000000000
--- a/tests/src/Mooc/Videos/Domain/VideoCreatedDomainEventMother.php
+++ /dev/null
@@ -1,46 +0,0 @@
-value(),
- [
- 'type' => $type->value(),
- 'title' => $title->value(),
- 'url' => $url->value(),
- 'courseId' => $courseId->value(),
- ]
- );
- }
-
- public static function random(): VideoCreatedDomainEvent
- {
- return self::create(
- VideoIdMother::random(),
- VideoTypeMother::random(),
- VideoTitleMother::random(),
- VideoUrlMother::random(),
- CourseIdMother::random()
- );
- }
-}
diff --git a/tests/src/Mooc/Videos/Domain/VideoIdMother.php b/tests/src/Mooc/Videos/Domain/VideoIdMother.php
deleted file mode 100644
index 511ec8f91..000000000
--- a/tests/src/Mooc/Videos/Domain/VideoIdMother.php
+++ /dev/null
@@ -1,21 +0,0 @@
-repository()->save(VideoMother::random());
- }
-
- /** @test */
- public function it_should_find_an_existing_video(): void
- {
- $video = VideoMother::random();
-
- $this->repository()->save($video);
- $this->clearUnitOfWork();
-
- $this->assertSimilar($video, $this->repository()->search($video->id()));
- }
-
- /** @test */
- public function it_should_not_find_a_non_existing_video(): void
- {
- $this->assertNull($this->repository()->search(VideoIdMother::random()));
- }
-
- private function repository(): VideoRepository
- {
- return $this->service(VideoRepositoryMySql::class);
- }
-}
diff --git a/tests/src/Mooc/Videos/VideoModuleFunctionalTestCase.php b/tests/src/Mooc/Videos/VideoModuleFunctionalTestCase.php
deleted file mode 100644
index fb4ea05c0..000000000
--- a/tests/src/Mooc/Videos/VideoModuleFunctionalTestCase.php
+++ /dev/null
@@ -1,11 +0,0 @@
-repository = $this->repository ?: $this->mock(VideoRepository::class);
- }
-
- protected function shouldSaveVideo(Video $video): void
- {
- $this->repository()
- ->shouldReceive('save')
- ->with(similarTo($video))
- ->once()
- ->andReturnNull();
- }
-
- protected function shouldSearchVideo(VideoId $id, Video $video = null): void
- {
- $this->repository()
- ->shouldReceive('search')
- ->with(equalTo($id))
- ->once()
- ->andReturn($video);
- }
-}
diff --git a/tests/src/Shared/Domain/BoolMother.php b/tests/src/Shared/Domain/BoolMother.php
deleted file mode 100644
index 987a86d86..000000000
--- a/tests/src/Shared/Domain/BoolMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-boolean;
- }
-}
diff --git a/tests/src/Shared/Domain/Criteria/CriteriaMother.php b/tests/src/Shared/Domain/Criteria/CriteriaMother.php
deleted file mode 100644
index e90912fe0..000000000
--- a/tests/src/Shared/Domain/Criteria/CriteriaMother.php
+++ /dev/null
@@ -1,33 +0,0 @@
-dateTimeBetween('-1 year'));
- }
-
- public static function now(): DateTimeImmutable
- {
- return self::create('now');
- }
-
- public static function aLongTimeAgo(): DateTimeImmutable
- {
- return static::immutable(MotherCreator::random()->dateTimeBetween('-2 year', '-1 year'));
- }
-
- public static function random(): DateTimeImmutable
- {
- return new DateTimeImmutable();
- }
-
- private static function immutable(DateTime $date): DateTimeImmutable
- {
- return DateTimeImmutable::createFromMutable($date);
- }
-}
diff --git a/tests/src/Shared/Domain/DateTimeZoneMother.php b/tests/src/Shared/Domain/DateTimeZoneMother.php
deleted file mode 100644
index b0fbf4683..000000000
--- a/tests/src/Shared/Domain/DateTimeZoneMother.php
+++ /dev/null
@@ -1,25 +0,0 @@
-timezone);
- }
-
- public static function UTC(): DateTimeZone
- {
- return self::create('UTC');
- }
-}
diff --git a/tests/src/Shared/Domain/DateTimestampMother.php b/tests/src/Shared/Domain/DateTimestampMother.php
deleted file mode 100644
index 73c369020..000000000
--- a/tests/src/Shared/Domain/DateTimestampMother.php
+++ /dev/null
@@ -1,21 +0,0 @@
-getName()])) {
- $property->setAccessible(true);
- $property->setValue($duplicated, $newParams[$property->getName()]);
- }
- },
- $reflection->getProperties()
- );
-
- return $duplicated;
- }
-}
diff --git a/tests/src/Shared/Domain/ImageUrlMother.php b/tests/src/Shared/Domain/ImageUrlMother.php
deleted file mode 100644
index 5b7eb3e56..000000000
--- a/tests/src/Shared/Domain/ImageUrlMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-imageUrl();
- }
-}
diff --git a/tests/src/Shared/Domain/Md5Mother.php b/tests/src/Shared/Domain/Md5Mother.php
deleted file mode 100644
index 37bc10539..000000000
--- a/tests/src/Shared/Domain/Md5Mother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-md5;
- }
-}
diff --git a/tests/src/Shared/Domain/MotherCreator.php b/tests/src/Shared/Domain/MotherCreator.php
deleted file mode 100644
index eb0683881..000000000
--- a/tests/src/Shared/Domain/MotherCreator.php
+++ /dev/null
@@ -1,23 +0,0 @@
-numberBetween($min, $max);
- }
-
- public static function lessThan($max): int
- {
- return self::between(1, $max);
- }
-
- public static function moreThan($min): int
- {
- return self::between($min);
- }
-
- public static function float($numDecimals = null): float
- {
- return MotherCreator::random()->randomFloat($numDecimals);
- }
-
- public static function floatBetween($min, $max, $numDecimals = null): float
- {
- return MotherCreator::random()->randomFloat($numDecimals, $min, $max);
- }
-
- public static function randomPercentage(): int
- {
- return self::between(0, 100);
- }
-
- public static function randomPositive(): int
- {
- return self::between(0, 1000);
- }
-
- public static function random(): int
- {
- return self::between(1);
- }
-}
diff --git a/tests/src/Shared/Domain/RandomElementMother.php b/tests/src/Shared/Domain/RandomElementMother.php
deleted file mode 100644
index 60efb3fcf..000000000
--- a/tests/src/Shared/Domain/RandomElementMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-randomElement($choices);
- }
-}
diff --git a/tests/src/Shared/Domain/RepeatMother.php b/tests/src/Shared/Domain/RepeatMother.php
deleted file mode 100644
index d367a17dc..000000000
--- a/tests/src/Shared/Domain/RepeatMother.php
+++ /dev/null
@@ -1,25 +0,0 @@
-text($maxNumbersOfCharacters);
- }
-
- public static function short(): string
- {
- return self::create(100);
- }
-
- public static function random(): string
- {
- return self::create(NumberMother::between(100, 2000));
- }
-
- public static function withMinLength(int $minLength): string
- {
- $numWords = $minLength;
- $variableNumWords = false;
-
- return MotherCreator::random()->sentence($numWords, $variableNumWords);
- }
-}
diff --git a/tests/src/Shared/Domain/UrlMother.php b/tests/src/Shared/Domain/UrlMother.php
deleted file mode 100644
index 622dca103..000000000
--- a/tests/src/Shared/Domain/UrlMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-url;
- }
-}
diff --git a/tests/src/Shared/Domain/UuidMother.php b/tests/src/Shared/Domain/UuidMother.php
deleted file mode 100644
index b508a04b6..000000000
--- a/tests/src/Shared/Domain/UuidMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-unique()->uuid;
- }
-}
diff --git a/tests/src/Shared/Domain/WordMother.php b/tests/src/Shared/Domain/WordMother.php
deleted file mode 100644
index e0ff29ee1..000000000
--- a/tests/src/Shared/Domain/WordMother.php
+++ /dev/null
@@ -1,13 +0,0 @@
-word;
- }
-}
diff --git a/tests/src/Shared/Enum/EnumTest.php b/tests/src/Shared/Enum/EnumTest.php
deleted file mode 100644
index 138ff83d9..000000000
--- a/tests/src/Shared/Enum/EnumTest.php
+++ /dev/null
@@ -1,25 +0,0 @@
-assertEquals('one', StringTestEnum::one()->value());
- $this->assertEquals('two', StringTestEnum::two()->value());
- $this->assertEquals('A very large number', StringTestEnum::aVeryLargeNumber()->value());
- }
-
- /** @test */
- public function it_should_be_able_to_construct_enums_with_numbers_inside(): void
- {
- $this->assertEquals(1, NumberTestEnum::one()->value());
- $this->assertEquals(2, NumberTestEnum::two()->value());
- }
-}
diff --git a/tests/src/Shared/Enum/NumberTestEnum.php b/tests/src/Shared/Enum/NumberTestEnum.php
deleted file mode 100644
index 7e1d4cab2..000000000
--- a/tests/src/Shared/Enum/NumberTestEnum.php
+++ /dev/null
@@ -1,22 +0,0 @@
-minkSession = $minkSession;
- }
-
-
- /**
- * @Given I send a :method request to :url
- */
- public function iSendARequestTo($method, $url): void
- {
- $this->getSessionRequestHelper()->sendRequest($method, $this->locatePath($url));
- }
-
- /**
- * @When I send a :method request to :url with the parameters:
- */
- public function iSendARequestToWithParameters($method, $url, TableNode $parameters): void
- {
- $this->getSessionRequestHelper()->sendRequestWithTableNode($method, $this->locatePath($url), $parameters);
- }
-
- /**
- * @Given I send a :method request to :url with body:
- */
- public function iSendARequestToWithBody($method, $url, PyStringNode $body): void
- {
- $this->getSessionRequestHelper()->sendRequestWithPyStringNode($method, $this->locatePath($url), $body);
- }
-
- /**
- * @When I add :name header equal to :value
- */
- public function iAddHeaderEqualTo($name, $value): void
- {
- $this->getSessionRequestHelper()->addHeaderEqualTo($name, $value);
- }
-
- /**
- * @Then print request headers
- */
- public function printRequestHeaders(): void
- {
- $this->getSessionRequestHelper()->printRequestHeaders();
- }
-
- private function getSessionRequestHelper(): MinkSessionRequestHelper
- {
- return $this->sessionRequestHelper = $this->sessionRequestHelper
- ?: new MinkSessionRequestHelper(new MinkHelper($this->minkSession));
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Behat/ApiContext/ApiResponseContext.php b/tests/src/Shared/Infrastructure/Behat/ApiContext/ApiResponseContext.php
deleted file mode 100644
index fb44c4f2e..000000000
--- a/tests/src/Shared/Infrastructure/Behat/ApiContext/ApiResponseContext.php
+++ /dev/null
@@ -1,191 +0,0 @@
-minkSession = $minkSession;
- }
-
- public static function assertJsonStringEqualsJsonString($expectedJson, $actualJson, $message = ''): void
- {
- Assert::assertJson($expectedJson, 'The expected value is not a valid json');
- Assert::assertJson($actualJson, 'The actual value is not a valid json');
-
- $expected = json_decode($expectedJson);
- $actual = json_decode($actualJson);
-
- Assert::assertThat(
- $actual,
- new CodelyTvConstraintIsSimilar($expected, 20), // @todo For functional
- $message
- );
- }
-
- /**
- * @Then the response content should be:
- */
- public function theResponseContentShouldBe(PyStringNode $expected): void
- {
- if ($this->getSessionHelper()->getResponseHeader('content-type') === 'application/json') {
- self::assertJsonStringEqualsJsonString(
- $this->adaptExpected($expected->getRaw()),
- $this->getSessionResponseHelper()->getResponse(),
- sprintf('The string "%s" is not equal to the response of the current page', $expected)
- );
- } else {
- Assert::assertEquals(
- $expected->getRaw(),
- $this->getSessionResponseHelper()->getResponse(),
- sprintf('The string "%s" is not equal to the response of the current page', $expected)
- );
- }
- }
-
- /**
- * @Then the response should be empty
- */
- public function theResponseShouldBeEmpty(): void
- {
- Assert::assertEmpty(
- $this->getSessionResponseHelper()->getResponse(),
- 'The response of the current page is not empty'
- );
- }
-
- /**
- * @Then print last api response
- */
- public function printApiResponse(): void
- {
- print_r($this->getSessionResponseHelper()->getResponse());
- }
-
- /**
- * @Then the response parameter :name should exist
- */
- public function theResponseParameterShouldExist($name): void
- {
- if (!$this->getSessionHelper()->hasResponseParameter($name)) {
- throw new RuntimeException(sprintf('Parameter "%s" does not exists in response', $name));
- }
- }
-
- /**
- * @Then the response parameter :name should match :regex
- */
- public function theResponseParameterShouldMatch($name, $regex): void
- {
- $value = $this->getSessionHelper()->getResponseParameter($name);
- $errorMessage = vsprintf(
- 'The response parameter "%s" is "%s" and it should match "%s" but it does not.',
- [$name, $value, $regex]
- );
-
- Assert::assertRegExp($regex, (string) $value, $errorMessage);
- }
-
- /**
- * @Then the response parameter :name should be :expectedValue
- */
- public function theResponseParameterShouldBe($name, $expectedValue): void
- {
- $value = $this->getSessionHelper()->getResponseParameter($name);
- Assert::assertEquals($expectedValue, $value);
- }
-
- /**
- * @Then print response headers
- */
- public function printResponseHeaders(): void
- {
- print_r($this->getSessionHelper()->getResponseHeaders());
- }
-
- /**
- * @Then the response header :name should be :value
- */
- public function theResponseHeaderShouldBe($name, $value): void
- {
- $this->theHeaderShouldExists($name);
-
- $header = $this->getSessionHelper()->getResponseHeader($name);
-
- Assert::assertSame(
- $value,
- $header,
- sprintf('The header "%s" is equal to "%s"', $name, $header)
- );
- }
-
- /**
- * @Then the response header :name should exists
- */
- public function theHeaderShouldExists($name): void
- {
- if (!$this->getSessionHelper()->hasResponseHeader($name)) {
- throw new RuntimeException(sprintf('The header "%s" does not exists', $name));
- }
- }
-
- /**
- * @Then the response status code should be :expectedResponseCode
- */
- public function theResponseStatusCodeShouldBe($expectedResponseCode): void
- {
- Assert::assertSame((int) $expectedResponseCode, $this->minkSession->getStatusCode());
- }
-
- private function getSessionResponseHelper(): MinkSessionResponseHelper
- {
- return $this->sessionResponseHelper = $this->sessionResponseHelper ?: new MinkSessionResponseHelper(
- $this->getSessionHelper()
- );
- }
-
- private function getSessionHelper(): MinkHelper
- {
- return $this->sessionHelper = $this->sessionHelper ?: new MinkHelper($this->minkSession);
- }
-
- private function adaptExpected($expectedResponse)
- {
- return $this->convertRelativeDates($expectedResponse);
- }
-
- private function convertRelativeDates($expectedResponse)
- {
- if (preg_match_all('/\#date (?[^\#]+)\#/', $expectedResponse, $matches)) {
- foreach ($matches['dates'] as $date) {
- $expectedResponse = str_replace(
- sprintf('#date %s#', $date),
- date_to_string(new DateTimeImmutable($date)),
- $expectedResponse
- );
- }
- }
-
- return $expectedResponse;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Behat/ApiFeatureContext.php b/tests/src/Shared/Infrastructure/Behat/ApiFeatureContext.php
deleted file mode 100644
index d034f24e6..000000000
--- a/tests/src/Shared/Infrastructure/Behat/ApiFeatureContext.php
+++ /dev/null
@@ -1,48 +0,0 @@
-connections = $connections;
- $this->publisher = $publisher;
- $this->bus = $bus;
- }
-
- /** @BeforeScenario */
- public function cleanEnvironment(): void
- {
- $this->connections->clear();
- $this->connections->truncate();
- }
-
- /** @AfterStep */
- public function publishEvents(): void
- {
- $publisher = function (DomainEvent $event) {
- $this->bus->notify($event);
- };
-
- while ($this->publisher->hasEventsToPublish()) {
- each($publisher, $this->publisher->popPublishedEvents());
- }
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Command/CommandBusSyncWithMiddlewaresTest.php b/tests/src/Shared/Infrastructure/Bus/Command/CommandBusSyncWithMiddlewaresTest.php
deleted file mode 100644
index a1e2e6f24..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Command/CommandBusSyncWithMiddlewaresTest.php
+++ /dev/null
@@ -1,82 +0,0 @@
-markTestSkipped('Temporally middlewares are disabled');
-
- $this->commandBus = new SymfonySyncCommandBus(new MessageLoggerMiddleware($this->logger()));
- }
-
- /** @test */
- public function it_should_be_able_to_handle_a_command_with_middlewares(): void
- {
- $this->commandBus->register(get_class($this->command()), $this->commandHandler());
-
- $this->shouldCheckCommandMessageType();
- $this->shouldLog();
- $this->commandHandlerShouldBeCalled();
-
- $this->commandBus->dispatch($this->command());
- }
-
- /** @return LoggerInterface|MockInterface */
- protected function logger()
- {
- return $this->logger = $this->logger ?: $this->mock(LoggerInterface::class);
- }
-
- protected function shouldLog(): void
- {
- $this->logger()->shouldReceive('debug')->once()->andReturnNull();
- }
-
- private function commandHandler(): callable
- {
- return function ($command) {
- $command->name();
- };
- }
-
- /** @return Command|MockInterface */
- private function command()
- {
- return $this->command = $this->command ?: $this->mock(Command::class);
- }
-
- private function commandHandlerShouldBeCalled(): void
- {
- $this->command()
- ->shouldReceive('name')
- ->once()
- ->withNoArgs();
- }
-
- private function shouldCheckCommandMessageType(): void
- {
- $this->command()
- ->shouldReceive('messageType')
- ->once()
- ->withNoArgs()
- ->andReturn('command');
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Command/FakeCommand.php b/tests/src/Shared/Infrastructure/Bus/Command/FakeCommand.php
deleted file mode 100644
index 4cba23dfe..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Command/FakeCommand.php
+++ /dev/null
@@ -1,11 +0,0 @@
-commandBus = new SymfonySyncCommandBus([$this->commandHandler()]);
- }
-
- /**
- * @test
- * @expectedException RuntimeException
- */
- public function it_should_be_able_to_handle_a_command(): void
- {
- $this->commandBus->dispatch(new FakeCommand(Uuid::random()));
- }
-
- /** @test */
- public function it_should_raise_an_exception_dispatching_a_non_registered_command(): void
- {
- $this->expectException(CommandNotRegisteredError::class);
-
- $this->commandBus->dispatch($this->mock(Command::class));
- }
-
- private function commandHandler()
- {
- return new class
- {
- public function __invoke(FakeCommand $command)
- {
- throw new RuntimeException('This works fine!');
- }
- };
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Event/ConstructionTestDomainEvent.php b/tests/src/Shared/Infrastructure/Bus/Event/ConstructionTestDomainEvent.php
deleted file mode 100644
index 504283037..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Event/ConstructionTestDomainEvent.php
+++ /dev/null
@@ -1,25 +0,0 @@
- ['string'],
- ];
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Event/DomainEventTest.php b/tests/src/Shared/Infrastructure/Bus/Event/DomainEventTest.php
deleted file mode 100644
index 7b7cf8262..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Event/DomainEventTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
- $someIdentifier]);
-
- $this->assertEquals($aggregateId, $event->aggregateId());
- $this->assertEquals($someIdentifier, $event->someIdentifier());
- }
-
- /** @test */
- public function it_should_not_throw_an_exception_constructing_an_event_with_more_parameters_than_defined(): void
- {
- $aggregateId = UuidMother::random();
- $someIdentifier = UuidMother::random();
- $nonDeclaredParameter = WordMother::random();
-
- $event = new ConstructionTestDomainEvent(
- $aggregateId,
- [
- 'someIdentifier' => $someIdentifier,
- 'nonDeclaredParameter' => $nonDeclaredParameter,
- ]
- );
-
- $this->assertEquals($aggregateId, $event->aggregateId());
- $this->assertEquals($someIdentifier, $event->someIdentifier());
- $this->assertEquals($nonDeclaredParameter, $event->nonDeclaredParameter());
- }
-
- /** @test */
- public function it_should_throw_an_exception_constructing_an_event_without_a_required_parameter(): void
- {
- $this->expectException(DomainException::class);
-
- new ConstructionTestDomainEvent(UuidMother::random(), []);
- }
-
- /** @test */
- public function it_should_throw_an_exception_constructing_an_event_having_a_parameter_with_an_incorrect_type(): void
- {
- $this->expectException(DomainException::class);
-
- new ConstructionTestDomainEvent(UuidMother::random(), ['someIdentifier' => ['this is an array']]);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Event/FakeDomainEvent.php b/tests/src/Shared/Infrastructure/Bus/Event/FakeDomainEvent.php
deleted file mode 100644
index e6d4ec6ca..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Event/FakeDomainEvent.php
+++ /dev/null
@@ -1,20 +0,0 @@
-bus = new SymfonySyncEventBus(
- [
- $this->subscriber(),
- $this->subscriber(),
- ]
- );
- }
-
- /** @test */
- public function it_should_publish_and_handle_one_event(): void
- {
- $this->bus->notify(new FakeDomainEvent('aggregate id'));
-
- $this->assertEquals(2, self::$totalTimesCalled);
- }
-
- private function subscriber()
- {
- return new class() implements DomainEventSubscriber
- {
- public function __invoke(DomainEvent $unused)
- {
- SymfonySyncEventBusTest::$totalTimesCalled++;
- }
-
- public static function subscribedTo(): array
- {
- return [FakeDomainEvent::class];
- }
- };
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Query/FakeQuery.php b/tests/src/Shared/Infrastructure/Bus/Query/FakeQuery.php
deleted file mode 100644
index 4cb352774..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Query/FakeQuery.php
+++ /dev/null
@@ -1,11 +0,0 @@
-number = $number;
- }
-
- public function number(): int
- {
- return $this->number;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBusTest.php b/tests/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBusTest.php
deleted file mode 100644
index 389e3ad43..000000000
--- a/tests/src/Shared/Infrastructure/Bus/Query/SymfonySyncQueryBusTest.php
+++ /dev/null
@@ -1,52 +0,0 @@
-queryBus = new SymfonySyncQueryBus([$this->queryHandler()]);
- }
-
- /**
- * @test
- * @expectedException RuntimeException
- */
- public function it_should_return_a_response_successfully(): void
- {
- $this->queryBus->ask(new FakeQuery());
- }
-
- /** @test */
- public function it_should_raise_an_exception_dispatching_a_non_registered_query(): void
- {
- $this->expectException(QueryNotRegisteredError::class);
-
- $this->queryBus->ask($this->mock(Query::class));
- }
-
- private function queryHandler()
- {
- return new class
- {
- public function __invoke(FakeQuery $query)
- {
- throw new RuntimeException('This works fine!');
- }
- };
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Mink/MinkHelper.php b/tests/src/Shared/Infrastructure/Mink/MinkHelper.php
deleted file mode 100644
index d03929f8d..000000000
--- a/tests/src/Shared/Infrastructure/Mink/MinkHelper.php
+++ /dev/null
@@ -1,165 +0,0 @@
-session = $session;
- }
-
- public function setRequestHeader($header, $value): void
- {
- $this->getClient()->setServerParameter($header, $value);
- }
-
- public function addRequestHttpBasicAuthentication($username, $password): void
- {
- $this->getClient()->setServerParameter('PHP_AUTH_USER', $username);
- $this->getClient()->setServerParameter('PHP_AUTH_PW', $password);
- }
-
- public function sendRequest($method, $url, array $optionalParams = []): Crawler
- {
- $defaultOptionalParams = [
- 'parameters' => [],
- 'files' => [],
- 'server' => ['HTTP_ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json'],
- 'content' => null,
- 'changeHistory' => true,
- ];
-
- $optionalParams = array_merge($defaultOptionalParams, $optionalParams);
-
- $crawler = $this->getClient()->request(
- $method,
- $url,
- $optionalParams['parameters'],
- $optionalParams['files'],
- $optionalParams['server'],
- $optionalParams['content'],
- $optionalParams['changeHistory']
- );
-
- $this->resetRequestStuff();
-
- return $crawler;
- }
-
- public function getRequestHeaders(): array
- {
- return $this->normalizeHeaders($this->getRequest()->headers->all());
- }
-
- public function getResponse(): string
- {
- return $this->getSession()->getPage()->getContent();
- }
-
- public function getResponseHeaders(): array
- {
- return $this->normalizeHeaders(
- array_change_key_case($this->getSession()->getResponseHeaders(), CASE_LOWER)
- );
- }
-
- public function responseShouldContain($needle): void
- {
- if (strpos($this->clearString($this->getResponse()), $this->clearString($needle)) === false) {
- throw new RuntimeException(sprintf('The response do not contain %s', $needle));
- }
- }
-
- public function responseShouldNotContain($needle): void
- {
- if (strpos($this->clearString($this->getResponse()), $this->clearString($needle)) === true) {
- throw new RuntimeException(sprintf('The response do not contain %s', $needle));
- }
- }
-
- public function hasResponseHeader($name): bool
- {
- return array_key_exists($name, $this->getResponseHeaders());
- }
-
- public function getResponseHeader($name)
- {
- return get_in([$name], $this->getResponseHeaders());
- }
-
- public function hasResponseParameter($name): bool
- {
- return array_key_exists($name, $this->getResponseParameters());
- }
-
- public function getResponseParameter($name)
- {
- return get_in([$name], $this->getResponseParameters());
- }
-
- public function resetServerParameters(): void
- {
- $this->getClient()->setServerParameters([]);
- }
-
- public function getNodeElementByXpath($query)
- {
- return $this->getSession()->getPage()->find('xpath', $query);
- }
-
- public function getRequest(): Request
- {
- return $this->getClient()->getRequest();
- }
-
- private function getSession(): Session
- {
- return $this->session;
- }
-
- private function getDriver(): DriverInterface
- {
- return $this->getSession()->getDriver();
- }
-
- private function getClient(): Client
- {
- return $this->getDriver()->getClient();
- }
-
- /** FIXME: The content can be different than json, check the content-type header */
- private function getResponseParameters()
- {
- return json_decode($this->getSession()->getPage()->getContent(), true);
- }
-
- private function normalizeHeaders(array $headers): array
- {
- return array_map('implode', array_filter($headers));
- }
-
- private function resetRequestStuff(): void
- {
- $this->getSession()->reset();
- $this->resetServerParameters();
- }
-
- private function clearString($string)
- {
- return preg_replace('/\s+/S', ' ', $string);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php b/tests/src/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php
deleted file mode 100644
index 870da6717..000000000
--- a/tests/src/Shared/Infrastructure/Mink/MinkSessionRequestHelper.php
+++ /dev/null
@@ -1,58 +0,0 @@
-sessionHelper = $sessionHelper;
- }
-
- public function sendRequest($method, $url, array $optionalParams = []): void
- {
- $this->request($method, $url, $optionalParams);
- }
-
- /**
- * @todo : Fix parameters from hash, now is a simple solution
- */
- public function sendRequestWithTableNode($method, $url, TableNode $parameters): void
- {
- $this->request($method, $url, ['parameters' => $parameters->getRowsHash()]);
- }
-
- public function sendRequestWithPyStringNode($method, $url, PyStringNode $body): void
- {
- $this->request($method, $url, ['content' => $body->getRaw()]);
- }
-
- public function addHeaderEqualTo($name, $value): void
- {
- $this->sessionHelper->setRequestHeader($name, $value);
- }
-
- public function printRequestHeaders(): void
- {
- print_r($this->sessionHelper->getRequestHeaders());
- }
-
- public function request($method, $url, array $optionalParams = []): Crawler
- {
- return $this->sessionHelper->sendRequest($method, $url, $optionalParams);
- }
-
- public function addHttpBasicAuthentication($username, $password): void
- {
- $this->sessionHelper->addRequestHttpBasicAuthentication($username, $password);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Mink/MinkSessionResponseHelper.php b/tests/src/Shared/Infrastructure/Mink/MinkSessionResponseHelper.php
deleted file mode 100644
index dfca129b6..000000000
--- a/tests/src/Shared/Infrastructure/Mink/MinkSessionResponseHelper.php
+++ /dev/null
@@ -1,21 +0,0 @@
-sessionHelper = $sessionHelper;
- }
-
- public function getResponse(): string
- {
- return $this->sessionHelper->getResponse();
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsEqual.php b/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsEqual.php
deleted file mode 100644
index e99bbe7df..000000000
--- a/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsEqual.php
+++ /dev/null
@@ -1,35 +0,0 @@
-constraint = new CodelyTvConstraintIsEqual($value, $delta, $maxDepth, $canonicalize, $ignoreCase);
- }
-
- public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
- {
- return new static($value, $delta, $maxDepth, $canonicalize, $ignoreCase);
- }
-
- public function match(&$actual)
- {
- return $this->constraint->evaluate($actual, '', true);
- }
-
- public function __toString()
- {
- return 'Is equal';
- }
-}
diff --git a/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php b/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php
deleted file mode 100644
index 18dee5747..000000000
--- a/tests/src/Shared/Infrastructure/Mockery/CodelyTvMatcherIsSimilar.php
+++ /dev/null
@@ -1,41 +0,0 @@
-constraint = new CodelyTvConstraintIsSimilar(
- $value,
- $delta,
- $maxDepth,
- $canonicalize,
- $ignoreCase
- );
- }
-
- public static function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
- {
- return new static($value, $delta, $maxDepth, $canonicalize, $ignoreCase);
- }
-
- public function match(&$actual)
- {
- return $this->constraint->evaluate($actual, '', true);
- }
-
- public function __toString()
- {
- return 'Is similar';
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootArraySimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootArraySimilarComparator.php
deleted file mode 100644
index 17ebec188..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootArraySimilarComparator.php
+++ /dev/null
@@ -1,52 +0,0 @@
-contains($expected, $actual) || count($expected) !== count($actual)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->exporter->export($expected),
- $this->exporter->export($actual),
- false,
- 'Failed asserting the collection of AGs contains all the expected elements.'
- );
- }
- }
-
- private function contains(array $expectedArray, array $actualArray): bool
- {
- $exists = function (AggregateRoot $expected) use ($actualArray) {
- return any(
- function (AggregateRoot $actual) use ($expected) {
- return isSimilar($expected, $actual);
- },
- $actualArray
- );
- };
-
- return all($exists, $expectedArray);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootSimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootSimilarComparator.php
deleted file mode 100644
index ea9b8af85..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/AggregateRootSimilarComparator.php
+++ /dev/null
@@ -1,90 +0,0 @@
-pullDomainEvents();
-
- if (!$this->aggregateRootsAreSimilar($expected, $actualEntity)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->exporter->export($expected),
- $this->exporter->export($actual),
- false,
- 'Failed asserting the aggregate roots are equal.'
- );
- }
- }
-
- /**
- * @param AggregateRoot $expected
- * @param AggregateRoot $actual
- */
- private function aggregateRootsAreSimilar($expected, $actual): bool
- {
- if (!$this->aggregateRootsAreTheSameClass($expected, $actual)) {
- return false;
- }
-
- return $this->aggregateRootPropertiesAreSimilar($expected, $actual);
- }
-
- /**
- * @param AggregateRoot $expected
- * @param AggregateRoot $actual
- */
- private function aggregateRootsAreTheSameClass($expected, $actual): bool
- {
- return get_class($expected) === get_class($actual);
- }
-
- /**
- * @param AggregateRoot $expected
- * @param AggregateRoot $actual
- */
- private function aggregateRootPropertiesAreSimilar($expected, $actual): bool
- {
- $expectedReflected = new ReflectionObject($expected);
- $actualReflected = new ReflectionObject($actual);
-
- foreach ($expectedReflected->getProperties() as $expectedReflectedProperty) {
- $actualReflectedProperty = $actualReflected->getProperty($expectedReflectedProperty->getName());
-
- $expectedReflectedProperty->setAccessible(true);
- $actualReflectedProperty->setAccessible(true);
-
- $expectedProperty = $expectedReflectedProperty->getValue($expected);
- $actualProperty = $actualReflectedProperty->getValue($actual);
-
- if (!isSimilar($expectedProperty, $actualProperty)) {
- return false;
- }
- }
-
- return true;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeSimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeSimilarComparator.php
deleted file mode 100644
index 305867def..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeSimilarComparator.php
+++ /dev/null
@@ -1,50 +0,0 @@
-sub($intervalWithDelta) || $actual > $expectedUpper->add($intervalWithDelta)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->dateTimeToString($expected),
- $this->dateTimeToString($actual),
- false,
- 'Failed asserting that two DateTime objects are equal.'
- );
- }
- }
-
- protected function dateTimeToString(DateTimeInterface $datetime): string
- {
- return $datetime->format(DateTime::ATOM) ?: 'Invalid DateTime object';
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeStringSimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeStringSimilarComparator.php
deleted file mode 100644
index e25f35a9c..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DateTimeStringSimilarComparator.php
+++ /dev/null
@@ -1,72 +0,0 @@
-isValidDateTimeString($expected) &&
- $this->isValidDateTimeString($actual);
- }
-
- private function isValidDateTimeString($expected): bool
- {
- $isValid = true;
-
- try {
- new DateTimeImmutable($expected);
- } catch (Throwable $throwable) {
- $isValid = false;
- }
-
- return $isValid;
- }
-
- public function assertEquals(
- $expected,
- $actual,
- $delta = 0.0,
- $canonicalize = false,
- $ignoreCase = false,
- array &$processed = []
- ): void {
- $expectedDate = new DateTimeImmutable($expected);
- $actualDate = new DateTimeImmutable($actual);
-
- $normalizedDelta = $delta === 0.0 ? 10 : $delta;
- $intervalWithDelta = new DateInterval(sprintf('PT%sS', abs($normalizedDelta)));
-
- if ($actualDate < $expectedDate->sub($intervalWithDelta) ||
- $actualDate > $expectedDate->add($intervalWithDelta)) {
- throw new ComparisonFailure(
- $expectedDate,
- $actualDate,
- $this->dateTimeToString($expectedDate),
- $this->dateTimeToString($actualDate),
- false,
- 'Failed asserting that two DateTime strings are equal.'
- );
- }
- }
-
- protected function dateTimeToString(DateTimeInterface $datetime): string
- {
- $string = $datetime->format(DateTime::ATOM);
-
- return $string ?: 'Invalid DateTime object';
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventArraySimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventArraySimilarComparator.php
deleted file mode 100644
index 66eed2c1a..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventArraySimilarComparator.php
+++ /dev/null
@@ -1,52 +0,0 @@
-contains($expected, $actual) || count($expected) !== count($actual)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->exporter->export($expected),
- $this->exporter->export($actual),
- false,
- 'Failed asserting the collection of Events contains all the expected elements.'
- );
- }
- }
-
- private function contains(array $expectedArray, array $actualArray): bool
- {
- $exists = function (DomainEvent $expected) use ($actualArray) {
- return any(
- function (DomainEvent $actual) use ($expected) {
- return isSimilar($expected, $actual);
- },
- $actualArray
- );
- };
-
- return all($exists, $expectedArray);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventSimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventSimilarComparator.php
deleted file mode 100644
index 16773751c..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/DomainEventSimilarComparator.php
+++ /dev/null
@@ -1,91 +0,0 @@
-areSimilar($expected, $actual)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->exporter->export($expected),
- $this->exporter->export($actual),
- false,
- 'Failed asserting the events are equal.'
- );
- }
- }
-
- /**
- * @param DomainEvent $expected
- * @param DomainEvent $actual
- */
- private function areSimilar($expected, $actual): bool
- {
- if (!$this->areTheSameClass($expected, $actual)) {
- return false;
- }
-
- return $this->propertiesAreSimilar($expected, $actual);
- }
-
- /**
- * @param DomainEvent $expected
- * @param DomainEvent $actual
- */
- private function areTheSameClass($expected, $actual): bool
- {
- return get_class($expected) === get_class($actual);
- }
-
- /**
- * @param DomainEvent $expected
- * @param DomainEvent $actual
- */
- private function propertiesAreSimilar($expected, $actual): bool
- {
- $expectedReflected = new ReflectionObject($expected);
- $actualReflected = new ReflectionObject($actual);
-
- foreach ($expectedReflected->getProperties() as $expectedReflectedProperty) {
- if (!in_array($expectedReflectedProperty->getName(), self::$ignoredAttributes, false)) {
- $actualReflectedProperty = $actualReflected->getProperty($expectedReflectedProperty->getName());
-
- $expectedReflectedProperty->setAccessible(true);
- $actualReflectedProperty->setAccessible(true);
-
- $expectedProperty = $expectedReflectedProperty->getValue($expected);
- $actualProperty = $actualReflectedProperty->getValue($actual);
-
- if (!isSimilar($expectedProperty, $actualProperty)) {
- return false;
- }
- }
- }
-
- return true;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/StringableObjectSimilarComparator.php b/tests/src/Shared/Infrastructure/PHPUnit/Comparator/StringableObjectSimilarComparator.php
deleted file mode 100644
index e9f96677f..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Comparator/StringableObjectSimilarComparator.php
+++ /dev/null
@@ -1,36 +0,0 @@
-isStringable($expected) && !is_object($actual)) ||
- ($this->isStringable($actual) && !is_object($expected));
- }
-
- public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false): void
- {
- if (gettype($expected) !== gettype($actual)) {
- throw new ComparisonFailure(
- $expected,
- $actual,
- $this->exporter->export($expected),
- $this->exporter->export($actual),
- false,
- 'Failed asserting that stringable objects are similar.'
- );
- }
- }
-
- private function isStringable($possibleStringable): bool
- {
- return is_object($possibleStringable) && method_exists($possibleStringable, '__toString');
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsEqual.php b/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsEqual.php
deleted file mode 100644
index a25000717..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsEqual.php
+++ /dev/null
@@ -1,39 +0,0 @@
-register(new StringableObjectSimilarComparator());
-
- try {
- $comparator = $comparatorFactory->getComparatorFor($other, $this->value);
-
- $comparator->assertEquals($this->value, $other, $this->delta);
- } catch (ComparisonFailure $f) {
- if (!$returnResult) {
- throw new ExpectationFailedException(
- trim($description . "\n" . $f->getMessage()),
- $f
- );
- }
-
- $isValid = false;
- }
-
- return $isValid;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsSimilar.php b/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsSimilar.php
deleted file mode 100644
index c59bf14b9..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Constraint/CodelyTvConstraintIsSimilar.php
+++ /dev/null
@@ -1,51 +0,0 @@
-register(new AggregateRootArraySimilarComparator());
- $comparatorFactory->register(new AggregateRootSimilarComparator());
- $comparatorFactory->register(new DomainEventArraySimilarComparator());
- $comparatorFactory->register(new DomainEventSimilarComparator());
- $comparatorFactory->register(new DateTimeSimilarComparator());
- $comparatorFactory->register(new DateTimeStringSimilarComparator());
- $comparatorFactory->register(new StringableObjectSimilarComparator());
-
- try {
- $comparator = $comparatorFactory->getComparatorFor($other, $this->value);
-
- $comparator->assertEquals($this->value, $other, $this->delta);
- } catch (ComparisonFailure $f) {
- if (!$returnResult) {
- throw new ExpectationFailedException(
- trim($description . "\n" . $f->getMessage()),
- $f
- );
- }
-
- $isValid = false;
- }
-
- return $isValid;
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/FunctionalTestCase.php b/tests/src/Shared/Infrastructure/PHPUnit/FunctionalTestCase.php
deleted file mode 100644
index a29ff7c32..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/FunctionalTestCase.php
+++ /dev/null
@@ -1,27 +0,0 @@
- 'test']);
-
- parent::setUp();
- }
-
- protected function service($id)
- {
- return self::$container->get($id);
- }
-
- protected function parameter($parameter)
- {
- return self::$container->getParameter($parameter);
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleFunctionalTestCase.php b/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleFunctionalTestCase.php
deleted file mode 100644
index ef3fe1690..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleFunctionalTestCase.php
+++ /dev/null
@@ -1,62 +0,0 @@
-arrange();
- },
- $this->environmentArrangers()
- );
- }
-
- protected function tearDown()
- {
- each(
- function (EnvironmentArranger $arranger) {
- $arranger->close();
- },
- $this->environmentArrangers()
- );
-
- parent::tearDown();
- }
-
- protected function clearUnitOfWork(): void
- {
- $this->service(EntityManager::class)->clear();
- }
-
- protected function notify(DomainEvent $event): void
- {
- $this->assertNull($this->domainEventPublisher()->publish($event));
- }
-
- protected function assertSimilar($expected, $actual): void
- {
- assertSimilar($expected, $actual);
- }
-
- private function domainEventPublisher(): DomainEventPublisher
- {
- return $this->service('codely.infrastructure.domain_event_publisher');
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleUnitTestCase.php b/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleUnitTestCase.php
deleted file mode 100644
index 276d7e043..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/Module/ModuleUnitTestCase.php
+++ /dev/null
@@ -1,148 +0,0 @@
-queryBus = $this->queryBus ?: $this->mock(QueryBus::class);
- }
-
- /** @return DomainEventPublisher|MockInterface */
- protected function domainEventPublisher()
- {
- return $this->domainEventPublisher = $this->domainEventPublisher ?: $this->mock(DomainEventPublisher::class);
- }
-
- /** @return CommandBus|MockInterface */
- protected function commandBus()
- {
- return $this->commandBus = $this->commandBus ?: $this->mock(CommandBus::class);
- }
-
- /** @return LoggerInterface|MockInterface */
- protected function logger()
- {
- return $this->logger = $this->logger ?: $this->mock(LoggerInterface::class);
- }
-
- protected function assertAskResponse(Query $query, Response $response, callable $handler): void
- {
- $this->assertEquals($response, $this->ask($query, $handler), 'QueryBus did not returned the expected response');
- }
-
- protected function assertAskNullResponse(Query $query, callable $handler): void
- {
- $this->assertNull($this->ask($query, $handler), 'QueryBus did not returned the expected response');
- }
-
- protected function assertAskThrowsException($exceptionClass, Query $query, callable $handler): void
- {
- $this->expectException($exceptionClass);
-
- $this->ask($query, $handler);
- }
-
- protected function shouldAsk(Query $query, Response $response = null): void
- {
- $this->queryBus()
- ->shouldReceive('ask')
- ->once()
- ->with(similarTo($query))
- ->andReturn($response);
- }
-
- protected function shouldAskThrowingException(Query $query, $exception): void
- {
- $this->queryBus()
- ->shouldReceive('ask')
- ->once()
- ->with(equalTo($query))
- ->andThrow($exception);
- }
-
- protected function notify(DomainEvent $event, callable $subscriber): void
- {
- $subscriber($event);
- }
-
- protected function shouldNotifyThrowingException(
- DomainEvent $event,
- callable $subscriber,
- string $exceptionClass
- ): void {
- $this->expectException($exceptionClass);
-
- $this->notify($event, $subscriber);
- }
-
- protected function dispatch(Command $command, callable $handler): void
- {
- $handler($command);
- }
-
- /** @param DomainEvent[] $events */
- protected function shouldPublishDomainEvents(DomainEvent ...$events): void
- {
- $this->domainEventPublisher()
- ->shouldReceive('publish')
- ->once()
- ->with(...map($this->addSimilarTo(), $events))
- ->andReturnNull();
- }
-
- protected function shouldNotPublishDomainEvents(): void
- {
- $this->domainEventPublisher()
- ->shouldNotReceive('publish');
- }
-
- protected function shouldLog($level): void
- {
- $this->logger()->shouldReceive($level)->once()->andReturnNull();
- }
-
- protected function shouldLogMessage($level, $message, array $context = []): void
- {
- $this->logger()
- ->shouldReceive($level)
- ->once()
- ->with($message, $context)
- ->andReturnNull();
- }
-
- private function ask(Query $query, callable $handler)
- {
- return $handler($query);
- }
-
- private function addSimilarTo(): callable
- {
- return function (DomainEvent $event) {
- return similarTo($event);
- };
- }
-}
diff --git a/tests/src/Shared/Infrastructure/PHPUnit/UnitTestCase.php b/tests/src/Shared/Infrastructure/PHPUnit/UnitTestCase.php
deleted file mode 100644
index 865658581..000000000
--- a/tests/src/Shared/Infrastructure/PHPUnit/UnitTestCase.php
+++ /dev/null
@@ -1,22 +0,0 @@
-assertSame($expected, date_to_string($date));
- }
-
- /**
- * @test
- * @dataProvider validDatesConversions
- */
- public function it_should_convert_a_date_from_milliseconds(DateTimeImmutable $expected, string $stringDate): void
- {
- $this->assertEquals($expected, string_to_date($stringDate));
- }
-
- public function validDatesConversions(): array
- {
- return [
- [
- 'date' => DateTimeMother::create('1993-06-26 10:00:00 GMT+0200'),
- 'string' => '741081600000',
- ],
- [
- 'date' => DateTimeMother::create('1994-09-29 15:00:00 GMT+0200'),
- 'string' => '780843600000',
- ],
-
- [
- 'date' => DateTimeMother::create('2020-01-15 22:23:24 GMT+0500'),
- 'string' => '1579109004000',
- ],
- [
- 'date' => DateTimeMother::create('2016-10-03 12:41:32.980000', DateTimeZoneMother::UTC()),
- 'string' => '1475498492980',
- ],
- ];
- }
-}
diff --git a/tests/src/Shared/utils.php b/tests/src/Shared/utils.php
deleted file mode 100644
index 31e6affec..000000000
--- a/tests/src/Shared/utils.php
+++ /dev/null
@@ -1,63 +0,0 @@
-evaluate($value, '', true);
-}
-
-function assertSimilar(
- $expected,
- $actual,
- $message = '',
- $delta = 0.0,
- $maxDepth = 10,
- $canonicalize = false,
- $ignoreCase = false
-) {
- $constraint = new CodelyTvConstraintIsSimilar($expected, $delta, $maxDepth, $canonicalize, $ignoreCase);
-
- Assert::assertThat($actual, $constraint, $message);
-}
-
-function similarTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
-{
- return CodelyTvMatcherIsSimilar::equalTo($value, $delta, $maxDepth, $canonicalize, $ignoreCase);
-}
-
-function isEqual($expected, $value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
-{
- $constraint = new CodelyTvConstraintIsEqual($expected, $delta, $maxDepth, $canonicalize, $ignoreCase);
-
- return $constraint->evaluate($value, '', true);
-}
-
-function assertEquals(
- $expected,
- $actual,
- $message = '',
- $delta = 0.0,
- $maxDepth = 10,
- $canonicalize = false,
- $ignoreCase = false
-) {
- $constraint = new CodelyTvConstraintIsEqual($expected, $delta, $maxDepth, $canonicalize, $ignoreCase);
-
- Assert::assertThat($actual, $constraint, $message);
-}
-
-function equalTo($value, $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false)
-{
- return CodelyTvMatcherIsEqual::equalTo($value, $delta, $maxDepth, $canonicalize, $ignoreCase);
-}