diff --git a/.php_cs.dist.php b/.php_cs.dist.php
index 4ad5af914..843d215ff 100644
--- a/.php_cs.dist.php
+++ b/.php_cs.dist.php
@@ -1,7 +1,7 @@
`_ to be run. As a developer, use `docker-compose `_ to bootstrap a dev environment in a glance. You do not need any other dependencies ;
- Make is used to automate scripts.
-Installation in development mode
-********************************
+Installation
+************
+
+If you plan to run chill in production:
+
+1. install it locally first, and check if everything is ok on your local machine;
+2. once ready, build the image from your local machine, and deploy them.
+
+If you want to develop some bundles, the first step is sufficient (until you deploy on production).
+
1. Get the code
===============
-Clone or download the chill-app project and `cd` into the main directory.
+Clone or download the chill-skeleton project and `cd` into the main directory.
.. code-block:: bash
- git clone https://gitlab.com/Chill-Projet/chill-app.git
+ git clone https://gitlab.com/Chill-Projet/chill-skeleton-basic.git
cd chill-app
As a developer, the code will stay on your computer and will be executed in docker container. To avoid permission problem, the code should be run with the same uid/gid from your current user. This is why we get your current user id with the command ``id -u`` in each following scripts.
-2. Prepare composer download of sources
-=======================================
+2. Prepare composer to download the sources
+===========================================
-As you are running in dev, you must configure an auth token for getting the source code.
+As you are running in dev, you must configure an auth token for getting the source code.
.. warning
If you skip this part, the code will be downloaded from dist instead of source (with git repository). You will probably replace the source manually, but the next time you will run ```composer update```, your repository will be replaced and you might loose something.
1. Create a personal access token from https://gitlab.com/-/profile/personal_access_tokens, with the `read_api` scope.
-2. add a file called ```.composer/auth.json```:
+2. add a file called ```.composer/auth.json``` with this content:
.. code-block:: json
@@ -68,13 +76,25 @@ As you are running in dev, you must configure an auth token for getting the sour
2. Prepare your variables and environment
=========================================
-Copy ```docker-compose.override.dev.yml``` into ```docker-compose.override.yml```
+Copy ```docker-compose.override.dev.yml``` into ```docker-compose.override.yml```
.. code-block:: bash
cp docker-compose.override.dev.template.yml docker-compose.override.yml
-Configure your environment variables, by creating a .env.local file and override the desired variables.
+2. Prepare your variables and docker-compose
+============================================
+
+Have a look at the variable in ``.env`` and check if you need to adapt them. If they do not adapt with your need, or if some are missing:
+
+1. copy the file as ``.env.local``: ``cp .env .env.local``
+2. you may replace some variables inside ``.env``
+
+Prepare also you docker-compose installation, and adapt it to your needs:
+
+1. If you plan to deploy on dev, copy the file ``docker-compose.override.dev.template.yml`` to ``docker-compose.override.yml``.
+2. adapt to your needs.
+
**Note**: If you intend to use the bundle ``Chill-Doc-Store``, you will need to configure and install an openstack object storage container with temporary url middleware. You will have to configure `secret keys `_.
@@ -90,10 +110,21 @@ This script can be run using `make`
This script will :
1. force docker-compose to, eventually, pull the base images and build the image used by this project ;
-2. run an install script to download `composer `_ ;
+2. run an install script to download `composer `_ ;
3. install the php dependencies
4. build assets
+.. warning::
+
+ The script will work only if the binary ``docker-compose`` is located into your ``PATH``. If you use ``compose`` as a docker plugin,
+ you can simulate this binary by creating this file at (for instance), ``/usr/local/bin/docker-compose`` (and run ``chmod +x /usr/local/bin/docker-compose``):
+
+ .. code-block:: bash
+
+ #!/bin/bash
+
+ /usr/bin/docker compose "$@"
+
.. note::
@@ -117,13 +148,20 @@ This script will :
.. code-block:: bash
- make migrate
+ # mount into to container
+ ./docker-php.sh
+ # and load fixtures
+ bin/console doctrine:migrations:migrate
+
Chill will be available at ``http://localhost:8001.`` Currently, there isn't any user or data. To add fixtures, run
.. code-block:: bash
- docker-compose exec --user $(id -u) php bin/console doctrine:fixtures:load --purge-with-truncate
+ # mount into to container
+ ./docker-php.sh
+ # and load fixtures
+ bin/console doctrine:fixtures:load --purge-with-truncate
There are several users available:
@@ -134,28 +172,6 @@ The password is always ``password``.
Now, read `Operations` below.
-Prepare for development
-***********************
-
-Add a Gitlab token to ensure that you get always the source code:
-
-1. generate a gitlab token there: https://gitlab.com/oauth/token
-2. run this command (in php container, at the app's root): :code:`composer config gitlab-token.gitlab.com `
-
-The auth token should appears now in the directory :code:`.composer`:
-
-.. code-block: bash
-
- $ cat .composer/auth.json
- {
- "gitlab-token": {
- "gitlab.com": ""
- }
- }
-
-
-See also "how to switch branch and get new dependencies".
-
Operations
**********
@@ -163,7 +179,7 @@ Operations
Build assets
============
-run those commands:
+run those commands:
.. code-block:: bash
@@ -175,8 +191,8 @@ How to execute the console ?
.. code-block:: bash
# if a container is running
- docker-compose exec --user $(id -u) php bin/console
- # if not
+ ./docker-php.sh
+ # if not
docker-compose run --user $(id -u) php bin/console
How to create the database schema (= run migrations) ?
@@ -185,8 +201,9 @@ How to create the database schema (= run migrations) ?
.. code-block:: bash
# if a container is running
- docker-compose exec --user $(id -u) php bin/console doctrine:migrations:migrate
- # if not
+ ./docker-php.sh
+ bin/console doctrine:migrations:migrate
+ # if not
docker-compose run --user $(id -u) php bin/console doctrine:migrations:migrate
@@ -203,8 +220,9 @@ How to load fixtures ? (development mode only)
.. code-block:: bash
# if a container is running
- docker-compose exec --user $(id -u) php bin/console doctrine:fixtures:load
- # if not
+ ./docker-php.sh
+ bin/console doctrine:fixtures:load
+ # if not
docker-compose run --user $(id -u) php bin/console doctrine:fixtures:load
How to open a terminal in the project
@@ -213,8 +231,8 @@ How to open a terminal in the project
.. code-block:: bash
# if a container is running
- docker-compose exec --user $(id -u) php /bin/bash
- # if not
+ ./docker-php.sh
+ # if not
docker-compose run --user $(id -u) php /bin/bash
How to run composer ?
@@ -223,21 +241,22 @@ How to run composer ?
.. code-block:: bash
# if a container is running
- docker-compose exec --user $(id -u) php ./composer.phar
- # if not
- docker-compose run --user $(id -u) php ./composer.phar
+ ./docker-php.sh
+ composer
+ # if not
+ docker-compose run --user $(id -u) php composer
How to access to PGADMIN ?
==========================
-Pgadmin is installed with docker-compose.
+Pgadmin is installed with docker-compose, and is available **only if you uncomment the appropriate lines into ``docker-compose.override.yml``.
You can access it at ``http://localhost:8002``.
Credentials:
-- login: admin@chill.social
-- password: password
+- login: from the variable you set into ``docker-composer.override.yml``
+- password: same :-)
How to run tests ?
==================
@@ -246,18 +265,20 @@ Tests reside inside the installed bundles. You must `cd` into that directory, do
**Note**: some bundle require the fixture to be executed. See the dedicated _how-tos_.
-Exemple, for running test inside `main` bundle:
+Exemple, for running test inside `main` bundle:
.. code-block:: bash
# mount into the php image
- docker-compose run --user $(id -u) php /bin/bash
+ ./docker-php.sh
# cd into main directory
- cd vendor/chill-project/main
+ cd vendor/chill-project/chill-bundles
# download deps
- php ../../../composer.phar install
+ git submodule init
+ git submodule update
+ composer install
# run tests
- /vendor/bin/phpunit
+ bin/phpunit src/Bundle/path/to/your/test
How to run webpack interactively
================================
@@ -269,10 +290,14 @@ How to switch the branch for chill-bundles, and get new dependencies
During development, you will switch to new branches for chill-bundles. As long as the dependencies are equals, this does not cause any problem. But sometimes, a new branch introduces a new dependency, and you must download it.
+.. warning::
+
+ Ensure that you have gitlab-token ready before updating your branches. See above.
+
In order to do that without pain, use those steps:
0. Ensuire you have a token, set
-1. at the app's root, update the `composer.json` to your current branch:
+1. at the app's root, update the ``composer.json`` to your current branch:
.. code-block:: json
@@ -281,14 +306,7 @@ In order to do that without pain, use those steps:
"chill-bundles": "dev-@dev"
}
-2. mount into the php container, and run `composer update`
-
-Build the documentation API
-===========================
-
-A basic configuration of `sami `_ is embedded within the project.
-
-A configuration file for `phpDocumentor `_ is present.
+2. mount into the php container (``./docker-php.sh``), and run ``composer update``
Error `An exception has been thrown during the rendering of a template ("Asset manifest file "/var/www/app/web/build/manifest.json" does not exist.").` on first run
====================================================================================================================================================================
@@ -302,8 +320,9 @@ Currently, to run this software in production, the *state of the art* is the fol
1. Run the software locally and tweak the configuration to your needs ;
2. Build the image and store them into a private container registry. This can be done using :code:`make build-and-push-image`.
-
- To be sure to target the correct container registry, you have to adapt the values ``IMAGE_NGINX`` and ``IMAGE_PHP`` date in the ``.env`` file.
+
+ To be sure to target the correct container registry, you have to adapt the image names into your ``docker-compose.override.yml`` file.
+3. Push the image on your registry, or upload them to the destination machine using ``docker image save`` and ``docker image load``.
3. Run the image on your production server, using docker-compose or eventually docker stack. You have to customize the variable set in docker-compose.
See also the :ref:`running-production-tips-and-tricks` below.
@@ -335,7 +354,7 @@ It is worth having an eye on the configuration of logstash container.
Design principles
*****************
-Why the DB URL is set in environment, and not in parameters.yml ?
+Why the DB URL is also set in environment, and not in .env file ?
=================================================================
Because, at startup, a script does check the db is up and, if not, wait for a couple of seconds before running ``entrypoint.sh``. For avoiding double configuration, the configuration of the PHP app takes his configuration from environment also (and it will be standard in future releases, with symfony 4.0).
diff --git a/phpstan-deprecations.neon b/phpstan-deprecations.neon
index 1f6ca4401..9a6d862b5 100644
--- a/phpstan-deprecations.neon
+++ b/phpstan-deprecations.neon
@@ -175,13 +175,6 @@ parameters:
count: 1
path: src/Bundle/ChillActivityBundle/Form/ActivityType.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillActivityBundle/Repository/ActivityACLAwareRepository.php
-
message: """
@@ -294,14 +287,6 @@ parameters:
count: 1
path: src/Bundle/ChillEventBundle/Form/Type/PickEventType.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillEventBundle/Search/EventSearch.php
-
-
message: """
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
@@ -390,13 +375,6 @@ parameters:
count: 1
path: src/Bundle/ChillMainBundle/Export/ExportInterface.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillMainBundle/Export/ExportManager.php
-
message: """
@@ -754,14 +732,6 @@ parameters:
count: 1
path: src/Bundle/ChillPersonBundle/Widget/PersonListWidget.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillReportBundle/Controller/ReportController.php
-
-
message: """
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
@@ -794,14 +764,6 @@ parameters:
count: 1
path: src/Bundle/ChillReportBundle/Export/Filter/ReportDateFilter.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillReportBundle/Form/ReportType.php
-
-
message: """
#^Parameter \\$role of method Chill\\\\ReportBundle\\\\Form\\\\ReportType\\:\\:appendScopeChoices\\(\\) has typehint with deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
@@ -810,14 +772,6 @@ parameters:
count: 1
path: src/Bundle/ChillReportBundle/Form/ReportType.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 1
- path: src/Bundle/ChillReportBundle/Search/ReportSearch.php
-
-
message: """
#^Instantiation of deprecated class Symfony\\\\Component\\\\Security\\\\Core\\\\Role\\\\Role\\:
@@ -826,13 +780,6 @@ parameters:
count: 1
path: src/Bundle/ChillReportBundle/Search/ReportSearch.php
- -
- message: """
- #^Call to deprecated method getReachableScopes\\(\\) of class Chill\\\\MainBundle\\\\Security\\\\Authorization\\\\AuthorizationHelper\\:
- Use getReachableCircles$#
- """
- count: 2
- path: src/Bundle/ChillReportBundle/Timeline/TimelineReportProvider.php
-
message: """
diff --git a/src/Bundle/ChillActivityBundle/ChillActivityBundle.php b/src/Bundle/ChillActivityBundle/ChillActivityBundle.php
index 21245504f..5f872a7dc 100644
--- a/src/Bundle/ChillActivityBundle/ChillActivityBundle.php
+++ b/src/Bundle/ChillActivityBundle/ChillActivityBundle.php
@@ -1,14 +1,14 @@
charges, function ($el) { return $el['active']; })
+ array_filter($this->charges, static function ($el) { return $el['active']; })
: $this->charges;
}
private function getResources(bool $onlyActive = false): array
{
return $onlyActive ?
- array_filter($this->resources, function ($el) { return $el['active']; })
+ array_filter($this->resources, static function ($el) { return $el['active']; })
: $this->resources;
}
diff --git a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
index 94cb9255a..badccf3b3 100644
--- a/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
+++ b/src/Bundle/ChillBudgetBundle/Controller/AbstractElementController.php
@@ -1,14 +1,14 @@
logger->notice('[export] choices for an export unserialized', [
'key' => $key,
- 'rawData' => json_encode($rawData)
+ 'rawData' => json_encode($rawData),
]);
$alias = $rawData['alias'];
diff --git a/src/Bundle/ChillMainBundle/Controller/LanguageController.php b/src/Bundle/ChillMainBundle/Controller/LanguageController.php
index 4612a3728..4e72d8983 100644
--- a/src/Bundle/ChillMainBundle/Controller/LanguageController.php
+++ b/src/Bundle/ChillMainBundle/Controller/LanguageController.php
@@ -1,14 +1,14 @@
handleAggregators($export, $query, $data[ExportType::AGGREGATOR_KEY], $centers);
$this->logger->notice('[export] will execute this qb in export', [
- 'dql' => $query->getDQL()
+ 'dql' => $query->getDQL(),
]);
-
} else {
throw new UnexpectedValueException('The method `intiateQuery` should return '
. 'a `\\Doctrine\\ORM\\NativeQuery` or a `Doctrine\\ORM\\QueryBuilder` '
. 'object.');
}
-
$result = $export->getResult($query, $data[ExportType::EXPORT_KEY]);
if (!is_iterable($result)) {
diff --git a/src/Bundle/ChillMainBundle/Export/FilterInterface.php b/src/Bundle/ChillMainBundle/Export/FilterInterface.php
index 0b27f1cf1..5e398c30d 100644
--- a/src/Bundle/ChillMainBundle/Export/FilterInterface.php
+++ b/src/Bundle/ChillMainBundle/Export/FilterInterface.php
@@ -1,14 +1,14 @@
executeStatement(array_merge(...$this->waitingForInsert));
- if ($affected === 0) {
- throw new \RuntimeException('no row affected');
+ if (0 === $affected) {
+ throw new RuntimeException('no row affected');
}
} catch (Exception $e) {
// in some case, we can add debug code here
diff --git a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
index c30b7c4f2..7a9659884 100644
--- a/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
+++ b/src/Bundle/ChillMainBundle/Service/Import/AddressReferenceFromBano.php
@@ -1,14 +1,14 @@
setRefPostalCodeId($postalCodeId = '1234'.uniqid())
+ ->setRefPostalCodeId($postalCodeId = '1234' . uniqid())
->setPostalCodeSource('testing')
->setCode('TEST456')
->setName('testing');
@@ -54,7 +70,8 @@ class AddressReferenceBaseImporterTest extends KernelTestCase
$addresses = $this->addressReferenceRepository->findByPostalCodePattern(
$postalCode,
- 'Rue test abcc guessed');
+ 'Rue test abcc guessed'
+ );
$this->assertCount(1, $addresses);
$this->assertEquals('Rue test abccc-guessed', $addresses[0]->getStreet());
@@ -79,12 +96,11 @@ class AddressReferenceBaseImporterTest extends KernelTestCase
$addresses = $this->addressReferenceRepository->findByPostalCodePattern(
$postalCode,
- 'abcc guessed fixed');
+ 'abcc guessed fixed'
+ );
$this->assertCount('1', $addresses);
- $this->assertEquals( 'Rue test abccc guessed fixed', $addresses[0]->getStreet());
+ $this->assertEquals('Rue test abccc guessed fixed', $addresses[0]->getStreet());
$this->assertEquals($previousAddressId, $addresses[0]->getId());
}
-
-
-}
\ No newline at end of file
+}
diff --git a/src/Bundle/ChillMainBundle/Tests/Services/Import/PostalCodeBaseImporterTest.php b/src/Bundle/ChillMainBundle/Tests/Services/Import/PostalCodeBaseImporterTest.php
index 826e581ac..ce9a7a432 100644
--- a/src/Bundle/ChillMainBundle/Tests/Services/Import/PostalCodeBaseImporterTest.php
+++ b/src/Bundle/ChillMainBundle/Tests/Services/Import/PostalCodeBaseImporterTest.php
@@ -1,5 +1,14 @@
importer->importCode(
'BE',
- 'tested with pattern '. ($uniqid = uniqid()),
+ 'tested with pattern ' . ($uniqid = uniqid()),
'12345',
- $refPostalCodeId = 'test'.uniqid(),
+ $refPostalCodeId = 'test' . uniqid(),
'test',
50.0,
5.0,
@@ -46,8 +59,8 @@ class PostalCodeBaseImporterTest extends KernelTestCase
$this->importer->finalize();
$postalCodes = $this->postalCodeRepository->findByPattern(
- 'with pattern '.$uniqid,
- $this->countryRepository->findOneBy(['countryCode' => 'BE'])
+ 'with pattern ' . $uniqid,
+ $this->countryRepository->findOneBy(['countryCode' => 'BE'])
);
$this->assertCount(1, $postalCodes);
@@ -59,7 +72,7 @@ class PostalCodeBaseImporterTest extends KernelTestCase
$this->importer->importCode(
'BE',
- 'tested with adapted pattern '. ($uniqid = uniqid()),
+ 'tested with adapted pattern ' . ($uniqid = uniqid()),
'12345',
$refPostalCodeId,
'test',
@@ -71,7 +84,7 @@ class PostalCodeBaseImporterTest extends KernelTestCase
$this->importer->finalize();
$postalCodes = $this->postalCodeRepository->findByPattern(
- 'with pattern '.$uniqid,
+ 'with pattern ' . $uniqid,
$this->countryRepository->findOneBy(['countryCode' => 'BE'])
);
@@ -79,7 +92,4 @@ class PostalCodeBaseImporterTest extends KernelTestCase
$this->assertStringStartsWith('tested with adapted pattern', $postalCodes[0]->getName());
$this->assertEquals($previousId, $postalCodes[0]->getId());
}
-
-
-
-}
\ No newline at end of file
+}
diff --git a/src/Bundle/ChillMainBundle/Tests/Services/MenuComposerTest.php b/src/Bundle/ChillMainBundle/Tests/Services/MenuComposerTest.php
index 8ed185aa9..2df11c4f9 100644
--- a/src/Bundle/ChillMainBundle/Tests/Services/MenuComposerTest.php
+++ b/src/Bundle/ChillMainBundle/Tests/Services/MenuComposerTest.php
@@ -1,14 +1,14 @@
setWorkflowName('workflow_name')
- ->setRelatedEntityClass(\stdClass::class)
- ->setRelatedEntityId(1)
- ;
+ ->setRelatedEntityClass(stdClass::class)
+ ->setRelatedEntityId(1);
// force an id to entityWorkflow:
- $reflection = new \ReflectionClass($entityWorkflow);
+ $reflection = new ReflectionClass($entityWorkflow);
$id = $reflection->getProperty('id');
$id->setAccessible(true);
$id->setValue($entityWorkflow, 1);
@@ -48,12 +62,11 @@ class NotificationOnTransitionTest extends TestCase
$step = new EntityWorkflowStep();
$entityWorkflow->addStep($step);
$step->addDestUser($dest)
- ->setCurrentStep('to_state')
- ;
+ ->setCurrentStep('to_state');
$em = $this->prophesize(EntityManagerInterface::class);
$em->persist(Argument::type(Notification::class))->should(
- function($args) use ($dest) {
+ static function ($args) use ($dest) {
/** @var Call[] $args */
if (1 !== count($args)) {
throw new FailedPredictionException('no notification sent');
@@ -68,7 +81,8 @@ class NotificationOnTransitionTest extends TestCase
if (!$notification->getAddressees()->contains($dest)) {
throw new FailedPredictionException('the dest is not notified');
}
- });
+ }
+ );
$engine = $this->prophesize(EngineInterface::class);
$engine->render(Argument::type('string'), Argument::type('array'))
diff --git a/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php
index a6cd9d6df..20fc1b48c 100644
--- a/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php
+++ b/src/Bundle/ChillMainBundle/Timeline/TimelineBuilder.php
@@ -1,14 +1,14 @@
userRender = $userRender;
}
+ public function addDests(Event $event): void
+ {
+ if (!$event->getSubject() instanceof EntityWorkflow) {
+ return;
+ }
+
+ /** @var EntityWorkflow $entityWorkflow */
+ $entityWorkflow = $event->getSubject();
+
+ foreach ($entityWorkflow->futureDestUsers as $user) {
+ $entityWorkflow->getCurrentStep()->addDestUser($user);
+ }
+
+ foreach ($entityWorkflow->futureDestEmails as $email) {
+ $entityWorkflow->getCurrentStep()->addDestEmail($email);
+ }
+ }
+
public static function getSubscribedEvents(): array
{
return [
@@ -55,23 +73,6 @@ class EntityWorkflowTransitionEventSubscriber implements EventSubscriberInterfac
];
}
- public function addDests(Event $event): void
- {
- if (!$event->getSubject() instanceof EntityWorkflow) {
- return;
- }
-
- /** @var EntityWorkflow $entityWorkflow */
- $entityWorkflow = $event->getSubject();
- foreach ($entityWorkflow->futureDestUsers as $user) {
- $entityWorkflow->getCurrentStep()->addDestUser($user);
- }
-
- foreach ($entityWorkflow->futureDestEmails as $email) {
- $entityWorkflow->getCurrentStep()->addDestEmail($email);
- }
- }
-
public function guardEntityWorkflow(GuardEvent $event)
{
if (!$event->getSubject() instanceof EntityWorkflow) {
diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php
index 982a7024e..608ae6fa1 100644
--- a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php
+++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/NotificationOnTransition.php
@@ -1,14 +1,14 @@
$dests array of unique values, where keys is the object's hash */
$dests = [];
+
foreach (array_merge(
// the subscriber to each step
$entityWorkflow->getSubscriberToStep()->toArray(),
diff --git a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/SendAccessKeyEventSubscriber.php b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/SendAccessKeyEventSubscriber.php
index d91926dc5..7d0ad8280 100644
--- a/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/SendAccessKeyEventSubscriber.php
+++ b/src/Bundle/ChillMainBundle/Workflow/EventSubscriber/SendAccessKeyEventSubscriber.php
@@ -1,14 +1,14 @@
addSql('DROP INDEX chill_main_address_reference_unicity');
+ }
+
public function getDescription(): string
{
return 'Add an unique constraint on addresses references';
@@ -18,9 +30,4 @@ final class Version20220730204216 extends AbstractMigration
{
$this->addSql('CREATE UNIQUE INDEX chill_main_address_reference_unicity ON chill_main_address_reference (refId, source)');
}
-
- public function down(Schema $schema): void
- {
- $this->addSql('DROP INDEX chill_main_address_reference_unicity');
- }
}
diff --git a/src/Bundle/ChillMainBundle/migrations/Version20220829132409.php b/src/Bundle/ChillMainBundle/migrations/Version20220829132409.php
index 0da81d182..2012aba27 100644
--- a/src/Bundle/ChillMainBundle/migrations/Version20220829132409.php
+++ b/src/Bundle/ChillMainBundle/migrations/Version20220829132409.php
@@ -9,6 +9,13 @@
declare(strict_types=1);
+/*
+ * Chill is a software for social workers
+ *
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
+ */
+
namespace Chill\Migrations\Main;
use Doctrine\DBAL\Schema\Schema;
diff --git a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/PersonAddressMoveEventSubscriber.php b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/PersonAddressMoveEventSubscriber.php
index 04dfb25cc..666febe9d 100644
--- a/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/PersonAddressMoveEventSubscriber.php
+++ b/src/Bundle/ChillPersonBundle/AccompanyingPeriod/Events/PersonAddressMoveEventSubscriber.php
@@ -1,14 +1,14 @@
,
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
+ * For the full copyright and license information, please view
+ * the LICENSE file that was distributed with this source code.
*/
namespace Chill\PersonBundle\Repository\SocialWork;
diff --git a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
index dc7f2632c..8d04ec79b 100644
--- a/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
+++ b/src/Bundle/ChillPersonBundle/Resources/public/vuejs/VisGraph/api.js
@@ -5,8 +5,10 @@ import {makeFetch} from 'ChillMainAssets/lib/api/apiMethods.ts';
* @function getFetch
* @param url
* @returns {Promise}
+ * @deprecated use makeFetch instead
*/
const getFetch = (url) => {
+ console.error('deprecated method');
return makeFetch('GET', url, null)
}
@@ -51,8 +53,10 @@ const getHouseholdByPerson = (person) => {
if (person.current_household_id === null) {
throw 'Currently the person has not household!'
}
- return getFetch(
- `/api/1.0/person/household/${person.current_household_id}.json`)
+ return makeFetch(
+ 'GET',
+ `/api/1.0/person/household/${person.current_household_id}.json`
+ );
}
/**
@@ -62,8 +66,10 @@ const getHouseholdByPerson = (person) => {
*/
const getCoursesByPerson = (person) => {
//console.log('getCoursesByPerson', person._id)
- return getFetch(
- `/api/1.0/person/accompanying-course/by-person/${person._id}.json`)
+ return makeFetch(
+ 'GET',
+ `/api/1.0/person/accompanying-course/by-person/${person._id}.json`
+ );
}
/**
@@ -73,8 +79,10 @@ const getCoursesByPerson = (person) => {
*/
const getRelationshipsByPerson = (person) => {
//console.log('getRelationshipsByPerson', person.id)
- return getFetch(
- `/api/1.0/relations/relationship/by-person/${person._id}.json`)
+ return makeFetch(
+ 'GET',
+ `/api/1.0/relations/relationship/by-person/${person._id}.json`
+ );
}
/**
@@ -82,7 +90,7 @@ const getRelationshipsByPerson = (person) => {
* @returns {Promise}
*/
const getRelationsList = () => {
- return getFetch(`/api/1.0/relations/relation.json`)
+ return makeFetch('GET', `/api/1.0/relations/relation.json`);
}
/**
diff --git a/src/Bundle/ChillPersonBundle/Search/PersonSearch.php b/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
index 9b18ae244..7a8c2dd14 100644
--- a/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
+++ b/src/Bundle/ChillPersonBundle/Search/PersonSearch.php
@@ -1,14 +1,14 @@
documentCategoryRepository = $documentCategoryRepository;
- $this->normalizer = $normalizer;
- $this->translatableStringHelper = $translatableStringHelper;
- $this->em = $em;
- $this->baseContextData = $baseContextData;
- $this->translator = $translator;
$this->authorizationHelper = $authorizationHelper;
+ $this->centerResolverManager = $centerResolverManager;
+ $this->baseContextData = $baseContextData;
+ $this->documentCategoryRepository = $documentCategoryRepository;
+ $this->em = $em;
+ $this->normalizer = $normalizer;
+ $this->security = $security;
+ $this->showScopes = $parameterBag->get('chill_main')['acl']['form_show_scopes'];
+ $this->translator = $translator;
+ $this->translatableStringHelper = $translatableStringHelper;
}
public function adminFormReverseTransform(array $data): array
@@ -112,6 +132,18 @@ class PersonContext implements DocGeneratorContextWithAdminFormInterface, DocGen
]);
}
+ /**
+ * @param Person $entity
+ */
+ public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
+ {
+ $builder->add('scope', ScopePickerType::class, [
+ 'center' => $this->centerResolverManager->resolveCenters($entity),
+ 'role' => PersonDocumentVoter::CREATE,
+ 'label' => 'Scope',
+ ]);
+ }
+
public function getData(DocGeneratorTemplate $template, $entity, array $contextGenerationData = []): array
{
if (!$entity instanceof Person) {
@@ -163,6 +195,14 @@ class PersonContext implements DocGeneratorContextWithAdminFormInterface, DocGen
return true;
}
+ /**
+ * @param Person $entity
+ */
+ public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
+ {
+ return $this->isScopeNecessary($entity);
+ }
+
/**
* @param Person $entity
*/
@@ -185,42 +225,36 @@ class PersonContext implements DocGeneratorContextWithAdminFormInterface, DocGen
);
}
- if ($this->showScopes()) {
-
- $scopes = $this->authorizationHelper->getReachableScopes();
-
- if (count($scopes > 1))
- {
- $scope = $this->getFormData();
- $doc->setScope($scope);
-
- } else {
-
- $doc->setScope($scopes[0]);
+ if ($this->isScopeNecessary($entity)) {
+ $doc->setScope($contextGenerationData['scope']);
+ } elseif ($this->showScopes) {
+ // in this case, it should have only one scope possible, we get it through AuthorizationHelper::getReachableScopes
+ $scopes = $this->authorizationHelper->getReachableScopes(
+ $this->security->getUser(),
+ PersonDocumentVoter::CREATE,
+ $this->centerResolverManager->resolveCenters($entity)
+ );
+ if (1 !== count($scopes)) {
+ throw new LogicException('at this step, it should have only one scope');
}
+
+ $doc->setScope($scopes[0]);
}
$this->em->persist($doc);
}
- public function showScopes(){
- return $this->parameterBag->get('chill_main')['acl']['form_show_scopes'];
- }
-
- public function buildPublicForm(FormBuilderInterface $builder, DocGeneratorTemplate $template, $entity): void
+ private function isScopeNecessary(Person $person): bool
{
- $builder->add('Center', ScopeType::class, [
- 'required' => true
- ]);
- }
-
- public function hasPublicForm(DocGeneratorTemplate $template, $entity): bool
- {
- if ($this->showScopes()) {
+ if ($this->showScopes && 1 < $this->authorizationHelper->getReachableScopes(
+ $this->security->getUser(),
+ PersonDocumentVoter::CREATE,
+ $this->centerResolverManager->resolveCenters($person)
+ )) {
return true;
- } else {
- return false;
}
+
+ return false;
}
}
diff --git a/src/Bundle/ChillPersonBundle/Service/Import/ChillImporter.php b/src/Bundle/ChillPersonBundle/Service/Import/ChillImporter.php
index 8f0a53157..6464066f1 100644
--- a/src/Bundle/ChillPersonBundle/Service/Import/ChillImporter.php
+++ b/src/Bundle/ChillPersonBundle/Service/Import/ChillImporter.php
@@ -1,14 +1,14 @@
setName(['fr' => 'template']);
+
+ $parameter = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => false]]]);
+ $em = $this->prophesize(EntityManagerInterface::class);
+ $em->persist(Argument::type(PersonDocument::class))
+ ->should(static function ($calls, $object, $method) {
+ if (1 !== count($calls)) {
+ throw new FailedPredictionException(sprintf('the persist should be called exactly once, %d receivved', count($calls)));
+ }
+
+ /** @var PersonDocument $personDocument */
+ $personDocument = $calls[0]->getArguments()[0];
+
+ if (null !== $personDocument->getScope()) {
+ throw new FailedPredictionException('the person document should not have any scope');
+ }
+ });
+
+ $personContext = $this->buildPersonContext(
+ null,
+ null,
+ null,
+ null,
+ $em->reveal(),
+ null,
+ $parameter
+ );
+
+ $this->assertFalse($personContext->hasPublicForm($docGen, $person));
+
+ $personContext->storeGenerated(
+ $docGen,
+ new StoredObject(),
+ $person,
+ []
+ );
+ }
+
+ public function testScopeScopeMustBeShownInFormsAndUserAccessMultipleScope()
+ {
+ $person = new Person();
+ $docGen = (new DocGeneratorTemplate())
+ ->setName(['fr' => 'template']);
+ $scope = new Scope();
+
+ $em = $this->prophesize(EntityManagerInterface::class);
+ $em->persist(Argument::type(PersonDocument::class))
+ ->should(static function ($calls, $object, $method) use ($scope) {
+ if (1 !== count($calls)) {
+ throw new FailedPredictionException(sprintf('the persist should be called exactly once, %d receivved', count($calls)));
+ }
+
+ /** @var PersonDocument $personDocument */
+ $personDocument = $calls[0]->getArguments()[0];
+
+ if ($personDocument->getScope() !== $scope) {
+ throw new FailedPredictionException('the person document should show the exactly prepared scope');
+ }
+ });
+
+ $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class);
+ $authorizationHelper->getReachableScopes(Argument::type(UserInterface::class), PersonDocumentVoter::CREATE, Argument::type('array'))
+ ->willReturn([$scope, new Scope()]);
+
+ $personContext = $this->buildPersonContext(
+ $authorizationHelper->reveal(),
+ null,
+ null,
+ null,
+ $em->reveal(),
+ );
+
+ $this->assertTrue($personContext->hasPublicForm($docGen, $person));
+
+ $personContext->storeGenerated(
+ $docGen,
+ new StoredObject(),
+ $person,
+ ['scope' => $scope]
+ );
+ }
+
+ public function testScopeScopeMustBeShownInFormsAndUserAccessOneScope()
+ {
+ $person = new Person();
+ $docGen = (new DocGeneratorTemplate())
+ ->setName(['fr' => 'template']);
+ $scope = new Scope();
+
+ $em = $this->prophesize(EntityManagerInterface::class);
+ $em->persist(Argument::type(PersonDocument::class))
+ ->should(static function ($calls, $object, $method) use ($scope) {
+ if (1 !== count($calls)) {
+ throw new FailedPredictionException(sprintf('the persist should be called exactly once, %d receivved', count($calls)));
+ }
+
+ /** @var PersonDocument $personDocument */
+ $personDocument = $calls[0]->getArguments()[0];
+
+ if ($personDocument->getScope() !== $scope) {
+ throw new FailedPredictionException('the person document should show the exactly prepared scope');
+ }
+ });
+
+ $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class);
+ $authorizationHelper->getReachableScopes(Argument::type(UserInterface::class), PersonDocumentVoter::CREATE, Argument::type('array'))
+ ->willReturn([$scope]);
+
+ $personContext = $this->buildPersonContext(
+ $authorizationHelper->reveal(),
+ null,
+ null,
+ null,
+ $em->reveal(),
+ );
+
+ $this->assertTrue($personContext->hasPublicForm($docGen, $person));
+
+ $personContext->storeGenerated(
+ $docGen,
+ new StoredObject(),
+ $person,
+ ['scope' => $scope]
+ );
+ }
+
+ private function buildPersonContext(
+ ?AuthorizationHelperInterface $authorizationHelper = null,
+ ?BaseContextData $baseContextData = null,
+ ?CenterResolverManagerInterface $centerResolverManager = null,
+ ?DocumentCategoryRepository $documentCategoryRepository = null,
+ ?EntityManagerInterface $em = null,
+ ?NormalizerInterface $normalizer = null,
+ ?ParameterBagInterface $parameterBag = null,
+ ?Security $security = null,
+ ?TranslatorInterface $translator = null,
+ ?TranslatableStringHelperInterface $translatableStringHelper = null
+ ): PersonContext {
+ if (null === $authorizationHelper) {
+ $authorizationHelper = $this->prophesize(AuthorizationHelperInterface::class)->reveal();
+ }
+
+ if (null === $baseContextData) {
+ $baseContextData = $this->prophesize(BaseContextData::class)->reveal();
+ }
+
+ if (null === $centerResolverManager) {
+ $centerResolverManager = $this->prophesize(CenterResolverManagerInterface::class);
+ $centerResolverManager->resolveCenters(Argument::any(), Argument::any())
+ ->willReturn([new Center()]);
+ $centerResolverManager = $centerResolverManager->reveal();
+ }
+
+ if (null === $documentCategoryRepository) {
+ $documentCategoryRepository = $this->prophesize(DocumentCategoryRepository::class);
+ $documentCategoryRepository->find(Argument::type('integer'))->willReturn(
+ new DocumentCategory(PersonDocument::class, 1)
+ );
+ $documentCategoryRepository = $documentCategoryRepository->reveal();
+ }
+
+ if (null === $em) {
+ $em = $this->prophesize(EntityManagerInterface::class)->reveal();
+ }
+
+ if (null === $normalizer) {
+ $normalizer = $this->prophesize(NormalizerInterface::class);
+ $normalizer->normalize(Argument::type(Person::class), 'docgen', Argument::any())
+ ->willReturn(['type' => 'person']);
+ $normalizer = $normalizer->reveal();
+ }
+
+ if (null === $parameterBag) {
+ $parameterBag = new ParameterBag(['chill_main' => ['acl' => ['form_show_scopes' => true]]]);
+ }
+
+ if (null === $security) {
+ $security = $this->prophesize(Security::class);
+ $security->getUser()->willReturn(new User());
+ $security = $security->reveal();
+ }
+
+ if (null === $translator) {
+ $translator = $this->prophesize(TranslatorInterface::class)->reveal();
+ }
+
+ if (null === $translatableStringHelper) {
+ $translatableStringHelper = $this->prophesize(TranslatableStringHelperInterface::class);
+ // return only the 'fr' key
+ $translatableStringHelper->localize(Argument::type('array'))->will(static function ($args) {
+ return $args[0]['fr'];
+ });
+ $translatableStringHelper = $translatableStringHelper->reveal();
+ }
+
+ return new PersonContext(
+ $authorizationHelper,
+ $baseContextData,
+ $centerResolverManager,
+ $documentCategoryRepository,
+ $em,
+ $normalizer,
+ $parameterBag,
+ $security,
+ $translator,
+ $translatableStringHelper
+ );
+ }
+}
diff --git a/src/Bundle/ChillPersonBundle/Tests/Timeline/TimelineAccompanyingPeriodTest.php b/src/Bundle/ChillPersonBundle/Tests/Timeline/TimelineAccompanyingPeriodTest.php
index 9e602ea90..ebc6d4b40 100644
--- a/src/Bundle/ChillPersonBundle/Tests/Timeline/TimelineAccompanyingPeriodTest.php
+++ b/src/Bundle/ChillPersonBundle/Tests/Timeline/TimelineAccompanyingPeriodTest.php
@@ -1,14 +1,14 @@