From 18694a34cf5400086b14144e589b54831439c9ca Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 3 Mar 2022 16:24:37 +0100 Subject: [PATCH 001/294] logic added to only keep youngest descendant. works for issue, seems not to for action --- .../ChillActivityBundle/Entity/Activity.php | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 0a344236c..f80d4ab86 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -229,7 +229,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialAction(SocialAction $socialAction): self { - if (!$this->socialActions->contains($socialAction)) { + $descendants = $socialAction->getDescendants(); + $inCollection = false; + + if(null != $descendants) { + foreach ($descendants as $d) { + $inCollection = $this->socialActions->contains($d); + } + } else { + $inCollection = $this->socialActions->contains($socialAction); + } + + if(!$inCollection) { $this->socialActions[] = $socialAction; } @@ -238,7 +249,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialIssue(SocialIssue $socialIssue): self { - if (!$this->socialIssues->contains($socialIssue)) { + $descendants = $socialIssue->getDescendants(); + $inCollection = false; + + if(null != $descendants) { + foreach ($descendants as $d) { + $inCollection = $this->socialIssues->contains($d); + } + } else { + $inCollection = $this->socialIssues->contains($socialIssue); + } + + if(!$inCollection) { $this->socialIssues[] = $socialIssue; } From 214ef09fe72e6971de5609b94bd60cb389581f38 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 3 Mar 2022 16:29:35 +0100 Subject: [PATCH 002/294] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a38f2ea47..efd8189bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and this project adheres to * [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue) * [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474) * [template] do not list inactive templates (for doc generator) - +* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) ## Test releases ### test release 2022-02-21 From 7c043e9d85257c0e8104f8a026fee30b43a5735a Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 12:06:53 +0100 Subject: [PATCH 003/294] fix logic in activity entity --- .../ChillActivityBundle/Entity/Activity.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index f80d4ab86..034e6073c 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -230,18 +230,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialAction(SocialAction $socialAction): self { $descendants = $socialAction->getDescendants(); - $inCollection = false; - if(null != $descendants) { + if(count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialActions->contains($d); + if ($inCollection) { + return $this; + } } } else { - $inCollection = $this->socialActions->contains($socialAction); - } - - if(!$inCollection) { - $this->socialActions[] = $socialAction; + if (!$this->socialActions->contains($socialAction)) { + $this->socialActions[] = $socialAction; + }; } return $this; @@ -250,18 +250,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialIssue(SocialIssue $socialIssue): self { $descendants = $socialIssue->getDescendants(); - $inCollection = false; - if(null != $descendants) { + if(count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialIssues->contains($d); + if ($inCollection) { + return $this; + } } } else { - $inCollection = $this->socialIssues->contains($socialIssue); - } - - if(!$inCollection) { - $this->socialIssues[] = $socialIssue; + if (!$this->socialIssues->contains($socialIssue)) { + $this->socialIssues[] = $socialIssue; + }; } return $this; From 0333e79b0ae1d3636720f595691b994b31c101a2 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 12:07:29 +0100 Subject: [PATCH 004/294] csfixes --- src/Bundle/ChillActivityBundle/Entity/Activity.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 034e6073c..f183ced60 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -35,6 +35,7 @@ use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\SerializedName; +use function count; /** * Class Activity. @@ -231,9 +232,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $descendants = $socialAction->getDescendants(); - if(count($descendants) > 0) { + if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialActions->contains($d); + if ($inCollection) { return $this; } @@ -241,7 +243,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } else { if (!$this->socialActions->contains($socialAction)) { $this->socialActions[] = $socialAction; - }; + } } return $this; @@ -251,9 +253,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $descendants = $socialIssue->getDescendants(); - if(count($descendants) > 0) { + if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialIssues->contains($d); + if ($inCollection) { return $this; } @@ -261,7 +264,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } else { if (!$this->socialIssues->contains($socialIssue)) { $this->socialIssues[] = $socialIssue; - }; + } } return $this; From 474fffcbb5b4dd63a8866feb46c1532c7a51fe93 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 12:08:00 +0100 Subject: [PATCH 005/294] changelog updated --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efd8189bc..55cc51fde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ and this project adheres to * [confidential] Fix position of toggle button so it does not cover text nor fall outside of box (no issue) * [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474) * [template] do not list inactive templates (for doc generator) -* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) +* [activity] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) ## Test releases ### test release 2022-02-21 From 4ef22748033610a69325c826c119c32675d6039b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 3 Mar 2022 16:24:37 +0100 Subject: [PATCH 006/294] logic added to only keep youngest descendant. works for issue, seems not to for action --- .../ChillActivityBundle/Entity/Activity.php | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 0a344236c..f80d4ab86 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -229,7 +229,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialAction(SocialAction $socialAction): self { - if (!$this->socialActions->contains($socialAction)) { + $descendants = $socialAction->getDescendants(); + $inCollection = false; + + if(null != $descendants) { + foreach ($descendants as $d) { + $inCollection = $this->socialActions->contains($d); + } + } else { + $inCollection = $this->socialActions->contains($socialAction); + } + + if(!$inCollection) { $this->socialActions[] = $socialAction; } @@ -238,7 +249,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialIssue(SocialIssue $socialIssue): self { - if (!$this->socialIssues->contains($socialIssue)) { + $descendants = $socialIssue->getDescendants(); + $inCollection = false; + + if(null != $descendants) { + foreach ($descendants as $d) { + $inCollection = $this->socialIssues->contains($d); + } + } else { + $inCollection = $this->socialIssues->contains($socialIssue); + } + + if(!$inCollection) { $this->socialIssues[] = $socialIssue; } From b6e530fec6cd84ac44edd1897a0d594ec1e2b44b Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Thu, 3 Mar 2022 16:29:35 +0100 Subject: [PATCH 007/294] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 380cc6afe..926363314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ and this project adheres to * [template] do not list inactive templates (for doc generator) * [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490) +* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) ## Test releases ### test release 2022-02-21 From 25fe105590299fc02e79618095b6fc65c9b27d54 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 12:06:53 +0100 Subject: [PATCH 008/294] fix logic in activity entity --- .../ChillActivityBundle/Entity/Activity.php | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index f80d4ab86..034e6073c 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -230,18 +230,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialAction(SocialAction $socialAction): self { $descendants = $socialAction->getDescendants(); - $inCollection = false; - if(null != $descendants) { + if(count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialActions->contains($d); + if ($inCollection) { + return $this; + } } } else { - $inCollection = $this->socialActions->contains($socialAction); - } - - if(!$inCollection) { - $this->socialActions[] = $socialAction; + if (!$this->socialActions->contains($socialAction)) { + $this->socialActions[] = $socialAction; + }; } return $this; @@ -250,18 +250,18 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialIssue(SocialIssue $socialIssue): self { $descendants = $socialIssue->getDescendants(); - $inCollection = false; - if(null != $descendants) { + if(count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialIssues->contains($d); + if ($inCollection) { + return $this; + } } } else { - $inCollection = $this->socialIssues->contains($socialIssue); - } - - if(!$inCollection) { - $this->socialIssues[] = $socialIssue; + if (!$this->socialIssues->contains($socialIssue)) { + $this->socialIssues[] = $socialIssue; + }; } return $this; From 1c21b8070365ca9cb3163104b12bf12c3089a82c Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 12:07:29 +0100 Subject: [PATCH 009/294] csfixes --- src/Bundle/ChillActivityBundle/Entity/Activity.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index 034e6073c..f183ced60 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -35,6 +35,7 @@ use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Serializer\Annotation\DiscriminatorMap; use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Serializer\Annotation\SerializedName; +use function count; /** * Class Activity. @@ -231,9 +232,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $descendants = $socialAction->getDescendants(); - if(count($descendants) > 0) { + if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialActions->contains($d); + if ($inCollection) { return $this; } @@ -241,7 +243,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } else { if (!$this->socialActions->contains($socialAction)) { $this->socialActions[] = $socialAction; - }; + } } return $this; @@ -251,9 +253,10 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac { $descendants = $socialIssue->getDescendants(); - if(count($descendants) > 0) { + if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialIssues->contains($d); + if ($inCollection) { return $this; } @@ -261,7 +264,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } else { if (!$this->socialIssues->contains($socialIssue)) { $this->socialIssues[] = $socialIssue; - }; + } } return $this; From 2012df512cba695ade191a6df4643e3266d8fb83 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 4 Mar 2022 17:27:26 +0100 Subject: [PATCH 010/294] merge conflict fixed --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 926363314..caf897a68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,8 +29,7 @@ and this project adheres to * [parcours] Fix edit of both thirdparty and contact name (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/474) * [template] do not list inactive templates (for doc generator) * [person] email added to twig personRenderbox (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/490) - -* [action] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) +* [activity] Only youngest descendant is kept for social issues and actions (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/471) ## Test releases ### test release 2022-02-21 From 16be28681ad0d7a017803b5668a23466e0c2f015 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 7 Mar 2022 14:53:54 +0100 Subject: [PATCH 011/294] Test added for activity-social action and social issue --- .../Tests/Entity/ActivityTest.php | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php diff --git a/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php b/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php new file mode 100644 index 000000000..c67c99894 --- /dev/null +++ b/src/Bundle/ChillActivityBundle/Tests/Entity/ActivityTest.php @@ -0,0 +1,98 @@ +addChild($child); + $grandChild = new SocialAction(); + $child->addChild($grandChild); + + $activity = new Activity(); + + $activity->addSocialAction($parent); + + $this->assertCount(1, $activity->getSocialActions()); + $this->assertContains($parent, $activity->getSocialActions()); + + $activity->addSocialAction($grandChild); + + $this->assertCount(1, $activity->getSocialActions()); + $this->assertContains($grandChild, $activity->getSocialActions()); + $this->assertNotContains($parent, $activity->getSocialActions()); + + $activity->addSocialAction($child); + + $this->assertCount(1, $activity->getSocialActions()); + $this->assertContains($grandChild, $activity->getSocialActions()); + $this->assertNotContains($parent, $activity->getSocialActions()); + $this->assertNotContains($child, $activity->getSocialActions()); + + $activity->addSocialAction($another = new SocialAction()); + + $this->assertCount(2, $activity->getSocialActions()); + $this->assertContains($grandChild, $activity->getSocialActions()); + $this->assertContains($another, $activity->getSocialActions()); + $this->assertNotContains($parent, $activity->getSocialActions()); + $this->assertNotContains($child, $activity->getSocialActions()); + } + + public function testHierarchySocialIssues(): void + { + $parent = new SocialIssue(); + $child = new SocialIssue(); + + $parent->addChild($child); + $grandChild = new SocialIssue(); + $child->addChild($grandChild); + + $activity = new Activity(); + + $activity->addSocialIssue($parent); + + $this->assertCount(1, $activity->getSocialIssues()); + $this->assertContains($parent, $activity->getSocialIssues()); + + $activity->addSocialIssue($grandChild); + + $this->assertCount(1, $activity->getSocialIssues()); + $this->assertContains($grandChild, $activity->getSocialIssues()); + $this->assertNotContains($parent, $activity->getSocialIssues()); + + $activity->addSocialIssue($child); + + $this->assertCount(1, $activity->getSocialIssues()); + $this->assertContains($grandChild, $activity->getSocialIssues()); + $this->assertNotContains($parent, $activity->getSocialIssues()); + $this->assertNotContains($child, $activity->getSocialIssues()); + + $activity->addSocialIssue($another = new SocialIssue()); + + $this->assertCount(2, $activity->getSocialIssues()); + $this->assertContains($grandChild, $activity->getSocialIssues()); + $this->assertContains($another, $activity->getSocialIssues()); + $this->assertNotContains($parent, $activity->getSocialIssues()); + $this->assertNotContains($child, $activity->getSocialIssues()); + } + +} \ No newline at end of file From 325ab0daf3832427e52e312261f7315c92096c27 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 8 Mar 2022 15:48:26 +0100 Subject: [PATCH 012/294] chore: Update `composer.json` files. --- composer.json | 6 ++++-- src/Bundle/ChillDocGeneratorBundle/composer.json | 1 + src/Bundle/ChillDocStoreBundle/composer.json | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index c96738df8..d0fc51c0e 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "knplabs/knp-time-bundle": "^1.12", "league/csv": "^9.7.1", "nyholm/psr7": "^1.4", - "ocramius/package-versions": "^1.10", + "ocramius/package-versions": "^1.10 || ^2", "odolbeau/phone-number-bundle": "^3.6", "phpoffice/phpspreadsheet": "^1.16", "ramsey/uuid-doctrine": "^1.7", @@ -33,6 +33,7 @@ "symfony/expression-language": "^4.4", "symfony/form": "^4.4", "symfony/framework-bundle": "^4.4", + "symfony/http-foundation": "^4.4", "symfony/intl": "^4.4", "symfony/mailer": "^5.4", "symfony/mime": "^5.4", @@ -103,7 +104,8 @@ "ergebnis/composer-normalize": true, "ocramius/package-versions": true, "phpro/grumphp": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "roave/you-are-using-it-wrong": true }, "bin-dir": "bin", "optimize-autoloader": true, diff --git a/src/Bundle/ChillDocGeneratorBundle/composer.json b/src/Bundle/ChillDocGeneratorBundle/composer.json index 4ae119636..42939bd2b 100644 --- a/src/Bundle/ChillDocGeneratorBundle/composer.json +++ b/src/Bundle/ChillDocGeneratorBundle/composer.json @@ -18,6 +18,7 @@ } ], "require": { + "spomky-labs/base64url": "^2" }, "require-dev": { }, diff --git a/src/Bundle/ChillDocStoreBundle/composer.json b/src/Bundle/ChillDocStoreBundle/composer.json index c011ce29b..aa636535e 100644 --- a/src/Bundle/ChillDocStoreBundle/composer.json +++ b/src/Bundle/ChillDocStoreBundle/composer.json @@ -8,7 +8,8 @@ } }, "require": { - "symfony/mime": "^4 || ^5" + "symfony/mime": "^4 || ^5", + "symfony/http-foundation": "^4" }, "license": "AGPL-3.0" } From 6ddbf35a7b334e0e6745e03e0984c4b088ee0908 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 8 Mar 2022 15:46:50 +0100 Subject: [PATCH 013/294] misc: Add return types. --- src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php index c512dba73..d5afd4a28 100644 --- a/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php +++ b/src/Bundle/ChillDocStoreBundle/Entity/StoredObject.php @@ -109,12 +109,12 @@ class StoredObject implements AsyncFileInterface, Document return $this->id; } - public function getIv() + public function getIv(): array { return $this->iv; } - public function getKeyInfos() + public function getKeyInfos(): array { return $this->keyInfos; } @@ -163,21 +163,21 @@ class StoredObject implements AsyncFileInterface, Document return $this; } - public function setIv($iv) + public function setIv(array $iv) { $this->iv = $iv; return $this; } - public function setKeyInfos($keyInfos) + public function setKeyInfos(array $keyInfos) { $this->keyInfos = $keyInfos; return $this; } - public function setType($type) + public function setType(string $type) { $this->type = $type; From b8992b8eeba281559cf9b226c10d194a54bd92d9 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 8 Mar 2022 15:47:33 +0100 Subject: [PATCH 014/294] misc: Update interface doc. --- .../Context/ContextManager.php | 5 +--- .../Context/ContextManagerInterface.php | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/Bundle/ChillDocGeneratorBundle/Context/ContextManagerInterface.php diff --git a/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php index 8dfecb730..b8f4d0eed 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php +++ b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManager.php @@ -14,7 +14,7 @@ namespace Chill\DocGeneratorBundle\Context; use Chill\DocGeneratorBundle\Context\Exception\ContextNotFoundException; use Chill\DocGeneratorBundle\Entity\DocGeneratorTemplate; -class ContextManager +final class ContextManager implements ContextManagerInterface { /** * @var DocGeneratorContextInterface[]|iterable @@ -26,9 +26,6 @@ class ContextManager $this->contexts = $contexts; } - /** - * @throw ContextNotFoundException when the context is not found - */ public function getContextByDocGeneratorTemplate(DocGeneratorTemplate $docGeneratorTemplate): DocGeneratorContextInterface { foreach ($this->contexts as $key => $context) { diff --git a/src/Bundle/ChillDocGeneratorBundle/Context/ContextManagerInterface.php b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManagerInterface.php new file mode 100644 index 000000000..3468d787d --- /dev/null +++ b/src/Bundle/ChillDocGeneratorBundle/Context/ContextManagerInterface.php @@ -0,0 +1,30 @@ + Date: Tue, 8 Mar 2022 15:46:31 +0100 Subject: [PATCH 015/294] refactor: Return a string instead of a resource. --- .../GeneratorDriver/DriverInterface.php | 7 +-- .../GeneratorDriver/RelatorioDriver.php | 46 +++++++++++++------ 2 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/DriverInterface.php b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/DriverInterface.php index 2572484e1..d787523c9 100644 --- a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/DriverInterface.php +++ b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/DriverInterface.php @@ -13,10 +13,5 @@ namespace Chill\DocGeneratorBundle\GeneratorDriver; interface DriverInterface { - /** - * @param resource $template - * - * @return resource - */ - public function generateFromResource($template, string $resourceType, array $data, ?string $templateName = null); + public function generateFromString(string $template, string $resourceType, array $data, ?string $templateName = null): string; } diff --git a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php index 7a3e4ac69..73a4ba9e0 100644 --- a/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php +++ b/src/Bundle/ChillDocGeneratorBundle/GeneratorDriver/RelatorioDriver.php @@ -20,40 +20,40 @@ use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface; use Symfony\Contracts\HttpClient\Exception\HttpExceptionInterface; use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Throwable; -class RelatorioDriver implements DriverInterface +final class RelatorioDriver implements DriverInterface { - private LoggerInterface $logger; + private HttpClientInterface $client; - private HttpClientInterface $relatorioClient; + private LoggerInterface $logger; private string $url; public function __construct( - HttpClientInterface $relatorioClient, + HttpClientInterface $client, ParameterBagInterface $parameterBag, LoggerInterface $logger ) { - $this->relatorioClient = $relatorioClient; + $this->client = $client; $this->logger = $logger; $this->url = $parameterBag->get('chill_doc_generator')['driver']['relatorio']['url']; } - public function generateFromResource($template, string $resourceType, array $data, ?string $templateName = null) + public function generateFromString(string $template, string $resourceType, array $data, ?string $templateName = null): string { - $formFields = [ - 'variables' => json_encode($data), - 'template' => new DataPart($template, $templateName ?? uniqid('template_'), $resourceType), - ]; - $form = new FormDataPart($formFields); + $form = new FormDataPart( + [ + 'variables' => json_encode($data), + 'template' => new DataPart($template, $templateName ?? uniqid('template_'), $resourceType), + ] + ); try { - $response = $this->relatorioClient->request('POST', $this->url, [ + $response = $this->client->request('POST', $this->url, [ 'headers' => $form->getPreparedHeaders()->toArray(), 'body' => $form->bodyToIterable(), ]); - - return $response->toStream(); } catch (HttpExceptionInterface $e) { $content = $e->getResponse()->getContent(false); @@ -88,5 +88,23 @@ class RelatorioDriver implements DriverInterface throw $e; } + + try { + $content = $response->getContent(); + } catch (Throwable $exception) { + $this + ->logger + ->error( + 'relatorio: Unable to get content from response.', + [ + 'msg' => $exception->getMessage(), + 'e' => $exception->getTraceAsString(), + ] + ); + + throw $exception; + } + + return $content; } } From 62af980ea545dbcfa018ee793d8d515d1e45cb88 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 8 Mar 2022 15:45:39 +0100 Subject: [PATCH 016/294] feat: Add new `StoredObjectManager` service. To read and write onto `StoredObject` document using a common interface. --- .../StoredObjectManagerException.php | 40 ++++ .../Service/StoredObjectManager.php | 133 +++++++++++++ .../Service/StoredObjectManagerInterface.php | 34 ++++ .../Tests/StoredObjectManagerTest.php | 183 ++++++++++++++++++ 4 files changed, 390 insertions(+) create mode 100644 src/Bundle/ChillDocStoreBundle/Exception/StoredObjectManagerException.php create mode 100644 src/Bundle/ChillDocStoreBundle/Service/StoredObjectManager.php create mode 100644 src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php create mode 100644 src/Bundle/ChillDocStoreBundle/Tests/StoredObjectManagerTest.php diff --git a/src/Bundle/ChillDocStoreBundle/Exception/StoredObjectManagerException.php b/src/Bundle/ChillDocStoreBundle/Exception/StoredObjectManagerException.php new file mode 100644 index 000000000..b5d0bf679 --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Exception/StoredObjectManagerException.php @@ -0,0 +1,40 @@ +client = $client; + $this->tempUrlGenerator = $tempUrlGenerator; + } + + public function read(StoredObject $document): string + { + try { + $response = $this + ->client + ->request( + Request::METHOD_GET, + $this + ->tempUrlGenerator + ->generate( + Request::METHOD_GET, + $document->getFilename() + ) + ->url + ); + } catch (Throwable $e) { + throw StoredObjectManagerException::errorDuringHttpRequest($e); + } + + if ($response->getStatusCode() !== Response::HTTP_OK) { + throw StoredObjectManagerException::invalidStatusCode($response->getStatusCode()); + } + + try { + $data = $response->getContent(); + } catch (Throwable $e) { + throw StoredObjectManagerException::unableToGetResponseContent($e); + } + + if (false === $this->hasKeysAndIv($document)) { + return $data; + } + + $clearData = openssl_decrypt( + $data, + self::ALGORITHM, + // TODO: Why using this library and not use base64_decode() ? + Base64Url::decode($document->getKeyInfos()['k']), + OPENSSL_RAW_DATA, + pack('C*', ...$document->getIv()) + ); + + if (false === $clearData) { + throw StoredObjectManagerException::unableToDecrypt(openssl_error_string()); + } + + return $clearData; + } + + public function write(StoredObject $document, string $clearContent): void + { + $encryptedContent = $this->hasKeysAndIv($document) + ? openssl_encrypt( + $clearContent, + self::ALGORITHM, + // TODO: Why using this library and not use base64_decode() ? + Base64Url::decode($document->getKeyInfos()['k']), + OPENSSL_RAW_DATA, + pack('C*', ...$document->getIv()) + ) + : $clearContent; + + try { + $response = $this + ->client + ->request( + Request::METHOD_PUT, + $this + ->tempUrlGenerator + ->generate( + Request::METHOD_PUT, + $document->getFilename() + ) + ->url, + [ + 'body' => $encryptedContent, + ] + ); + } catch (TransportExceptionInterface $exception) { + throw StoredObjectManagerException::errorDuringHttpRequest($exception); + } + + if ($response->getStatusCode() !== Response::HTTP_CREATED) { + throw StoredObjectManagerException::invalidStatusCode($response->getStatusCode()); + } + } + + private function hasKeysAndIv(StoredObject $storedObject): bool + { + return ([] !== $storedObject->getKeyInfos()) && ([] !== $storedObject->getIv()); + } +} diff --git a/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php new file mode 100644 index 000000000..3cf67cb0c --- /dev/null +++ b/src/Bundle/ChillDocStoreBundle/Service/StoredObjectManagerInterface.php @@ -0,0 +1,34 @@ +setFilename('encrypted.txt') + ->setKeyInfos(['k' => base64_encode('S9NIHMaFHOWzLPez3jZOIHBaNfBrMQUR5zvqBz6kme8')]) + ->setIv(unpack('C*', 'abcdefghijklmnop')), + hex2bin('741237d255fd4f7eddaaa9058912a84caae28a41b10b34d4e3e3abe41d3b9b47cb0dd8f22c3c883d4f0e9defa75ff662'), // Binary encoded string + 'The quick brown fox jumps over the lazy dog', // clear + ]; + + // Non-encrypted object + yield [ + (new StoredObject())->setFilename('non-encrypted.txt'), // The StoredObject + 'The quick brown fox jumps over the lazy dog', // Encrypted + 'The quick brown fox jumps over the lazy dog', // Clear + ]; + + /* UNHAPPY SCENARIO */ + + // Encrypted object with issue during HTTP communication + yield [ + (new StoredObject()) + ->setFilename('error_during_http_request.txt') + ->setKeyInfos(['k' => base64_encode('S9NIHMaFHOWzLPez3jZOIHBaNfBrMQUR5zvqBz6kme8')]) + ->setIv(unpack('C*', 'abcdefghijklmnop')), + hex2bin('741237d255fd4f7eddaaa9058912a84caae28a41b10b34d4e3e3abe41d3b9b47cb0dd8f22c3c883d4f0e9defa75ff662'), // Binary encoded string + 'The quick brown fox jumps over the lazy dog', // clear + StoredObjectManagerException::class, + ]; + + // Encrypted object with issue during HTTP communication: Invalid status code + yield [ + (new StoredObject()) + ->setFilename('invalid_statuscode.txt') + ->setKeyInfos(['k' => base64_encode('S9NIHMaFHOWzLPez3jZOIHBaNfBrMQUR5zvqBz6kme8')]) + ->setIv(unpack('C*', 'abcdefghijklmnop')), + hex2bin('741237d255fd4f7eddaaa9058912a84caae28a41b10b34d4e3e3abe41d3b9b47cb0dd8f22c3c883d4f0e9defa75ff662'), // Binary encoded string + 'The quick brown fox jumps over the lazy dog', // clear + StoredObjectManagerException::class, + ]; + + // Erroneous encrypted: Unable to decrypt exception. + yield [ + (new StoredObject()) + ->setFilename('unable_to_decrypt.txt') + ->setKeyInfos(['k' => base64_encode('WRONG_PASS_PHRASE')]) + ->setIv(unpack('C*', 'abcdefghijklmnop')), + 'WRONG_ENCODED_VALUE', // Binary encoded string + 'The quick brown fox jumps over the lazy dog', // clear + StoredObjectManagerException::class, + ]; + } + + /** + * @dataProvider getDataProvider + */ + public function testRead(StoredObject $storedObject, string $encodedContent, string $clearContent, ?string $exceptionClass = null) + { + if (null !== $exceptionClass) { + $this->expectException($exceptionClass); + } + + $storedObjectManager = $this->getSubject($storedObject, $encodedContent); + + self::assertEquals($clearContent, $storedObjectManager->read($storedObject)); + } + + /** + * @dataProvider getDataProvider + */ + public function testWrite(StoredObject $storedObject, string $encodedContent, string $clearContent, ?string $exceptionClass = null) + { + if (null !== $exceptionClass) { + $this->expectException($exceptionClass); + } + + $storedObjectManager = $this->getSubject($storedObject, $encodedContent); + + $storedObjectManager->write($storedObject, $clearContent); + + self::assertEquals($clearContent, $storedObjectManager->read($storedObject)); + } + + private function getHttpClient(string $encodedContent): HttpClientInterface + { + $callback = static function ($method, $url, $options) use ($encodedContent) { + if (Request::METHOD_GET === $method) { + switch ($url) { + case 'https://example.com/non-encrypted.txt': + case 'https://example.com/encrypted.txt': + return new MockResponse($encodedContent, ['http_code' => 200]); + + case 'https://example.com/error_during_http_request.txt': + return new TransportException('error_during_http_request.txt'); + + case 'https://example.com/invalid_statuscode.txt': + return new MockResponse($encodedContent, ['http_code' => 404]); + } + } + + if (Request::METHOD_PUT === $method) { + switch ($url) { + case 'https://example.com/non-encrypted.txt': + case 'https://example.com/encrypted.txt': + return new MockResponse($encodedContent, ['http_code' => 201]); + + case 'https://example.com/error_during_http_request.txt': + throw new TransportException('error_during_http_request.txt'); + + case 'https://example.com/invalid_statuscode.txt': + return new MockResponse($encodedContent, ['http_code' => 404]); + } + } + + return new MockResponse('Not found'); + }; + + return new MockHttpClient($callback); + } + + private function getSubject(StoredObject $storedObject, string $encodedContent): StoredObjectManagerInterface + { + return new StoredObjectManager( + $this->getHttpClient($encodedContent), + $this->getTempUrlGenerator($storedObject) + ); + } + + private function getTempUrlGenerator(StoredObject $storedObject): TempUrlGeneratorInterface + { + $response = new stdClass(); + $response->url = $storedObject->getFilename(); + + $tempUrlGenerator = $this + ->getMockBuilder(TempUrlGeneratorInterface::class) + ->getMock(); + + $tempUrlGenerator + ->method('generate') + ->withAnyParameters() + ->willReturn($response); + + return $tempUrlGenerator; + } +} From 35d723e5fbc22ea324ce1c174f299c3794ee5d76 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 8 Mar 2022 15:48:52 +0100 Subject: [PATCH 017/294] refactor: Use `StoredObjectManager`. --- .../DocGeneratorTemplateController.php | 206 +++++++++--------- .../src/Service/Wopi/ChillDocumentManager.php | 70 +----- 2 files changed, 113 insertions(+), 163 deletions(-) diff --git a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php index 000fcb03a..2f64ea81e 100644 --- a/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php +++ b/src/Bundle/ChillDocGeneratorBundle/Controller/DocGeneratorTemplateController.php @@ -11,8 +11,6 @@ declare(strict_types=1); namespace Chill\DocGeneratorBundle\Controller; -use Base64Url\Base64Url; -use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface; use Chill\DocGeneratorBundle\Context\ContextManager; use Chill\DocGeneratorBundle\Context\DocGeneratorContextWithPublicFormInterface; use Chill\DocGeneratorBundle\Context\Exception\ContextNotFoundException; @@ -21,11 +19,11 @@ use Chill\DocGeneratorBundle\GeneratorDriver\DriverInterface; use Chill\DocGeneratorBundle\GeneratorDriver\Exception\TemplateException; use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository; use Chill\DocStoreBundle\Entity\StoredObject; +use Chill\DocStoreBundle\Service\StoredObjectManagerInterface; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Serializer\Model\Collection; +use Doctrine\ORM\EntityManagerInterface; use Exception; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\TransferException; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\FileType; @@ -34,14 +32,14 @@ use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; // TODO à mettre dans services use Symfony\Component\HttpFoundation\Response; -use Symfony\Component\HttpFoundation\StreamedResponse; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; +use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Throwable; +use function strlen; final class DocGeneratorTemplateController extends AbstractController { @@ -53,13 +51,13 @@ final class DocGeneratorTemplateController extends AbstractController private DriverInterface $driver; - private KernelInterface $kernel; + private EntityManagerInterface $entityManager; private LoggerInterface $logger; private PaginatorFactory $paginatorFactory; - private TempUrlGeneratorInterface $tempUrlGenerator; + private StoredObjectManagerInterface $storedObjectManager; public function __construct( ContextManager $contextManager, @@ -67,18 +65,18 @@ final class DocGeneratorTemplateController extends AbstractController DriverInterface $driver, LoggerInterface $logger, PaginatorFactory $paginatorFactory, - TempUrlGeneratorInterface $tempUrlGenerator, - KernelInterface $kernel, - HttpClientInterface $client + HttpClientInterface $client, + StoredObjectManagerInterface $storedObjectManager, + EntityManagerInterface $entityManager ) { $this->contextManager = $contextManager; $this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository; $this->driver = $driver; $this->logger = $logger; $this->paginatorFactory = $paginatorFactory; - $this->tempUrlGenerator = $tempUrlGenerator; - $this->kernel = $kernel; $this->client = $client; + $this->storedObjectManager = $storedObjectManager; + $this->entityManager = $entityManager; } /** @@ -177,8 +175,10 @@ final class DocGeneratorTemplateController extends AbstractController return $this->redirectToRoute( 'chill_docgenerator_test_generate_from_template', - ['template' => $template, 'entityClassName' => $entityClassName, 'entityId' => $entityId, - 'returnPath' => $request->query->get('returnPath', '/'), ] + [ + 'template' => $template, 'entityClassName' => $entityClassName, 'entityId' => $entityId, + 'returnPath' => $request->query->get('returnPath', '/'), + ] ); } @@ -192,16 +192,26 @@ final class DocGeneratorTemplateController extends AbstractController try { $context = $this->contextManager->getContextByDocGeneratorTemplate($template); } catch (ContextNotFoundException $e) { - throw new NotFoundHttpException($e->getMessage(), $e); + throw new NotFoundHttpException( + 'Context not found.', + $e + ); } - $entity = $this->getDoctrine()->getRepository($context->getEntityClass())->find($entityId); + $entity = $this + ->entityManager + ->getRepository($context->getEntityClass()) + ->find($entityId); if (null === $entity) { - throw new NotFoundHttpException("Entity with classname {$entityClassName} and id {$entityId} is not found"); + throw new NotFoundHttpException( + sprintf('Entity with classname %s and id %s is not found', $entityClassName, $entityId) + ); } - $contextGenerationData = []; + $contextGenerationData = [ + 'test_file' => null, + ]; if ( $context instanceof DocGeneratorContextWithPublicFormInterface @@ -235,123 +245,109 @@ final class DocGeneratorTemplateController extends AbstractController $contextGenerationData = $form->getData(); } elseif (!$form->isSubmitted() || ($form->isSubmitted() && !$form->isValid())) { $templatePath = '@ChillDocGenerator/Generator/basic_form.html.twig'; - $templateOptions = ['entity' => $entity, 'form' => $form->createView(), - 'template' => $template, 'context' => $context, ]; + $templateOptions = [ + 'entity' => $entity, 'form' => $form->createView(), + 'template' => $template, 'context' => $context, + ]; return $this->render($templatePath, $templateOptions); } } - if ($isTest && null !== $contextGenerationData['test_file']) { - /** @var File $file */ - $file = $contextGenerationData['test_file']; - $templateResource = fopen($file->getPathname(), 'rb'); + $document = $template->getFile(); + + if ($isTest && ($contextGenerationData['test_file'] instanceof File)) { + $dataDecrypted = file_get_contents($contextGenerationData['test_file']->getPathname()); } else { - $getUrlGen = $this->tempUrlGenerator->generate( - 'GET', - $template->getFile()->getFilename() - ); - - $data = $this->client->request('GET', $getUrlGen->url); - - $iv = $template->getFile()->getIv(); // iv as an Array - $ivGoodFormat = pack('C*', ...$iv); // iv as a String (ok for openssl_decrypt) - - $method = 'AES-256-CBC'; - - $key = $template->getFile()->getKeyInfos()['k']; - $keyGoodFormat = Base64Url::decode($key); - - $dataDecrypted = openssl_decrypt($data->getContent(), $method, $keyGoodFormat, 1, $ivGoodFormat); - - if (false === $dataDecrypted) { - throw new Exception('Error during Decrypt ', 1); + try { + $dataDecrypted = $this->storedObjectManager->read($document); + } catch (Throwable $exception) { + throw $exception; } - - if (false === $templateResource = fopen('php://memory', 'r+b')) { - $this->logger->error('Could not write data to memory'); - - throw new HttpException(500); - } - fwrite($templateResource, $dataDecrypted); - rewind($templateResource); } - $datas = $context->getData($template, $entity, $contextGenerationData); try { - $generatedResource = $this->driver->generateFromResource($templateResource, $template->getFile()->getType(), $datas, $template->getFile()->getFilename()); + $generatedResource = $this + ->driver + ->generateFromString( + $dataDecrypted, + $template->getFile()->getType(), + $context->getData($template, $entity, $contextGenerationData), + $template->getFile()->getFilename() + ); } catch (TemplateException $e) { - $msg = implode("\n", $e->getErrors()); - - return new Response($msg, 400, [ - 'Content-Type' => 'text/plain', - ]); + return new Response( + implode("\n", $e->getErrors()), + 400, + [ + 'Content-Type' => 'text/plain', + ] + ); } - fclose($templateResource); - if ($isTest) { - return new StreamedResponse( - static function () use ($generatedResource) { - fpassthru($generatedResource); - fclose($generatedResource); - }, + return new Response( + $generatedResource, Response::HTTP_OK, [ 'Content-Transfer-Encoding', 'binary', 'Content-Type' => 'application/vnd.oasis.opendocument.text', - 'Content-Disposition' => sprintf('attachment; filename="%s.odt"', 'generated'), - 'Content-Length' => fstat($generatedResource)['size'], + 'Content-Disposition' => 'attachment; filename="generated.odt"', + 'Content-Length' => strlen($generatedResource), ], ); } - $genDocName = 'doc_' . sprintf('%010d', mt_rand()) . 'odt'; - - $getUrlGen = $this->tempUrlGenerator->generate( - 'PUT', - $genDocName - ); - - $client = new Client(); + /** @var StoredObject $storedObject */ + $storedObject = (new ObjectNormalizer()) + ->denormalize( + [ + 'type' => $template->getFile()->getType(), + 'filename' => sprintf('%s_odt', uniqid('doc_', true)), + ], + StoredObject::class + ); try { - $putResponse = $client->request('PUT', $getUrlGen->url, [ - 'body' => $generatedResource, - ]); + $this->storedObjectManager->write($storedObject, $generatedResource); + } catch (Throwable $exception) { + throw $exception; + } - if ($putResponse->getStatusCode() === 201) { - $em = $this->getDoctrine()->getManager(); - $storedObject = new StoredObject(); - $storedObject - ->setType($template->getFile()->getType()) - ->setFilename($genDocName); + $this->entityManager->persist($storedObject); - $em->persist($storedObject); - - try { - $context->storeGenerated($template, $storedObject, $entity, $contextGenerationData); - } catch (Exception $e) { - $this->logger->error('Could not store the associated document to entity', [ + try { + $context + ->storeGenerated( + $template, + $storedObject, + $entity, + $contextGenerationData + ); + } catch (Exception $e) { + $this + ->logger + ->error( + 'Unable to store the associated document to entity', + [ 'entityClassName' => $entityClassName, 'entityId' => $entityId, 'contextKey' => $context->getName(), - ]); + ] + ); - throw $e; - } - - $em->flush(); - - return $this->redirectToRoute('chill_wopi_file_edit', [ - 'fileId' => $storedObject->getUuid(), - 'returnPath' => $request->query->get('returnPath', '/'), - ]); - } - } catch (TransferException $e) { throw $e; } - throw new Exception('Unable to generate document.'); + $this->entityManager->flush(); + + return $this + ->redirectToRoute( + 'chill_wopi_file_edit', + [ + 'fileId' => $storedObject->getUuid(), + 'returnPath' => $request->query->get('returnPath', '/'), + ] + ); } } diff --git a/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php b/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php index 19ff3c62e..7cc71188f 100644 --- a/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php +++ b/src/Bundle/ChillWopiBundle/src/Service/Wopi/ChillDocumentManager.php @@ -11,12 +11,12 @@ declare(strict_types=1); namespace Chill\WopiBundle\Service\Wopi; -use ChampsLibres\AsyncUploaderBundle\TempUrl\TempUrlGeneratorInterface; use ChampsLibres\WopiLib\Contract\Entity\Document; use ChampsLibres\WopiLib\Contract\Service\DocumentLockManagerInterface; use ChampsLibres\WopiLib\Contract\Service\DocumentManagerInterface; use Chill\DocStoreBundle\Entity\StoredObject; use Chill\DocStoreBundle\Repository\StoredObjectRepository; +use Chill\DocStoreBundle\Service\StoredObjectManagerInterface; use DateTimeInterface; use Doctrine\ORM\EntityManagerInterface; use Error; @@ -28,8 +28,6 @@ use Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Mime\MimeTypes; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; -use Symfony\Contracts\HttpClient\HttpClientInterface; -use Throwable; use function strlen; @@ -39,33 +37,29 @@ final class ChillDocumentManager implements DocumentManagerInterface private EntityManagerInterface $entityManager; - private HttpClientInterface $httpClient; - private Psr17Interface $psr17; private RequestInterface $request; private StoredObjectRepository $storedObjectRepository; - private TempUrlGeneratorInterface $tempUrlGenerator; + private StoredObjectManagerInterface $storedObjectManager; public function __construct( DocumentLockManagerInterface $documentLockManager, EntityManagerInterface $entityManager, - HttpClientInterface $httpClient, - Psr17Interface $psr17, - StoredObjectRepository $storedObjectRepository, - TempUrlGeneratorInterface $tempUrlGenerator, HttpMessageFactoryInterface $httpMessageFactory, - RequestStack $requestStack + Psr17Interface $psr17, + RequestStack $requestStack, + StoredObjectManagerInterface $storedObjectManager, + StoredObjectRepository $storedObjectRepository ) { + $this->documentLockManager = $documentLockManager; $this->entityManager = $entityManager; $this->psr17 = $psr17; - $this->storedObjectRepository = $storedObjectRepository; - $this->documentLockManager = $documentLockManager; - $this->tempUrlGenerator = $tempUrlGenerator; - $this->httpClient = $httpClient; $this->request = $httpMessageFactory->createRequest($requestStack->getCurrentRequest()); + $this->storedObjectManager = $storedObjectManager; + $this->storedObjectRepository = $storedObjectRepository; } public function create(array $data): Document @@ -197,18 +191,7 @@ final class ChillDocumentManager implements DocumentManagerInterface public function remove(Document $document): void { - $entityIsDeleted = false; - - try { - $this->entityManager->remove($document); - $entityIsDeleted = true; - } catch (Throwable $e) { - $entityIsDeleted = false; - } - - if (true === $entityIsDeleted) { - $this->deleteContent($document); - } + // TODO: To implement when we have a clearer view and API. } public function write(Document $document, array $properties = []): void @@ -216,42 +199,13 @@ final class ChillDocumentManager implements DocumentManagerInterface $this->setContent($document, $properties['content']); } - private function deleteContent(StoredObject $storedObject): void - { - /** @var StdClass $object */ - $object = $this->tempUrlGenerator->generate('DELETE', $storedObject->getFilename()); - - $response = $this->httpClient->request('DELETE', $object->url); - - if (200 !== $response->getStatusCode()) { - throw new Error('Unable to delete stored object.'); - } - } - private function getContent(StoredObject $storedObject): string { - /** @var StdClass $object */ - $object = $this->tempUrlGenerator->generate('GET', $storedObject->getFilename()); - - $response = $this->httpClient->request('GET', $object->url); - - if (200 !== $response->getStatusCode()) { - throw new Error('Unable to retrieve stored object.'); - } - - return $response->getContent(); + return $this->storedObjectManager->read($storedObject); } private function setContent(StoredObject $storedObject, string $content): void { - // TODO: Add strict typing in champs-libres/async-uploader-bundle - /** @var StdClass $object */ - $object = $this->tempUrlGenerator->generate('PUT', $storedObject->getFilename()); - - $response = $this->httpClient->request('PUT', $object->url, ['body' => $content]); - - if (201 !== $response->getStatusCode()) { - throw new Error('Unable to save stored object.'); - } + $this->storedObjectManager->write($storedObject, $content); } } From 3d7fcd99a8d5ad3e65f45fb6d583706e16e1aece Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 15 Mar 2022 11:25:19 +0100 Subject: [PATCH 018/294] fix: Remove `console.log`. --- .../ChillWopiBundle/src/Resources/public/page/editor/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js b/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js index 613a51d63..bb684e406 100644 --- a/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js +++ b/src/Bundle/ChillWopiBundle/src/Resources/public/page/editor/index.js @@ -18,7 +18,6 @@ window.addEventListener('DOMContentLoaded', function(e) { frameholder.appendChild(office_frame); document.getElementById('office_form').submit(); - console.log(office_frame); const url = new URL(editor_url); const editor_domain = url.origin; From 22755de1dda819aa584bc0c99d43b2b36c23a705 Mon Sep 17 00:00:00 2001 From: Pol Dellaiera Date: Tue, 15 Mar 2022 13:42:13 +0100 Subject: [PATCH 019/294] fix: Remove `PrependExtensionInterface`. It is now handled by `chill_main` bundle. --- .../DependencyInjection/ChillWopiExtension.php | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/Bundle/ChillWopiBundle/src/DependencyInjection/ChillWopiExtension.php b/src/Bundle/ChillWopiBundle/src/DependencyInjection/ChillWopiExtension.php index 9e8596336..37a9e2fa6 100644 --- a/src/Bundle/ChillWopiBundle/src/DependencyInjection/ChillWopiExtension.php +++ b/src/Bundle/ChillWopiBundle/src/DependencyInjection/ChillWopiExtension.php @@ -11,14 +11,12 @@ declare(strict_types=1); namespace Chill\WopiBundle\DependencyInjection; -use Ramsey\Uuid\Doctrine\UuidType; use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; use Symfony\Component\DependencyInjection\Loader\PhpFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; -final class ChillWopiExtension extends Extension implements PrependExtensionInterface +final class ChillWopiExtension extends Extension { public function load(array $configs, ContainerBuilder $container) { @@ -33,18 +31,4 @@ final class ChillWopiExtension extends Extension implements PrependExtensionInte $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.php'); } - - public function prepend(ContainerBuilder $container) - { - $container->prependExtensionConfig( - 'doctrine', - [ - 'dbal' => [ - 'types' => [ - 'uuid' => UuidType::class, - ], - ], - ] - ); - } } From 9551e10d2b3d902410ac3369bebf4f630cfb5bf5 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 16 Mar 2022 11:55:19 +0100 Subject: [PATCH 020/294] improvement, but still not correct --- .../ChillActivityBundle/Entity/Activity.php | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index f183ced60..db16ac9f6 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -235,15 +235,13 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialActions->contains($d); - if ($inCollection) { return $this; } } - } else { - if (!$this->socialActions->contains($socialAction)) { - $this->socialActions[] = $socialAction; - } + } + if (!$this->socialActions->contains($socialAction)) { + $this->socialActions[] = $socialAction; } return $this; @@ -256,15 +254,14 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac if (count($descendants) > 0) { foreach ($descendants as $d) { $inCollection = $this->socialIssues->contains($d); - if ($inCollection) { return $this; } } - } else { - if (!$this->socialIssues->contains($socialIssue)) { - $this->socialIssues[] = $socialIssue; - } + } + + if (!$this->socialIssues->contains($socialIssue)) { + $this->socialIssues[] = $socialIssue; } return $this; From 02571bf727135cbb305410a046bccee41694c8a3 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 22 Mar 2022 13:45:20 +0100 Subject: [PATCH 021/294] switch to using getDescendantsWithThis() --- src/Bundle/ChillActivityBundle/Entity/Activity.php | 13 +++++-------- .../Entity/SocialWork/SocialAction.php | 2 +- .../Entity/SocialWork/SocialIssue.php | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Entity/Activity.php b/src/Bundle/ChillActivityBundle/Entity/Activity.php index db16ac9f6..ac67a73e4 100644 --- a/src/Bundle/ChillActivityBundle/Entity/Activity.php +++ b/src/Bundle/ChillActivityBundle/Entity/Activity.php @@ -230,7 +230,7 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac public function addSocialAction(SocialAction $socialAction): self { - $descendants = $socialAction->getDescendants(); + $descendants = $socialAction->getDescendantsWithThis(); if (count($descendants) > 0) { foreach ($descendants as $d) { @@ -240,16 +240,14 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } } } - if (!$this->socialActions->contains($socialAction)) { - $this->socialActions[] = $socialAction; - } + $this->socialActions[] = $socialAction; return $this; } public function addSocialIssue(SocialIssue $socialIssue): self { - $descendants = $socialIssue->getDescendants(); + $descendants = $socialIssue->getDescendantsWithThis(); if (count($descendants) > 0) { foreach ($descendants as $d) { @@ -260,9 +258,8 @@ class Activity implements AccompanyingPeriodLinkedWithSocialIssuesEntityInterfac } } - if (!$this->socialIssues->contains($socialIssue)) { - $this->socialIssues[] = $socialIssue; - } + $this->socialIssues[] = $socialIssue; + return $this; } diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php index ec5e5a8e5..01f30f140 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php @@ -169,7 +169,7 @@ class SocialAction } /** - * @return Collection|self[] All the descendants with the current entity (this) + * @return Collection|self[] All the descendants including the current entity (this) */ public function getDescendantsWithThis(): Collection { diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php index c735c0132..fb277f56c 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php @@ -202,7 +202,7 @@ class SocialIssue } /** - * @return Collection|self[] All the descendants with the current entity (this) + * @return Collection|self[] All the descendants including the current entity (this) */ public function getDescendantsWithThis(): Collection { From 5f35a42fe351888ba786bf2a316f3be8f04aa3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 24 Mar 2022 22:09:12 +0100 Subject: [PATCH 022/294] allow phonumber helper to format null value --- .../Phonenumber/PhoneNumberHelperInterface.php | 2 +- .../ChillMainBundle/Phonenumber/PhonenumberHelper.php | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Phonenumber/PhoneNumberHelperInterface.php b/src/Bundle/ChillMainBundle/Phonenumber/PhoneNumberHelperInterface.php index 1ed67d967..12e74550e 100644 --- a/src/Bundle/ChillMainBundle/Phonenumber/PhoneNumberHelperInterface.php +++ b/src/Bundle/ChillMainBundle/Phonenumber/PhoneNumberHelperInterface.php @@ -22,7 +22,7 @@ use libphonenumber\PhoneNumber; */ interface PhoneNumberHelperInterface { - public function format(PhoneNumber $phoneNumber): string; + public function format(?PhoneNumber $phoneNumber = null): string; /** * Get type (mobile, landline, ...) for phone number. diff --git a/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php b/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php index 22f580d78..fa1b097c8 100644 --- a/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php +++ b/src/Bundle/ChillMainBundle/Phonenumber/PhonenumberHelper.php @@ -78,8 +78,12 @@ final class PhonenumberHelper implements PhoneNumberHelperInterface * * @throws NumberParseException */ - public function format(PhoneNumber $phoneNumber): string + public function format(?PhoneNumber $phoneNumber = null): string { + if (null === $phoneNumber) { + return ''; + } + return $this->phoneNumberUtil ->formatOutOfCountryCallingNumber($phoneNumber, $this->config['default_carrier_code']); } From ea66db07a448aee271c0b8fd8d5cea6f3c565b68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Thu, 24 Mar 2022 22:10:07 +0100 Subject: [PATCH 023/294] fix cs --- .../ChillActivityBundle/Form/ActivityType.php | 8 +- .../Authorization/AccompanyingPeriodVoter.php | 4 +- .../Entity/ThirdParty.php | 2 +- .../migrations/Version20220324175549.php | 86 ++++++++++--------- 4 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/Bundle/ChillActivityBundle/Form/ActivityType.php b/src/Bundle/ChillActivityBundle/Form/ActivityType.php index 3a772d878..1e1daead5 100644 --- a/src/Bundle/ChillActivityBundle/Form/ActivityType.php +++ b/src/Bundle/ChillActivityBundle/Form/ActivityType.php @@ -126,7 +126,7 @@ class ActivityType extends AbstractType if ($activityType->isVisible('socialIssues') && $accompanyingPeriod) { $builder->add('socialIssues', HiddenType::class, [ - 'required' => $activityType->getSocialIssuesVisible() === 2 + 'required' => $activityType->getSocialIssuesVisible() === 2, ]); $builder->get('socialIssues') ->addModelTransformer(new CallbackTransformer( @@ -154,7 +154,7 @@ class ActivityType extends AbstractType if ($activityType->isVisible('socialActions') && $accompanyingPeriod) { $builder->add('socialActions', HiddenType::class, [ - 'required' => $activityType->getSocialActionsVisible() === 2 + 'required' => $activityType->getSocialActionsVisible() === 2, ]); $builder->get('socialActions') ->addModelTransformer(new CallbackTransformer( @@ -344,8 +344,8 @@ class ActivityType extends AbstractType if ($activityType->isVisible('location')) { $builder->add('location', HiddenType::class, [ - 'required' => $activityType->getLocationVisible() === 2 - ]) + 'required' => $activityType->getLocationVisible() === 2, + ]) ->get('location') ->addModelTransformer(new CallbackTransformer( static function (?Location $location): string { diff --git a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php index a1166da25..9a2ee860d 100644 --- a/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php +++ b/src/Bundle/ChillPersonBundle/Security/Authorization/AccompanyingPeriodVoter.php @@ -131,8 +131,8 @@ class AccompanyingPeriodVoter extends AbstractChillVoter implements ProvideRoleH } if (in_array($attribute, [ - self::SEE, self::SEE_DETAILS, self::EDIT - ])) { + self::SEE, self::SEE_DETAILS, self::EDIT, + ], true)) { if ($subject->getUser() === $token->getUser()) { return true; } diff --git a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php index d7efce10c..16260ec97 100644 --- a/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php +++ b/src/Bundle/ChillThirdPartyBundle/Entity/ThirdParty.php @@ -198,7 +198,7 @@ class ThirdParty implements TrackCreationInterface, TrackUpdateInterface private ?string $email = null; /** - * @ORM\Column(name="firstname", type="text", options={"default":""}) + * @ORM\Column(name="firstname", type="text", options={"default": ""}) * @Groups({"read", "write", "docgen:read", "docgen:read:3party:parent"}) */ private string $firstname = ''; diff --git a/src/Bundle/ChillThirdPartyBundle/migrations/Version20220324175549.php b/src/Bundle/ChillThirdPartyBundle/migrations/Version20220324175549.php index e31b950d4..ae91699aa 100644 --- a/src/Bundle/ChillThirdPartyBundle/migrations/Version20220324175549.php +++ b/src/Bundle/ChillThirdPartyBundle/migrations/Version20220324175549.php @@ -1,5 +1,12 @@ addSql(" + CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER + LANGUAGE plpgsql + AS + $$ + BEGIN + NEW.canonicalized = + UNACCENT( + LOWER( + NEW.name || + CASE WHEN COALESCE(NEW.name_company, '') <> '' THEN ' ' ELSE '' END || + COALESCE(NEW.name_company, '') || + CASE WHEN COALESCE(NEW.acronym, '') <> '' THEN ' ' ELSE '' END || + COALESCE(NEW.acronym, '') + ) + ) + ; + + return NEW; + END + $$ + "); + $this->addSql(" + UPDATE chill_3party.third_party + SET canonicalized = + UNACCENT( + LOWER( + name || + CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END || + COALESCE(name_company, '') || + CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END || + COALESCE(acronym, '') + ) + ) + "); + } + public function getDescription(): string { return 'indexing of firstname on third parties'; @@ -55,45 +101,5 @@ final class Version20220324175549 extends AbstractMigration END $$ "); - - } - - public function down(Schema $schema): void - { - $this->addSql(" - CREATE OR REPLACE FUNCTION chill_3party.canonicalize() RETURNS TRIGGER - LANGUAGE plpgsql - AS - $$ - BEGIN - NEW.canonicalized = - UNACCENT( - LOWER( - NEW.name || - CASE WHEN COALESCE(NEW.name_company, '') <> '' THEN ' ' ELSE '' END || - COALESCE(NEW.name_company, '') || - CASE WHEN COALESCE(NEW.acronym, '') <> '' THEN ' ' ELSE '' END || - COALESCE(NEW.acronym, '') - ) - ) - ; - - return NEW; - END - $$ - "); - $this->addSql(" - UPDATE chill_3party.third_party - SET canonicalized = - UNACCENT( - LOWER( - name || - CASE WHEN COALESCE(name_company, '') <> '' THEN ' ' ELSE '' END || - COALESCE(name_company, '') || - CASE WHEN COALESCE(acronym, '') <> '' THEN ' ' ELSE '' END || - COALESCE(acronym, '') - ) - ) - "); } } From f2ae183682b7fc9de3972c0fafdba912e8da40aa Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 25 Mar 2022 13:01:33 +0100 Subject: [PATCH 024/294] first commit --- .../ReassignAccompanyingPeriodController.php | 19 +++++++++++++-- .../reassign_list.html.twig | 24 +++++++++++++++++-- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index 4abf5e93c..eb8dcc70e 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -19,6 +19,7 @@ use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\FormType; +use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -64,7 +65,9 @@ class ReassignAccompanyingPeriodController extends AbstractController throw new AccessDeniedException(); } - $form = $this->buildFilterForm(); + $periodIds = []; + + $form = $this->buildFilterForm($periodIds); $form->handleRequest($request); @@ -80,16 +83,25 @@ class ReassignAccompanyingPeriodController extends AbstractController $paginator->getCurrentPageFirstItemNumber() ); + foreach ($periods as $period) { + $periodIds[] = $period->getId(); + } + + $assignForm= $this->buildFilterForm($periodIds); + + dump($assignForm->get('periods')); + return new Response( $this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [ 'paginator' => $paginator, 'periods' => $periods, 'form' => $form->createView(), + 'assignForm' => $assignForm->createView() ]) ); } - private function buildFilterForm(): FormInterface + private function buildFilterForm(array $periodIds): FormInterface { $data = [ 'user' => null, @@ -107,6 +119,9 @@ class ReassignAccompanyingPeriodController extends AbstractController 'multiple' => false, 'label' => 'User', 'required' => false, + ]) + ->add('periods', HiddenType::class, [ + 'data' => serialize($periodIds), ]); return $builder->getForm(); diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig index 87166d990..2b36a175f 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -14,7 +14,7 @@ {% if is_granted('CHILL_PERSON_ACCOMPANYING_PERIOD_UPDATE', period) %}
{% set job_id = null %} - {% if period.job is defined %} + {% if period.job is defined and period.job is not null %} {% set job_id = period.job.id %} {% endif %}
  • {{ form_end(form) }} +
    +

    {{ 'Attribute all parcours in this list to the following users,'|trans }}

    + {{ form_start(assignForm) }} +
    +
    + {{ form_label(assignForm.user ) }} + {{ form_widget(assignForm.user, {'attr': {'class': 'select2'}}) }} +
    +
    + +
      +
    • + +
    • +
    + {{ form_end(assignForm) }} +
    + {% if form.user.vars.value is empty %}

    {{ 'period_by_user_list.Pick a user'|trans }}

    {% elseif periods|length == 0 and form.user.vars.value is not empty %} From bdcb135adbe50745b97d8e26695fd9050781e724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 25 Mar 2022 15:48:30 +0100 Subject: [PATCH 025/294] re-introduce link to create user --- .../ChillMainBundle/Resources/views/User/index.html.twig | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig b/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig index 5a558b6a0..83a82f140 100644 --- a/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig +++ b/src/Bundle/ChillMainBundle/Resources/views/User/index.html.twig @@ -59,4 +59,10 @@ {{ chill_pagination(paginator) }} -{% endblock %} \ No newline at end of file + + +{% endblock %} From 79630765055d2aa8cca508ce438f4d84435a6c27 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 25 Mar 2022 16:59:05 +0100 Subject: [PATCH 026/294] attempts to submit reassign form --- .../ReassignAccompanyingPeriodController.php | 127 ++++++++++++++++-- .../reassign_list.html.twig | 48 ++++--- 2 files changed, 143 insertions(+), 32 deletions(-) diff --git a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php index eb8dcc70e..05dd70cb4 100644 --- a/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php +++ b/src/Bundle/ChillPersonBundle/Controller/ReassignAccompanyingPeriodController.php @@ -16,10 +16,12 @@ use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Repository\UserRepository; use Chill\MainBundle\Templating\Entity\UserRender; use Chill\PersonBundle\Repository\AccompanyingPeriodACLAwareRepositoryInterface; +use Chill\PersonBundle\Repository\AccompanyingPeriodRepository; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\Extension\Core\Type\FormType; -use Symfony\Component\Form\Extension\Core\Type\HiddenType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -45,7 +47,21 @@ class ReassignAccompanyingPeriodController extends AbstractController private UserRepository $userRepository; - public function __construct(AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, UserRepository $userRepository, EngineInterface $engine, FormFactoryInterface $formFactory, PaginatorFactory $paginatorFactory, Security $security, UserRender $userRender) + private AccompanyingPeriodRepository $courseRepository; + + private EntityManagerInterface $em; + + public function __construct( + AccompanyingPeriodACLAwareRepositoryInterface $accompanyingPeriodACLAwareRepository, + UserRepository $userRepository, + AccompanyingPeriodRepository $courseRepository, + EngineInterface $engine, + FormFactoryInterface $formFactory, + PaginatorFactory $paginatorFactory, + Security $security, + UserRender $userRender, + EntityManagerInterface $em + ) { $this->accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; $this->engine = $engine; @@ -54,6 +70,8 @@ class ReassignAccompanyingPeriodController extends AbstractController $this->security = $security; $this->userRepository = $userRepository; $this->userRender = $userRender; + $this->courseRepository = $courseRepository; + $this->em = $em; } /** @@ -65,9 +83,7 @@ class ReassignAccompanyingPeriodController extends AbstractController throw new AccessDeniedException(); } - $periodIds = []; - - $form = $this->buildFilterForm($periodIds); + $form = $this->buildFilterForm(); $form->handleRequest($request); @@ -83,14 +99,66 @@ class ReassignAccompanyingPeriodController extends AbstractController $paginator->getCurrentPageFirstItemNumber() ); - foreach ($periods as $period) { - $periodIds[] = $period->getId(); + // foreach ($periods as $period) { + // $periodIds[] = $period->getId(); + // } + + // $assignForm= $this->buildReassignForm($periods); + $assignData = []; + $assignForm = $this->createFormBuilder($assignData) + ->add('periods', ChoiceType::class, [ + // 'data' => serialize($periods), + 'choices' => $periods, + 'multiple' => true, + 'expanded' => true + ]) + ->add('user', EntityType::class, [ + 'class' => User::class, + 'choices' => $this->userRepository->findByActive(['username' => 'ASC']), + 'choice_label' => function (User $u) { + return $this->userRender->renderString($u, []); + }, + 'placeholder' => 'Choose a user to reassign to', + 'multiple' => false, + 'label' => 'User', + 'required' => true, + ]) + ->getForm(); + + $assignForm->handleRequest($request); + + if ($assignForm->isSubmitted()) { + + $periods = $assignForm->get('periods')->getData(); + $userAssign = $assignForm->get('user')->getData(); + + foreach($periods as $periodId) { + $reassignPeriod = $this->courseRepository->find($periodId); + $reassignPeriod->setUser($userAssign); + $this->em->persist($reassignPeriod); + } + + $this->em->flush(); + + $remainingPeriods = $this->accompanyingPeriodACLAwareRepository + ->findByUserOpenedAccompanyingPeriod( + $form['user']->getData(), + ['openingDate' => 'ASC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + return new Response( + $this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [ + 'paginator' => $paginator, + 'periods' => $remainingPeriods, + 'form' => $form->createView(), + 'assignForm' => $assignForm->createView() + ]) + ); + } - $assignForm= $this->buildFilterForm($periodIds); - - dump($assignForm->get('periods')); - return new Response( $this->engine->render('@ChillPerson/AccompanyingPeriod/reassign_list.html.twig', [ 'paginator' => $paginator, @@ -101,7 +169,7 @@ class ReassignAccompanyingPeriodController extends AbstractController ); } - private function buildFilterForm(array $periodIds): FormInterface + private function buildFilterForm(): FormInterface { $data = [ 'user' => null, @@ -119,9 +187,40 @@ class ReassignAccompanyingPeriodController extends AbstractController 'multiple' => false, 'label' => 'User', 'required' => false, + ]); + // ->add('periods', HiddenType::class, [ + // 'data' => serialize($periodIds), + // ]); + + return $builder->getForm(); + } + + private function buildReassignForm(array $periods): FormInterface + { + $defaultData = [ + 'user' => [], + 'periods' => $periods + ]; + + $builder = $this->formFactory->createBuilder(FormType::class, $defaultData, ['csrf_protection' => false, ]); + + $builder + ->add('periods', ChoiceType::class, [ + // 'data' => serialize($periods), + 'choices' => $periods, + 'multiple' => true, + 'expanded' => true ]) - ->add('periods', HiddenType::class, [ - 'data' => serialize($periodIds), + ->add('user', EntityType::class, [ + 'class' => User::class, + 'choices' => $this->userRepository->findByActive(['username' => 'ASC']), + 'choice_label' => function (User $u) { + return $this->userRender->renderString($u, []); + }, + 'placeholder' => 'Choose a user to reassign to', + 'multiple' => false, + 'label' => 'User', + 'required' => true, ]); return $builder->getForm(); diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig index 2b36a175f..201925188 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/reassign_list.html.twig @@ -59,15 +59,37 @@ {{ form_end(form) }} -
    -

    {{ 'Attribute all parcours in this list to the following users,'|trans }}

    + {% if form.user.vars.value is empty %} +

    {{ 'period_by_user_list.Pick a user'|trans }}

    + {% elseif periods|length == 0 and form.user.vars.value is not empty %} +

    {{ 'period_by_user_list.Any course or no authorization to see them'|trans }}

    + {% else %} +

    {{ 'Attribute parcours in this list to the following user,'|trans }}

    +

    {{ paginator.totalItems }} parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})

    + +
    +
    + {{ form_label(assignForm.user ) }} + {{ form_widget(assignForm.user, {'attr': {'class': 'select2'}}) }} +
    +
    + {{ form_start(assignForm) }} -
    -
    - {{ form_label(assignForm.user ) }} - {{ form_widget(assignForm.user, {'attr': {'class': 'select2'}}) }} +
    +
    + {% for choice in assignForm.periods.vars.choices %} +
    + + +
    + {% endfor %}
    + {% do assignForm.periods.setRendered() %}
    • @@ -77,22 +99,12 @@
    {{ form_end(assignForm) }} -
    - - {% if form.user.vars.value is empty %} -

    {{ 'period_by_user_list.Pick a user'|trans }}

    - {% elseif periods|length == 0 and form.user.vars.value is not empty %} -

    {{ 'period_by_user_list.Any course or no authorization to see them'|trans }}

    - - {% else %} -

    {{ paginator.totalItems }} parcours à réassigner (calculé ce jour à {{ null|format_time('medium') }})

    - -
    + {#
    {% for period in periods %} {% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, 'recordAction': m.period_actions(period), 'itemMeta': m.period_meta(period) } %} {% endfor %} -
    +
    #} {% endif %} {{ chill_pagination(paginator) }} From 632ea710c81b8b14172ba807b802bed933fb8a65 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 25 Mar 2022 17:05:41 +0100 Subject: [PATCH 027/294] budget menu entry placed in different order --- CHANGELOG.md | 1 + src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php | 2 +- src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af1105275..3543c3de3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,7 @@ and this project adheres to * [household] Within parcours listing page of household add create button (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/560) * [person_resource] bugfix when adding thirdparty or freetext resource + prevent personOwner themselves to be added. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/526) * [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529) +* [budget] order within the menu adjusted (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/592) ## Test releases diff --git a/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php index e983ddebb..f8033da7d 100644 --- a/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php +++ b/src/Bundle/ChillBudgetBundle/Menu/HouseholdMenuBuilder.php @@ -42,7 +42,7 @@ class HouseholdMenuBuilder implements LocalMenuBuilderInterface 'routeParameters' => [ 'id' => $household->getId(), ], ]) - ->setExtras(['order' => 50]); + ->setExtras(['order' => 19]); // } } diff --git a/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php b/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php index 047185b18..fdd38ac08 100644 --- a/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php +++ b/src/Bundle/ChillBudgetBundle/Menu/PersonMenuBuilder.php @@ -44,7 +44,7 @@ class PersonMenuBuilder implements LocalMenuBuilderInterface 'routeParameters' => ['id' => $person->getId()], ] ) - ->setExtra('order', 4000); + ->setExtra('order', 59); } } From 1812592d43c52116d0364ac145482cfdf746baef Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 25 Mar 2022 17:22:10 +0100 Subject: [PATCH 028/294] fix create person on the fly --- .../public/vuejs/OnTheFly/components/OnTheFly.vue | 8 ++++++-- .../ChillMainBundle/Resources/public/vuejs/_js/i18n.js | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue index 979f53d74..669c225dd 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/OnTheFly/components/OnTheFly.vue @@ -235,8 +235,12 @@ export default { type = this.$refs.castNew.radioType; data = this.$refs.castNew.castDataByType(); // console.log('type', type); - data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null; - data.profession = data.profession !== null ? {type: 'third_party_profession', id: data.profession.id} : null; + if (typeof data.civility !== 'undefined' && null !== data.civility) { + data.civility = data.civility !== null ? {type: 'chill_main_civility', id: data.civility.id} : null; + } + if (typeof data.civility !== 'undefined' && null !== data.profession) { + data.profession = data.profession !== null ? {type: 'third_party_profession', id: data.profession.id} : null; + } // console.log('onthefly data', data); } } else { diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.js b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.js index 6ae44be41..1371989ba 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.js +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/_js/i18n.js @@ -69,7 +69,7 @@ const messages = { person: "Usager" }, holder: "Titulaire", - years_old: "an | {n} an | {n} ans", + years_old: "1 an | {n} an | {n} ans", residential_address: "Adresse de résidence", located_at: "réside chez" } From 58953342441172ee30d475e373ca078d40b1ec14 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Fri, 25 Mar 2022 17:23:14 +0100 Subject: [PATCH 029/294] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad392cea2..bdd739444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -73,6 +73,7 @@ and this project adheres to * [person_resource] bugfix when adding thirdparty or freetext resource + prevent personOwner themselves to be added. (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/526) * [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529) * [budget] order within the menu adjusted (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/592) +* [onthefly] fix create person. Bug was noticed in filiation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/591) ## Test releases From 6f270188f7a626fc0f100d2ea5e996456ae2aa79 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Mon, 28 Mar 2022 11:22:42 +0200 Subject: [PATCH 030/294] buttons made sticky for parcours documents --- CHANGELOG.md | 1 + .../Resources/views/AccompanyingCourseDocument/new.html.twig | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdd739444..2e213d2b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,6 +74,7 @@ and this project adheres to * [aside_activity] style correction + sticky-form create button (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/529) * [budget] order within the menu adjusted (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/592) * [onthefly] fix create person. Bug was noticed in filiation (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/591) +* [parcours] Create document buttons made sticky (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/532) ## Test releases diff --git a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/new.html.twig b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/new.html.twig index d76e5a745..94cfb8828 100644 --- a/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/new.html.twig +++ b/src/Bundle/ChillDocStoreBundle/Resources/views/AccompanyingCourseDocument/new.html.twig @@ -23,7 +23,7 @@ {{ form_row(form.description) }} {{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }} - {{ form_end(form) }} From a70c56159631ab8e18c48f231c33e982a1e52183 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 20 Apr 2022 16:23:08 +0200 Subject: [PATCH 175/294] Number of parcours of user displayed in blue pill --- CHANGELOG.md | 1 + .../views/AccompanyingPeriod/user_periods_list.html.twig | 2 ++ src/Bundle/ChillPersonBundle/translations/messages.fr.yml | 1 + 3 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index da3ee1a3a..e8201ceb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to * [notification email on course designation] allow raw string in email content generation * [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older * [Documents] Change wording 'créer' to 'enregistrer' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/634) +* [Parcours]: The number of 'mes parcours' displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/572) ## Test releases diff --git a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig index 7395fceda..031e0728c 100644 --- a/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig +++ b/src/Bundle/ChillPersonBundle/Resources/views/AccompanyingPeriod/user_periods_list.html.twig @@ -17,6 +17,8 @@

    {{ 'My accompanying periods'|trans }}

    +

    {{ 'Number of periods'|trans }}: {{ pagination.totalItems }}

    +
    {% for period in accompanyingPeriods %} {% include '@ChillPerson/AccompanyingPeriod/_list_item.html.twig' with {'period': period, 'recordAction': _self.recordAction(period)} %} diff --git a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml index c6baf9513..2a4077e1c 100644 --- a/src/Bundle/ChillPersonBundle/translations/messages.fr.yml +++ b/src/Bundle/ChillPersonBundle/translations/messages.fr.yml @@ -581,6 +581,7 @@ Linked evaluations: Évaluations associées # Accompanying period per user My accompanying periods: Mes parcours My accompanying periods in draft: Mes parcours brouillons +Number of periods: Nombre de parcours workflow: Doc for evaluation (n°%eval%): Document de l'évaluation n°%eval% From 9a0eb1c74c60ca5d3623c22621aea3977e8a045f Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Wed, 20 Apr 2022 16:33:05 +0200 Subject: [PATCH 176/294] Renaming of tabs and removal of social actions tab --- CHANGELOG.md | 1 + .../public/vuejs/HomepageWidget/App.vue | 6 +-- .../public/vuejs/HomepageWidget/MyWorks.vue | 1 + .../public/vuejs/HomepageWidget/js/i18n.js | 6 +-- .../public/vuejs/HomepageWidget/js/store.js | 50 +++++++++---------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8201ceb6..e074d731f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to * [Accompanying period work] list evaluations associated to a work by startDate, and then by id, from the most recent to older * [Documents] Change wording 'créer' to 'enregistrer' (https://gitlab.com/champs-libres/departement-de-la-vendee/accent-suivi-developpement/-/issues/634) * [Parcours]: The number of 'mes parcours' displayed (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/572) +* [Hompage_widget]: Renaming of tabs and removal of social actions tab (https://gitlab.com/champs-libres/departement-de-la-vendee/chill/-/issues/570) ## Test releases diff --git a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue index 343b638da..fbf453b47 100644 --- a/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue +++ b/src/Bundle/ChillMainBundle/Resources/public/vuejs/HomepageWidget/App.vue @@ -25,14 +25,14 @@ {{ $t('my_accompanying_courses.tab') }} -