cs: Fix code style (safe rules only).

This commit is contained in:
Pol Dellaiera
2021-11-23 14:06:38 +01:00
parent 149d7ce991
commit 8f96a1121d
1223 changed files with 65199 additions and 64625 deletions

View File

@@ -1,10 +1,17 @@
<?php
/**
* 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\ThirdPartyBundle;
use Chill\ThirdPartyBundle\DependencyInjection\CompilerPass\ThirdPartyTypeCompilerPass;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeProviderInterface;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Chill\ThirdPartyBundle\DependencyInjection\CompilerPass\ThirdPartyTypeCompilerPass;
class ChillThirdPartyBundle extends Bundle
{
@@ -15,5 +22,4 @@ class ChillThirdPartyBundle extends Bundle
->addTag('chill_3party.provider');
$container->addCompilerPass(new ThirdPartyTypeCompilerPass());
}
}

View File

@@ -1,55 +1,51 @@
<?php
/**
* 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\ThirdPartyBundle\Controller;
use Chill\MainBundle\CRUD\Controller\AbstractCRUDController;
use Chill\MainBundle\CRUD\Controller\CRUDController;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Pagination\PaginatorInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Repository\ThirdPartyACLAwareRepositoryInterface;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use http\Exception\RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use LogicException;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Doctrine\Common\Collections\ArrayCollection;
use Chill\ThirdPartyBundle\Form\ThirdPartyType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Security\Core\Role\Role;
use Chill\MainBundle\Pagination\PaginatorFactory;
use function array_merge;
final class ThirdPartyController extends CRUDController
{
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var PaginatorFactory
*/
protected $paginatorFactory;
protected RequestStack $requestStack;
protected ThirdPartyACLAwareRepositoryInterface $thirdPartyACLAwareRepository;
protected RequestStack $requestStack;
/**
* @var TranslatorInterface
*/
protected $translator;
public function __construct(
AuthorizationHelper $authorizationHelper,
@@ -65,21 +61,57 @@ final class ThirdPartyController extends CRUDController
$this->thirdPartyACLAwareRepository = $thirdPartyACLAwareRepository;
}
protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper
{
return $this->getFilterOrderHelperFactory()
->create(self::class)
->addSearchBox(['name', 'company_name', 'acronym'])
//->addToggle('only-active', [])
// ->addOrderBy()
->build();
}
protected function countEntities(string $action, Request $request, ?FilterOrderHelper $filterOrder = null): int
{
if (NULL === $filterOrder){
throw new \LogicException('filterOrder should not be null');
if (null === $filterOrder) {
throw new LogicException('filterOrder should not be null');
}
return $this->thirdPartyACLAwareRepository->countThirdParties(ThirdPartyVoter::SHOW,
$filterOrder->getQueryString());
return $this->thirdPartyACLAwareRepository->countThirdParties(
ThirdPartyVoter::SHOW,
$filterOrder->getQueryString()
);
}
protected function createFormFor(string $action, $entity, ?string $formClass = null, array $formOptions = []): FormInterface
{
if ('new' === $action) {
return parent::createFormFor($action, $entity, $formClass, array_merge(
$formOptions,
['kind' => $this->requestStack->getCurrentRequest()->query->getAlpha('kind')]
));
}
if ('edit' === $action) {
return parent::createFormFor($action, $entity, $formClass, array_merge(
$formOptions,
['kind' => $entity->getKind()]
));
}
return parent::createFormFor($action, $entity, $formClass, $formOptions);
}
protected function getQueryResult(string $action, Request $request, int $totalItems, PaginatorInterface $paginator, ?FilterOrderHelper $filterOrder = null)
{
return $this->thirdPartyACLAwareRepository
->listThirdParties(ThirdPartyVoter::SHOW, $filterOrder->getQueryString(), ['name' => 'ASC'], $paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber());
->listThirdParties(
ThirdPartyVoter::SHOW,
$filterOrder->getQueryString(),
['name' => 'ASC'],
$paginator->getItemsPerPage(),
$paginator->getCurrentPageFirstItemNumber()
);
}
protected function onPostCheckACL($action, Request $request, $entity): ?Response
@@ -93,42 +125,16 @@ final class ThirdPartyController extends CRUDController
if ('new' === $action) {
if (!$request->query->has('kind')) {
return $this->render('@ChillThirdParty/ThirdParty/new_pick_kind.html.twig');
} else {
$kind = $request->query->getAlpha('kind', '');
if (!(ThirdParty::KIND_COMPANY === $kind || ThirdParty::KIND_CONTACT === $kind)) {
throw new BadRequestHttpException('This kind is not supported: '.$kind);
}
$entity->setKind($kind);
}
$kind = $request->query->getAlpha('kind', '');
if (!(ThirdParty::KIND_COMPANY === $kind || ThirdParty::KIND_CONTACT === $kind)) {
throw new BadRequestHttpException('This kind is not supported: ' . $kind);
}
$entity->setKind($kind);
}
return null;
}
protected function createFormFor(string $action, $entity, string $formClass = null, array $formOptions = []): FormInterface
{
if ('new' === $action) {
return parent::createFormFor($action, $entity, $formClass, \array_merge(
$formOptions, [ 'kind' => $this->requestStack->getCurrentRequest()->query->getAlpha('kind')]
));
} elseif ('edit' === $action) {
return parent::createFormFor($action, $entity, $formClass, \array_merge(
$formOptions, [ 'kind' => $entity->getKind()]
));
}
return parent::createFormFor($action, $entity, $formClass, $formOptions);
}
protected function buildFilterOrderHelper(string $action, Request $request): ?FilterOrderHelper
{
return $this->getFilterOrderHelperFactory()
->create(self::class)
->addSearchBox(['name', 'company_name', 'acronym'])
//->addToggle('only-active', [])
// ->addOrderBy()
->build();
}
}

View File

@@ -1,21 +1,38 @@
<?php
/**
* 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\ThirdPartyBundle\DataFixtures\ORM;
use Chill\MainBundle\DataFixtures\ORM\LoadCenters;
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\PostalCode;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateTimeImmutable;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Persistence\ObjectManager;
use Doctrine\Common\DataFixtures\DependentFixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Iterator;
use Nelmio\Alice\Loader\NativeLoader;
use Nelmio\Alice\ObjectSet;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\MainBundle\Entity\Address;
use Doctrine\ORM\EntityManagerInterface;
use function array_map;
class LoadThirdParty extends Fixture Implements DependentFixtureInterface
class LoadThirdParty extends Fixture implements DependentFixtureInterface
{
public function getDependencies()
{
return [
LoadCenters::class,
LoadPostalCodes::class,
];
}
public function load(ObjectManager $manager)
{
$thirdParties = $this->getThirdParties()->getObjects();
@@ -25,10 +42,10 @@ class LoadThirdParty extends Fixture Implements DependentFixtureInterface
// this is an address
continue;
}
$thirdParty->setCreatedAt(new \DateTimeImmutable('today'));
$thirdParty->setCreatedAt(new DateTimeImmutable('today'));
foreach ($this->getCenters() as $center) {
$thirdParty->addCenter($center);
$thirdParty->addCenter($center);
}
$manager->persist($thirdParty);
@@ -37,13 +54,31 @@ class LoadThirdParty extends Fixture Implements DependentFixtureInterface
$manager->flush();
}
private function getCenters(): \Iterator
private function createAddress(): ObjectSet
{
$references = \array_map(function($a) { return $a['ref']; },
LoadCenters::$centers);
$loader = new NativeLoader();
return $loader->loadData([
Address::class => [
'address1' => [
'name' => '<fr_FR:company()>',
'telephone' => '<fr_FR:phonenumber()>',
'email' => '<email()>',
'comment' => '<fr_FR:realTextBetween(10, 500)>',
],
],
]);
}
private function getCenters(): Iterator
{
$references = array_map(
function ($a) { return $a['ref']; },
LoadCenters::$centers
);
$number = random_int(1, count($references));
if ($number === 1) {
if (1 === $number) {
yield $this->getReference($references[\array_rand($references)]);
} else {
foreach (array_rand($references, $number) as $index) {
@@ -52,40 +87,6 @@ class LoadThirdParty extends Fixture Implements DependentFixtureInterface
}
}
public function getDependencies()
{
return [
LoadCenters::class,
LoadPostalCodes::class
];
}
private function getThirdParties(): ObjectSet
{
$loader = new NativeLoader();
$objectSet = $loader->loadData([
Address::class => [
'address{1..75}' => [
'street' => '<fr_FR:streetName()>',
'streetNumber' => '<fr_FR:buildingNumber()>',
'validFrom' => '<dateTimeBetween(\'-1 year\', \'now\')>',
'postCode' => $this->getPostalCode()
],
],
ThirdParty::class => [
'thirdparty{1..75}' => [
'name' => '<fr_FR:company()>',
'telephone' => '<fr_FR:phonenumber()>',
'email' => '<email()>',
'comment' => '<fr_FR:realTextBetween(10, 500)>',
'address' => '@address<current()>'
]
]
]);
return $objectSet;
}
private function getPostalCode(): PostalCode
{
$ref = LoadPostalCodes::$refs[\array_rand(LoadPostalCodes::$refs)];
@@ -93,22 +94,28 @@ class LoadThirdParty extends Fixture Implements DependentFixtureInterface
return $this->getReference($ref);
}
private function createAddress(): ObjectSet
private function getThirdParties(): ObjectSet
{
$loader = new NativeLoader();
$objectSet = $loader->loadData([
return $loader->loadData([
Address::class => [
'address1' => [
'address{1..75}' => [
'street' => '<fr_FR:streetName()>',
'streetNumber' => '<fr_FR:buildingNumber()>',
'validFrom' => '<dateTimeBetween(\'-1 year\', \'now\')>',
'postCode' => $this->getPostalCode(),
],
],
ThirdParty::class => [
'thirdparty{1..75}' => [
'name' => '<fr_FR:company()>',
'telephone' => '<fr_FR:phonenumber()>',
'email' => '<email()>',
'comment' => '<fr_FR:realTextBetween(10, 500)>'
]
]
'comment' => '<fr_FR:realTextBetween(10, 500)>',
'address' => '@address<current()>',
],
],
]);
return $objectSet;
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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\ThirdPartyBundle\DataFixtures\ORM;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
@@ -8,9 +15,7 @@ use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Persistence\ObjectManager;
/**
* Class LoadThirdPartyCategory
* @package Chill\ThirdPartyBundle\DataFixtures\ORM
* @author Mathieu Jaumotte mathieu.jaumotte@champs-libres.coop
* Class LoadThirdPartyCategory.
*/
class LoadThirdPartyCategory extends Fixture implements FixtureGroupInterface
{
@@ -22,19 +27,19 @@ class LoadThirdPartyCategory extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager)
{
$categories = [
['name' => ['fr' => "maison médicale" ]],
['name' => ['fr' => "hôpital" ]],
['name' => ['fr' => "médecin généraliste" ]],
['name' => ['fr' => "pharmacien" ]],
['name' => ['fr' => "assistance aux personnes âgées" ]],
['name' => ['fr' => "assistante maternelle" ]],
['name' => ['fr' => "assistant social" ]],
['name' => ['fr' => "éducateur spécialisé" ]],
['name' => ['fr' => "infirmier.ère" ]],
['name' => ['fr' => 'maison médicale']],
['name' => ['fr' => 'hôpital']],
['name' => ['fr' => 'médecin généraliste']],
['name' => ['fr' => 'pharmacien']],
['name' => ['fr' => 'assistance aux personnes âgées']],
['name' => ['fr' => 'assistante maternelle']],
['name' => ['fr' => 'assistant social']],
['name' => ['fr' => 'éducateur spécialisé']],
['name' => ['fr' => 'infirmier.ère']],
];
foreach ( $categories as $val) {
print "Creating thirdparty category : " . $val['name']['fr'] . "\n";
foreach ($categories as $val) {
echo 'Creating thirdparty category : ' . $val['name']['fr'] . "\n";
$category = (new ThirdPartyCategory())
->setName($val['name'])
->setActive(true);

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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\ThirdPartyBundle\DataFixtures\ORM;
use Chill\ThirdPartyBundle\Entity\ThirdPartyProfession;
@@ -8,9 +15,7 @@ use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Persistence\ObjectManager;
/**
* Class LoadThirdPartyProfession
* @package Chill\ThirdPartyBundle\DataFixtures\ORM
* @author Mathieu Jaumotte mathieu.jaumotte@champs-libres.coop
* Class LoadThirdPartyProfession.
*/
class LoadThirdPartyProfession extends Fixture implements FixtureGroupInterface
{
@@ -22,17 +27,17 @@ class LoadThirdPartyProfession extends Fixture implements FixtureGroupInterface
public function load(ObjectManager $manager)
{
$professions = [
['name' => ['fr' => "Directeur" ]],
['name' => ['fr' => "Docteur" ]],
['name' => ['fr' => "Médecin" ]],
['name' => ['fr' => "Opérateur" ]],
['name' => ['fr' => "Personnel administratif" ]],
['name' => ['fr' => "Président" ]],
['name' => ['fr' => "Responsable infirmier.ère" ]],
['name' => ['fr' => 'Directeur']],
['name' => ['fr' => 'Docteur']],
['name' => ['fr' => 'Médecin']],
['name' => ['fr' => 'Opérateur']],
['name' => ['fr' => 'Personnel administratif']],
['name' => ['fr' => 'Président']],
['name' => ['fr' => 'Responsable infirmier.ère']],
];
foreach ( $professions as $val) {
print "Creating thirdparty professions : " . $val['name']['fr'] . "\n";
foreach ($professions as $val) {
echo 'Creating thirdparty professions : ' . $val['name']['fr'] . "\n";
$profession = (new ThirdPartyProfession())
->setName($val['name'])
->setActive(true);

View File

@@ -1,35 +1,38 @@
<?php
/**
* 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\ThirdPartyBundle\DependencyInjection;
use Chill\ThirdPartyBundle\Controller\ThirdPartyController;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Form\ThirdPartyType;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
/**
* This is the class that loads and manages your bundle configuration.
*
* @link http://symfony.com/doc/current/cookbook/bundles/extension.html
* @see http://symfony.com/doc/current/cookbook/bundles/extension.html
*/
class ChillThirdPartyExtension extends Extension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../config'));
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../config'));
$loader->load('services.yaml');
$loader->load('services/controller.yaml');
$loader->load('services/form.yaml');
@@ -49,15 +52,25 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
$this->prependRoleHierarchy($container);
}
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', [
'role_hierarchy' => [
ThirdPartyVoter::CREATE => [ThirdPartyVoter::SHOW],
ThirdPartyVoter::UPDATE => [ThirdPartyVoter::SHOW],
],
]);
}
protected function preprendRoutes(ContainerBuilder $container)
{
//declare routes for 3party bundle
$container->prependExtensionConfig('chill_main', array(
'routing' => [
'resources' => array(
'@ChillThirdPartyBundle/config/routes.yaml'
)
],
$container->prependExtensionConfig('chill_main', [
'routing' => [
'resources' => [
'@ChillThirdPartyBundle/config/routes.yaml',
],
],
'cruds' => [
[
'class' => ThirdParty::class,
@@ -81,10 +94,9 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
'view' => [
'template' => '@ChillThirdParty/ThirdParty/view.html.twig',
'role' => ThirdPartyVoter::SHOW,
]
]
]
],
],
],
],
'apis' => [
[
@@ -100,29 +112,19 @@ class ChillThirdPartyExtension extends Extension implements PrependExtensionInte
Request::METHOD_HEAD => true,
Request::METHOD_POST => true,
Request::METHOD_PUT => true,
Request::METHOD_PATCH => true
Request::METHOD_PATCH => true,
],
'roles' => [
Request::METHOD_GET => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::SHOW,
Request::METHOD_HEAD => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::SHOW,
Request::METHOD_POST => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::CREATE,
Request::METHOD_PUT => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::CREATE,
Request::METHOD_PATCH => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::CREATE
Request::METHOD_PATCH => \Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter::CREATE,
],
]
]
]
],
],
],
],
));
}
protected function prependRoleHierarchy(ContainerBuilder $container)
{
$container->prependExtensionConfig('security', array(
'role_hierarchy' => array(
ThirdPartyVoter::CREATE => [ThirdPartyVoter::SHOW],
ThirdPartyVoter::UPDATE => [ThirdPartyVoter::SHOW],
)
));
]);
}
}

View File

@@ -1,38 +1,48 @@
<?php
/**
* 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\ThirdPartyBundle\DependencyInjection\CompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
use LogicException;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use function in_array;
/**
* Load services tagged chill_3party.provider and add them to the service
* definition of manager
*
* Load services tagged chill_3party.provider and add them to the service
* definition of manager.
*/
class ThirdPartyTypeCompilerPass implements CompilerPassInterface
{
const TAG = 'chill_3party.provider';
public const TAG = 'chill_3party.provider';
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition(ThirdPartyTypeManager::class);
$usedKeys = [];
foreach ($container->findTaggedServiceIds(self::TAG) as $id => $tags) {
$taggedService = $container->getDefinition($id);
// check forr keys already in use :
$key = $taggedService->getClass()::getKey();
if (\in_array($key, $usedKeys)) {
throw new \LogicException(sprintf("Tag with key \"%s\" is already in used",
$key));
if (in_array($key, $usedKeys)) {
throw new LogicException(sprintf(
'Tag with key "%s" is already in used',
$key
));
}
$usedKeys[] = $key;
// alter the service definition of manager
$definition->addMethodCall('addProvider', [ new Reference($id) ]);
$definition->addMethodCall('addProvider', [new Reference($id)]);
}
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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\ThirdPartyBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
@@ -12,9 +19,6 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder('chill_third_party');

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ThirdPartyBundle\Entity;
@@ -31,6 +18,11 @@ use Doctrine\ORM\Mapping as ORM;
*/
class ThirdPartyCategory
{
/**
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -43,10 +35,10 @@ class ThirdPartyCategory
*/
private $name = [];
/**
* @ORM\Column(type="boolean")
*/
private $active = true;
public function getActive(): ?bool
{
return $this->active;
}
public function getId(): ?int
{
@@ -58,22 +50,17 @@ class ThirdPartyCategory
return $this->name;
}
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
}

View File

@@ -1,23 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ThirdPartyBundle\Entity;
@@ -31,6 +18,11 @@ use Doctrine\ORM\Mapping as ORM;
*/
class ThirdPartyProfession
{
/**
* @ORM\Column(type="boolean")
*/
private $active = true;
/**
* @ORM\Id
* @ORM\GeneratedValue
@@ -43,10 +35,10 @@ class ThirdPartyProfession
*/
private $name = [];
/**
* @ORM\Column(type="boolean")
*/
private $active = true;
public function getActive(): ?bool
{
return $this->active;
}
public function getId(): ?int
{
@@ -58,22 +50,17 @@ class ThirdPartyProfession
return $this->name;
}
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
public function getActive(): ?bool
{
return $this->active;
}
public function setActive(bool $active): self
{
$this->active = $active;
return $this;
}
public function setName(array $name): self
{
$this->name = $name;
return $this;
}
}

View File

@@ -1,45 +1,49 @@
<?php
/*
/**
* 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\ThirdPartyBundle\Form\ChoiceLoader;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Doctrine\ORM\EntityRepository;
use Chill\MainBundle\Entity\Center;
use Doctrine\ORM\EntityRepository;
use RuntimeException;
use Symfony\Component\Form\ChoiceList\ArrayChoiceList;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Loader\ChoiceLoaderInterface;
use function call_user_func;
use function in_array;
/**
* Lazy load third parties.
*
*/
class ThirdPartyChoiceLoader implements ChoiceLoaderInterface
{
/**
*
* @var \Chill\ThirdPartyBundle\Entity\ThirdParty[]
*/
protected $lazyLoadedParties = [];
/**
*
* @var Center
*/
protected $center;
/**
* @var \Chill\ThirdPartyBundle\Entity\ThirdParty[]
*/
protected $lazyLoadedParties = [];
/**
*
* @var EntityRepository
*/
protected $partyRepository;
public function __construct(Center $center, EntityRepository $partyRepository)
{
$this->center = $center;
$this->partyRepository = $partyRepository;
}
public function loadChoiceList($value = null): ChoiceListInterface
{
return new ArrayChoiceList($this->lazyLoadedParties, $value);
@@ -48,39 +52,40 @@ class ThirdPartyChoiceLoader implements ChoiceLoaderInterface
public function loadChoicesForValues($values, $value = null)
{
$choices = [];
foreach($values as $value) {
foreach ($values as $value) {
if (empty($value)) {
continue;
}
$party = $this->partyRepository->find($value);
if (FALSE === \in_array($this->center, $party->getCenters()->toArray())) {
throw new \RuntimeException("the party's center is not authorized");
if (false === in_array($this->center, $party->getCenters()->toArray())) {
throw new RuntimeException("the party's center is not authorized");
}
$choices[] = $party;
}
return $choices;
}
public function loadValuesForChoices(array $choices, $value = null)
{
$values = [];
foreach ($choices as $choice) {
if (NULL === $choice) {
if (null === $choice) {
$values[] = null;
continue;
}
$id = \call_user_func($value, $choice);
$id = call_user_func($value, $choice);
$values[] = $id;
$this->lazyLoadedParties[$id] = $choice;
}
return $values;
}
}

View File

@@ -1,51 +1,52 @@
<?php
/**
* 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\ThirdPartyBundle\Form;
use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Civility;
use Chill\MainBundle\Form\Type\ChillCollectionType;
use Chill\MainBundle\Form\Type\ChillTextareaType;
use Chill\MainBundle\Form\Type\PickAddressType;
use Chill\MainBundle\Form\Type\PickCenterType;
use Chill\MainBundle\Form\Type\ChillTextareaType;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use Chill\ThirdPartyBundle\Entity\ThirdPartyProfession;
use Chill\ThirdPartyBundle\Form\Type\PickThirdPartyType;
use Chill\ThirdPartyBundle\Form\Type\PickThirdPartyTypeCategoryType;
use Doctrine\ORM\EntityManager;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use function array_key_exists;
class ThirdPartyType extends AbstractType
{
protected AuthorizationHelper $authorizationHelper;
protected TokenStorageInterface $tokenStorage;
protected EntityManagerInterface $om;
protected ThirdPartyTypeManager $typesManager;
protected TokenStorageInterface $tokenStorage;
protected TranslatableStringHelper $translatableStringHelper;
protected EntityManagerInterface $om;
protected ThirdPartyTypeManager $typesManager;
private bool $askCenter;
@@ -65,35 +66,32 @@ class ThirdPartyType extends AbstractType
$this->askCenter = $parameterBag->get('chill_main')['acl']['form_show_centers'];
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [
'required' => true
'required' => true,
])
->add('telephone', TextType::class, [
'label' => 'Phonenumber',
'required' => false
'required' => false,
])
->add('email', EmailType::class, [
'required' => false
'required' => false,
])
->add('comment', ChillTextareaType::class, [
'required' => false
'required' => false,
]);
if ($this->askCenter) {
$builder
->add('centers', PickCenterType::class, [
'role' => (\array_key_exists('data', $options) && $this->om->contains($options['data'])) ?
'role' => (array_key_exists('data', $options) && $this->om->contains($options['data'])) ?
ThirdPartyVoter::UPDATE : ThirdPartyVoter::CREATE,
'choice_options' => [
'multiple' => true,
'attr' => ['class' => 'select2']
]
'attr' => ['class' => 'select2'],
],
]);
}
@@ -111,7 +109,7 @@ class ThirdPartyType extends AbstractType
->where('c.active = true');
},
'placeholder' => 'thirdparty.choose civility',
'required' => false
'required' => false,
])
->add('profession', EntityType::class, [
'label' => 'thirdparty.Profession',
@@ -124,19 +122,18 @@ class ThirdPartyType extends AbstractType
->where('p.active = true');
},
'placeholder' => 'thirdparty.choose profession',
'required' => false
'required' => false,
])
->add('contactDataAnonymous', CheckboxType::class, [
'required' => false,
'label' => 'thirdparty.Contact data are confidential'
])
;
'label' => 'thirdparty.Contact data are confidential',
]);
// Institutional ThirdParty (parent)
} else {
$builder
->add('address', PickAddressType::class, [
'label' => 'Address'
'label' => 'Address',
])
->add('address2', PickAddressType::class, [
'label' => 'Address',
@@ -146,11 +143,11 @@ class ThirdPartyType extends AbstractType
])
->add('nameCompany', TextType::class, [
'label' => 'thirdparty.NameCompany',
'required' => false
'required' => false,
])
->add('acronym', TextType::class, [
'label' => 'thirdparty.Acronym',
'required' => false
'required' => false,
])
->add('activeChildren', ChillCollectionType::class, [
'entry_type' => ThirdPartyType::class,
@@ -163,40 +160,35 @@ class ThirdPartyType extends AbstractType
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'button_add_label' => "Add a contact",
'button_remove_label' => "Remove a contact",
'empty_collection_explain' => "Any contact"
])
;
'button_add_label' => 'Add a contact',
'button_remove_label' => 'Remove a contact',
'empty_collection_explain' => 'Any contact',
]);
}
if (ThirdParty::KIND_CHILD !== $options['kind']) {
$builder
->add('typesAndCategories', PickThirdPartyTypeCategoryType::class, [
'label' => 'thirdparty.Categories'
'label' => 'thirdparty.Categories',
])
->add('active', ChoiceType::class, [
'label' => 'thirdparty.Status',
'choices' => [
'Active, shown to users' => true,
'Inactive, not shown to users' => false
'Inactive, not shown to users' => false,
],
'expanded' => true,
'multiple' => false
'multiple' => false,
]);
}
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
$resolver->setDefaults([
'data_class' => ThirdParty::class,
'is_child' => false,
'kind' => null
));
'kind' => null,
]);
}
}

View File

@@ -1,55 +1,55 @@
<?php
/*
*
*/
namespace Chill\ThirdPartyBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\OptionsResolver\Options;
use Chill\ThirdPartyBundle\Form\ChoiceLoader\ThirdPartyChoiceLoader;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Chill\ThirdPartyBundle\Search\ThirdPartySearch;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Chill\MainBundle\Search\SearchInterface;
/**
*
* 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\ThirdPartyBundle\Form\Type;
use Chill\MainBundle\Search\SearchInterface;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Form\ChoiceLoader\ThirdPartyChoiceLoader;
use Chill\ThirdPartyBundle\Search\ThirdPartySearch;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Translation\TranslatorInterface;
use function array_diff;
use function array_merge;
use function is_array;
class PickThirdPartyType extends AbstractType
{
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var UrlGeneratorInterface
*/
protected $urlGenerator;
/**
*
* @var TranslatorInterface
*/
protected $translator;
/**
*
* @var ThirdPartyTypeManager
*/
protected $typesManager;
/**
* @var UrlGeneratorInterface
*/
protected $urlGenerator;
public function __construct(
EntityManagerInterface $em,
UrlGeneratorInterface $urlGenerator,
EntityManagerInterface $em,
UrlGeneratorInterface $urlGenerator,
TranslatorInterface $translator,
ThirdPartyTypeManager $typesManager
) {
@@ -59,54 +59,55 @@ class PickThirdPartyType extends AbstractType
$this->typesManager = $typesManager;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setRequired('center')
->setAllowedTypes('center', [ \Chill\MainBundle\Entity\Center::class ])
->setDefined('types')
->setRequired('types')
->setAllowedValues('types', function($types) {
if (FALSE === \is_array($types)) {
return false;
}
// return false if one element is not contained in allowed types
return count(\array_diff($types, $this->typesManager->getTypes())) === 0;
})
;
$resolver
->setDefault('class', ThirdParty::class)
->setDefault('choice_label', function(ThirdParty $tp) {
return $tp->getName();
})
->setDefault('choice_loader', function(Options $options) {
return new ThirdPartyChoiceLoader($options['center'],
$this->em->getRepository(ThirdParty::class));
})
;
}
public function getParent(): string
{
return EntityType::class;
}
public function buildView(\Symfony\Component\Form\FormView $view, \Symfony\Component\Form\FormInterface $form, array $options)
{
$view->vars['attr']['class'] = \array_merge(['select2 '], $view->vars['attr']['class'] ?? []);
$view->vars['attr']['class'] = array_merge(['select2 '], $view->vars['attr']['class'] ?? []);
$view->vars['attr']['data-3party-picker'] = true;
$view->vars['attr']['data-select-interactive-loading'] = true;
$view->vars['attr']['data-search-url'] = $this->urlGenerator
->generate('chill_main_search', [
'name' => ThirdPartySearch::NAME,
SearchInterface::REQUEST_QUERY_KEY_ADD_PARAMETERS => ['t' => $options['types']],
'_format' => 'json' ]
);
->generate(
'chill_main_search',
[
'name' => ThirdPartySearch::NAME,
SearchInterface::REQUEST_QUERY_KEY_ADD_PARAMETERS => ['t' => $options['types']],
'_format' => 'json', ]
);
$view->vars['attr']['data-placeholder'] = $this->translator->trans($options['placeholder']);
$view->vars['attr']['data-no-results-label'] = $this->translator->trans('select2.no_results');
$view->vars['attr']['data-error-load-label'] = $this->translator->trans('select2.error_loading');
$view->vars['attr']['data-searching-label'] = $this->translator->trans('select2.searching');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setRequired('center')
->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class])
->setDefined('types')
->setRequired('types')
->setAllowedValues('types', function ($types) {
if (false === is_array($types)) {
return false;
}
// return false if one element is not contained in allowed types
return count(array_diff($types, $this->typesManager->getTypes())) === 0;
});
$resolver
->setDefault('class', ThirdParty::class)
->setDefault('choice_label', function (ThirdParty $tp) {
return $tp->getName();
})
->setDefault('choice_loader', function (Options $options) {
return new ThirdPartyChoiceLoader(
$options['center'],
$this->em->getRepository(ThirdParty::class)
);
});
}
public function getParent(): string
{
return EntityType::class;
}
}

View File

@@ -1,27 +1,38 @@
<?php
/**
* 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\ThirdPartyBundle\Form\Type;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use Chill\ThirdPartyBundle\Repository\ThirdPartyCategoryRepository;
use Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeManager;
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;
use function array_merge;
use function implode;
use function uasort;
class PickThirdPartyTypeCategoryType extends \Symfony\Component\Form\AbstractType
{
private ThirdPartyCategoryRepository $thirdPartyCategoryRepository;
private ThirdPartyTypeManager $thirdPartyTypeManager;
private TranslatableStringHelper $translatableStringHelper;
private TranslatorInterface $translator;
private const PREFIX_TYPE = 'chill_3party.key_label.';
private ThirdPartyCategoryRepository $thirdPartyCategoryRepository;
private ThirdPartyTypeManager $thirdPartyTypeManager;
private TranslatableStringHelper $translatableStringHelper;
private TranslatorInterface $translator;
public function __construct(
ThirdPartyCategoryRepository $thirdPartyCategoryRepository,
ThirdPartyTypeManager $thirdPartyTypeManager,
@@ -34,67 +45,68 @@ class PickThirdPartyTypeCategoryType extends \Symfony\Component\Form\AbstractTyp
$this->translator = $translator;
}
public function configureOptions(OptionsResolver $resolver)
{
$choices = array_merge(
$this->thirdPartyCategoryRepository->findBy(['active' => true]),
$this->thirdPartyTypeManager->getTypes()
);
uasort($choices, function ($itemA, $itemB) {
$strA = $itemA instanceof ThirdPartyCategory ? $this->translatableStringHelper
->localize($itemA->getName()) : $this->translator->trans(self::PREFIX_TYPE . $itemA);
$strB = $itemB instanceof ThirdPartyCategory ? $this->translatableStringHelper
->localize($itemB->getName()) : $this->translator->trans(self::PREFIX_TYPE . $itemB);
return $strA <=> $strB;
});
$resolver->setDefaults([
'choices' => $choices,
'attr' => ['class' => 'select2'],
'multiple' => true,
'choice_label' => function ($item) {
if ($item instanceof ThirdPartyCategory) {
return $this->translatableStringHelper->localize($item->getName());
}
return self::PREFIX_TYPE . $item;
},
'choice_value' => function ($item) {
return $this->reverseTransform($item);
},
]);
}
public function getParent()
{
return ChoiceType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$choices = \array_merge(
$this->thirdPartyCategoryRepository->findBy(['active' => true]),
$this->thirdPartyTypeManager->getTypes()
);
\uasort($choices, function ($itemA, $itemB) {
$strA = $itemA instanceof ThirdPartyCategory ? $this->translatableStringHelper
->localize($itemA->getName()) : $this->translator->trans(self::PREFIX_TYPE.$itemA);
$strB = $itemB instanceof ThirdPartyCategory ? $this->translatableStringHelper
->localize($itemB->getName()) : $this->translator->trans(self::PREFIX_TYPE.$itemB);
return $strA <=> $strB;
});
$resolver->setDefaults([
'choices' => $choices,
'attr' => [ 'class' => 'select2' ],
'multiple' => true,
'choice_label' => function($item) {
if ($item instanceof ThirdPartyCategory) {
return $this->translatableStringHelper->localize($item->getName());
}
return self::PREFIX_TYPE.$item;
},
'choice_value' => function($item) {
return $this->reverseTransform($item);
}
]);
}
public function reverseTransform($value)
{
if ($value === null) {
if (null === $value) {
return null;
}
if (is_array($value)){
if (is_array($value)) {
$r = [];
foreach ($value as $v) {
$r[] = $this->transform($v);
$r[] = $this->transform($v);
}
return $r;
}
if ($value instanceof ThirdPartyCategory) {
return 'category:'.$value->getId();
return 'category:' . $value->getId();
}
if (is_string($value)) {
return 'type:'.$value;
return 'type:' . $value;
}
throw new UnexpectedTypeException($value, \implode(' or ', ['array', 'string', ThirdPartyCategory::class]));
throw new UnexpectedTypeException($value, implode(' or ', ['array', 'string', ThirdPartyCategory::class]));
}
}

View File

@@ -1,45 +1,31 @@
<?php
/*
* Chill is a software for social workers
*
* Copyright (C) 2014-2019, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
*/
namespace Chill\ThirdPartyBundle\Menu;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Knp\Menu\MenuItem;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
/**
* Add an entry in section to go to third party index page
* 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\ThirdPartyBundle\Menu;
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Knp\Menu\MenuItem;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Translation\TranslatorInterface;
/**
* Add an entry in section to go to third party index page.
*/
class MenuBuilder implements LocalMenuBuilderInterface
{
/**
*
* @var AuthorizationCheckerInterface
*/
protected $authorizationChecker;
/**
*
* @var TranslatorInterface
*/
protected $translator;
@@ -52,7 +38,6 @@ class MenuBuilder implements LocalMenuBuilderInterface
$this->translator = $translator;
}
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
if ($this->authorizationChecker->isGranted(ThirdPartyVoter::SHOW)) {
@@ -61,11 +46,11 @@ class MenuBuilder implements LocalMenuBuilderInterface
$this->translator->trans('Third parties'),
[
'route' => 'chill_crud_3party_3party_index',
])
]
)
->setExtras([
'order' => 112
])
;
'order' => 112,
]);
}
}

View File

@@ -1,16 +1,24 @@
<?php
/**
* 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\ThirdPartyBundle\Repository;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\QueryBuilder;
use Symfony\Component\Security\Core\Security;
final class ThirdPartyACLAwareRepository implements ThirdPartyACLAwareRepositoryInterface
{
private Security $security;
private AuthorizationHelper $authorizationHelper;
private Security $security;
private ThirdPartyRepository $thirdPartyRepository;
public function __construct(Security $security, AuthorizationHelper $authorizationHelper, ThirdPartyRepository $thirdPartyRepository)
@@ -20,23 +28,16 @@ final class ThirdPartyACLAwareRepository implements ThirdPartyACLAwareRepository
$this->thirdPartyRepository = $thirdPartyRepository;
}
public function listThirdParties(
string $role,
?string $filterString,
?array $orderBy = [],
?int $limit = null,
?int $offset = null
): array {
$qb = $this->buildQuery($filterString);
public function buildQuery(?string $filterString = null): QueryBuilder
{
$qb = $this->thirdPartyRepository->createQueryBuilder('tp');
foreach ($orderBy as $sort => $direction) {
$qb->addOrderBy('tp.'.$sort, $direction);
if (null !== $filterString) {
$qb->andWhere($qb->expr()->like('tp.canonicalized', 'LOWER(UNACCENT(:filterString))'))
->setParameter('filterString', '%' . $filterString . '%');
}
$qb->setFirstResult($offset)
->setMaxResults($limit);
return $qb->getQuery()->getResult();
return $qb;
}
public function countThirdParties(
@@ -49,15 +50,22 @@ final class ThirdPartyACLAwareRepository implements ThirdPartyACLAwareRepository
return $qb->getQuery()->getSingleScalarResult();
}
public function buildQuery(?string $filterString = null): QueryBuilder
{
$qb = $this->thirdPartyRepository->createQueryBuilder('tp');
public function listThirdParties(
string $role,
?string $filterString,
?array $orderBy = [],
?int $limit = null,
?int $offset = null
): array {
$qb = $this->buildQuery($filterString);
if (NULL !== $filterString) {
$qb->andWhere($qb->expr()->like('tp.canonicalized', 'LOWER(UNACCENT(:filterString))'))
->setParameter('filterString', '%'.$filterString.'%');
foreach ($orderBy as $sort => $direction) {
$qb->addOrderBy('tp.' . $sort, $direction);
}
return $qb;
$qb->setFirstResult($offset)
->setMaxResults($limit);
return $qb->getQuery()->getResult();
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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\ThirdPartyBundle\Repository;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
@@ -9,10 +16,6 @@ interface ThirdPartyACLAwareRepositoryInterface
public function countThirdParties(string $role, ?string $filterString): int;
/**
* @param string $role
* @param array|null $orderBy
* @param int|null $limit
* @param int|null $offset
* @return array|ThirdParty[]
*/
public function listThirdParties(

View File

@@ -1,23 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ThirdPartyBundle\Repository;
@@ -38,5 +25,4 @@ class ThirdPartyCategoryRepository extends ServiceEntityRepository
{
parent::__construct($registry, ThirdPartyCategory::class);
}
}

View File

@@ -1,23 +1,10 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2021, Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>, <info@champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ThirdPartyBundle\Repository;
@@ -38,5 +25,4 @@ class ThirdPartyProfessionRepository extends ServiceEntityRepository
{
parent::__construct($registry, ThirdPartyProfession::class);
}
}

View File

@@ -1,14 +1,22 @@
<?php
/**
* 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\ThirdPartyBundle\Repository;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\Query;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ObjectRepository;
use DomainException;
use function array_key_exists;
final class ThirdPartyRepository implements ObjectRepository
{
@@ -20,11 +28,9 @@ final class ThirdPartyRepository implements ObjectRepository
}
/**
* count amongst parties associated to $centers, with $terms parameters
* count amongst parties associated to $centers, with $terms parameters.
*
* @param array $centers
* @param type $terms
* @return int
*/
public function countByMemberOfCenters(array $centers, $terms = []): int
{
@@ -34,121 +40,9 @@ final class ThirdPartyRepository implements ObjectRepository
return $qb->getQuery()->getSingleScalarResult();
}
/**
* Search amongst parties associated to $centers, with $terms parameters
*
* Different format for return:
* - ['entity']: return the entity hydrated as objects
* - ['array', [ DQL ]: return objects hydrated as entity, with
* an array describing the fields as DQL.
*
* supported terms:
*
* - name or _default: containing the name (name LIKE %string%)
* - is_active: is active = true / false
* - types: an array of types
*
* @param array $centers
* @param int $firstResult
* @param int $maxResults
* @param array $terms
* @param string[] $returnFormat a format for returning
* @return array
*/
public function findByMemberOfCenters(array $centers, $firstResult = 0, $maxResults = 20, $terms = [], $returnFormat = ['entity']): array
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
{
$qb = $this->buildQuery($centers, $terms);
switch($returnFormat[0]) {
case 'entity':
$qb->select('tp');
$hydrate = Query::HYDRATE_OBJECT;
break;
case 'array':
$hydrate = Query::HYDRATE_ARRAY;
$first = true;
foreach ($returnFormat[1] as $dql) {
if ($first) {
$qb->select($dql);
$first = false;
} else {
$qb->addSelect($dql);
}
}
break;
default:
throw new \DomainException("This return format is invalid");
}
$qb->setFirstResult($firstResult)
->setMaxResults($maxResults);
return $qb->getQuery()->getResult();
}
protected function createMemberOfCentersQuery($centers): QueryBuilder
{
$qb = $this->createQueryBuilder('tp');
$or = $qb->expr()->orX();
foreach ($centers as $center) {
$or->add($qb->expr()->isMemberOf(':center_'.$center->getId(), 'tp.centers'));
$qb->setParameter('center_'.$center->getId(), $center);
}
$qb->where($or);
return $qb;
}
protected function buildQuery($centers, $terms): QueryBuilder
{
$qb = $this->createMemberOfCentersQuery($centers);
$this->setNameCondition($qb, $terms);
$this->setTypesCondition($qb, $terms);
$this->setIsActiveCondition($qb, $terms);
return $qb;
}
/**
* Add parameters to filter by containing $terms["name"] or
* $terms["_default"]
*
* @param QueryBuilder $qb
* @param array $terms
*/
protected function setNameCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('name', $terms) || \array_key_exists('_default', $terms)) {
$term = $terms['name'] ?? $terms['_default'];
if (empty($term)) {
return;
}
$qb->andWhere($qb->expr()->like('UNACCENT(LOWER(tp.name))', 'UNACCENT(LOWER(:name))'));
$qb->setParameter('name', '%'.$term.'%');
}
}
protected function setTypesCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('types', $terms)) {
$orx = $qb->expr()->orX();
foreach ($terms['types'] as $type) {
$orx->add('JSONB_EXISTS_IN_ARRAY(tp.type, :type_'.$type.') = \'TRUE\'');
$qb->setParameter('type_'.$type, $type);
}
$qb->andWhere($orx);
}
}
protected function setIsActiveCondition(QueryBuilder $qb, array $terms)
{
if (\array_key_exists('is_active', $terms)) {
$qb->andWhere(
$terms['is_active'] ? $qb->expr()->eq('tp.active', "'TRUE'") :
$qb->expr()->eq('tp.active', "'FALSE'")
);
}
return $this->repository->createQueryBuilder($alias, $indexBy);
}
public function find($id): ?ThirdParty
@@ -165,10 +59,9 @@ final class ThirdPartyRepository implements ObjectRepository
}
/**
* @param array $criteria
* @param array|null $orderBy
* @param null $limit
* @param null $offset
*
* @return array|ThirdParty[]
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null): array
@@ -176,6 +69,60 @@ final class ThirdPartyRepository implements ObjectRepository
return $this->repository->findBy($criteria, $orderBy, $limit, $offset);
}
/**
* Search amongst parties associated to $centers, with $terms parameters.
*
* Different format for return:
* - ['entity']: return the entity hydrated as objects
* - ['array', [ DQL ]: return objects hydrated as entity, with
* an array describing the fields as DQL.
*
* supported terms:
*
* - name or _default: containing the name (name LIKE %string%)
* - is_active: is active = true / false
* - types: an array of types
*
* @param int $firstResult
* @param int $maxResults
* @param array $terms
* @param string[] $returnFormat a format for returning
*/
public function findByMemberOfCenters(array $centers, $firstResult = 0, $maxResults = 20, $terms = [], $returnFormat = ['entity']): array
{
$qb = $this->buildQuery($centers, $terms);
switch ($returnFormat[0]) {
case 'entity':
$qb->select('tp');
$hydrate = Query::HYDRATE_OBJECT;
break;
case 'array':
$hydrate = Query::HYDRATE_ARRAY;
$first = true;
foreach ($returnFormat[1] as $dql) {
if ($first) {
$qb->select($dql);
$first = false;
} else {
$qb->addSelect($dql);
}
}
break;
default:
throw new DomainException('This return format is invalid');
}
$qb->setFirstResult($firstResult)
->setMaxResults($maxResults);
return $qb->getQuery()->getResult();
}
public function findOneBy(array $criteria): ?ThirdParty
{
return $this->repository->findOneBy($criteria);
@@ -186,9 +133,69 @@ final class ThirdPartyRepository implements ObjectRepository
return ThirdParty::class;
}
public function createQueryBuilder(string $alias, ?string $indexBy = null): QueryBuilder
private function buildQuery($centers, $terms): QueryBuilder
{
return $this->repository->createQueryBuilder($alias, $indexBy);
$qb = $this->createMemberOfCentersQuery($centers);
$this->setNameCondition($qb, $terms);
$this->setTypesCondition($qb, $terms);
$this->setIsActiveCondition($qb, $terms);
return $qb;
}
private function createMemberOfCentersQuery($centers): QueryBuilder
{
$qb = $this->createQueryBuilder('tp');
$or = $qb->expr()->orX();
foreach ($centers as $center) {
$or->add($qb->expr()->isMemberOf(':center_' . $center->getId(), 'tp.centers'));
$qb->setParameter('center_' . $center->getId(), $center);
}
$qb->where($or);
return $qb;
}
private function setIsActiveCondition(QueryBuilder $qb, array $terms)
{
if (array_key_exists('is_active', $terms)) {
$qb->andWhere(
$terms['is_active'] ? $qb->expr()->eq('tp.active', "'TRUE'") :
$qb->expr()->eq('tp.active', "'FALSE'")
);
}
}
/**
* Add parameters to filter by containing $terms["name"] or
* $terms["_default"].
*/
private function setNameCondition(QueryBuilder $qb, array $terms)
{
if (array_key_exists('name', $terms) || array_key_exists('_default', $terms)) {
$term = $terms['name'] ?? $terms['_default'];
if (empty($term)) {
return;
}
$qb->andWhere($qb->expr()->like('UNACCENT(LOWER(tp.name))', 'UNACCENT(LOWER(:name))'));
$qb->setParameter('name', '%' . $term . '%');
}
}
private function setTypesCondition(QueryBuilder $qb, array $terms)
{
if (array_key_exists('types', $terms)) {
$orx = $qb->expr()->orX();
foreach ($terms['types'] as $type) {
$orx->add('JSONB_EXISTS_IN_ARRAY(tp.type, :type_' . $type . ') = \'TRUE\'');
$qb->setParameter('type_' . $type, $type);
}
$qb->andWhere($orx);
}
}
}

View File

@@ -1,12 +1,21 @@
<?php
/**
* 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\ThirdPartyBundle\Search;
use Chill\MainBundle\Search\SearchApiInterface;
use Chill\MainBundle\Search\SearchApiQuery;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use function array_merge;
use function explode;
use function implode;
use function in_array;
/*
* Internal note: test query for parametrizing / testing:
@@ -33,7 +42,7 @@ FROM rows, searches
*/
/**
* Generate query for searching amongst third parties
* Generate query for searching amongst third parties.
*/
class ThirdPartyApiSearch implements SearchApiInterface
{
@@ -44,9 +53,18 @@ class ThirdPartyApiSearch implements SearchApiInterface
$this->thirdPartyRepository = $thirdPartyRepository;
}
public function getResult(string $key, array $metadata, float $pertinence)
{
return $this->thirdPartyRepository->find($metadata['id']);
}
public function prepare(array $metadatas): void
{
}
public function provideQuery(string $pattern, array $parameters): SearchApiQuery
{
$query = (new SearchApiQuery)
$query = (new SearchApiQuery())
->setSelectKey('tparty')
->setSelectJsonbMetadata("jsonb_build_object('id', tparty.id)")
->setFromClause('chill_3party.third_party AS tparty
@@ -55,8 +73,7 @@ class ThirdPartyApiSearch implements SearchApiInterface
LEFT JOIN chill_3party.third_party AS parent ON tparty.parent_id = parent.id
LEFT JOIN chill_main_address cma_p ON parent.address_id = cma_p.id
LEFT JOIN chill_main_postal_code cmpc_p ON cma_p.postcode_id = cmpc.id')
->andWhereClause("tparty.active IS TRUE")
;
->andWhereClause('tparty.active IS TRUE');
$strs = explode(' ', $pattern);
$wheres = [];
@@ -65,45 +82,39 @@ class ThirdPartyApiSearch implements SearchApiInterface
$pertinenceArgs = [];
foreach ($strs as $str) {
if (!empty($str)) {
$wheres[] = "(LOWER(UNACCENT(?)) <<% tparty.canonicalized OR
if (!empty($str)) {
$wheres[] = "(LOWER(UNACCENT(?)) <<% tparty.canonicalized OR
tparty.canonicalized LIKE '%' || LOWER(UNACCENT(?)) || '%')";
$whereArgs[] = [$str, $str];
$pertinence[] = "STRICT_WORD_SIMILARITY(LOWER(UNACCENT(?)), tparty.canonicalized) + ".
"(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT(?)) || '%')::int + ".
$whereArgs[] = [$str, $str];
$pertinence[] = 'STRICT_WORD_SIMILARITY(LOWER(UNACCENT(?)), tparty.canonicalized) + ' .
"(tparty.canonicalized LIKE '%s' || LOWER(UNACCENT(?)) || '%')::int + " .
// take postcode label into account, but lower than the canonicalized field
"COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0) + ".
"COALESCE((LOWER(UNACCENT(cmpc.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0) + " .
"COALESCE((LOWER(UNACCENT(cmpc_p.label)) LIKE '%' || LOWER(UNACCENT(?)) || '%')::int * 0.3, 0)";
$pertinenceArgs[] = [$str, $str, $str, $str];
}
$pertinenceArgs[] = [$str, $str, $str, $str];
}
}
$query
->setSelectPertinence(\implode(' + ', $pertinence), \array_merge([],
...$pertinenceArgs))
->andWhereClause(\implode(' OR ', $wheres), \array_merge([],
...$whereArgs));
->setSelectPertinence(implode(' + ', $pertinence), array_merge(
[],
...$pertinenceArgs
))
->andWhereClause(implode(' OR ', $wheres), array_merge(
[],
...$whereArgs
));
return $query;
}
public function supportsTypes(string $pattern, array $types, array $parameters): bool
{
return \in_array('thirdparty', $types);
}
public function prepare(array $metadatas): void
{
}
public function supportsResult(string $key, array $metadatas): bool
{
return $key === 'tparty';
return 'tparty' === $key;
}
public function getResult(string $key, array $metadata, float $pertinence)
public function supportsTypes(string $pattern, array $types, array $parameters): bool
{
return $this->thirdPartyRepository->find($metadata['id']);
return in_array('thirdparty', $types);
}
}

View File

@@ -1,53 +1,54 @@
<?php
/*
*/
namespace Chill\ThirdPartyBundle\Search;
use Chill\MainBundle\Search\SearchInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Symfony\Component\Security\Core\Role\Role;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\MainBundle\Pagination\PaginatorFactory;
/**
* Allow to search amongst parties
* 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\ThirdPartyBundle\Search;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Search\SearchInterface;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Security\Voter\ThirdPartyVoter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Role\Role;
/**
* Allow to search amongst parties.
*/
class ThirdPartySearch implements SearchInterface
{
public const NAME = '3party';
/**
*
* @var EntityManagerInterface
*/
protected $em;
/**
*
* @var TokenStorageInterface
*/
protected $tokenStorage;
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
*
* @var PaginatorFactory
* @var EntityManagerInterface
*/
protected $em;
/**
* @var PaginatorFactory
*/
protected $paginatorFactory;
const NAME = '3party';
/**
* @var TokenStorageInterface
*/
protected $tokenStorage;
public function __construct(
EntityManagerInterface $em,
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper,
EntityManagerInterface $em,
TokenStorageInterface $tokenStorage,
AuthorizationHelper $authorizationHelper,
PaginatorFactory $paginatorFactory
) {
$this->em = $em;
@@ -56,7 +57,6 @@ class ThirdPartySearch implements SearchInterface
$this->paginatorFactory = $paginatorFactory;
}
public function getOrder(): int
{
return 59866;
@@ -67,34 +67,39 @@ class ThirdPartySearch implements SearchInterface
return false;
}
public function renderResult(array $terms, $start = 0, $limit = 50, $options = array(), $format = 'html')
public function renderResult(array $terms, $start = 0, $limit = 50, $options = [], $format = 'html')
{
$centers = $this->authorizationHelper
->getReachableCenters(
$this->tokenStorage->getToken()->getUser(),
$this->tokenStorage->getToken()->getUser(),
new Role(ThirdPartyVoter::SHOW)
);
);
$total = $this->count($centers, $terms);
$paginator = $this->paginatorFactory->create($total);
// replace types in terms by types in query
$terms['types'] = $options[SearchInterface::REQUEST_QUERY_PARAMETERS]['t'];
$terms['is_active'] = true;
if ($format === 'json') {
if ('json' === $format) {
return [
'results' => $this->em->getRepository(ThirdParty::class)
->findByMemberOfCenters($centers, $start, $limit, $terms,
['array', ['tp.id', 'tp.name AS text']]),
'more' => $paginator->hasNextPage()
->findByMemberOfCenters(
$centers,
$start,
$limit,
$terms,
['array', ['tp.id', 'tp.name AS text']]
),
'more' => $paginator->hasNextPage(),
];
}
}
public function supports($domain, $format): bool
{
return self::NAME === $domain and $format === 'json';
return self::NAME === $domain and 'json' === $format;
}
protected function count($centers, $terms): int
{
return $this->em->getRepository(ThirdParty::class)

View File

@@ -1,93 +1,56 @@
<?php
/*
*/
namespace Chill\ThirdPartyBundle\Security\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Security\Core\Role\Role;
/**
* Voter for Third Party
*
*
* 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\ThirdPartyBundle\Security\Voter;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\Role;
use function array_intersect;
use function in_array;
/**
* Voter for Third Party.
*/
class ThirdPartyVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
public const CREATE = 'CHILL_3PARTY_3PARTY_CREATE';
public const SHOW = 'CHILL_3PARTY_3PARTY_SHOW';
public const UPDATE = 'CHILL_3PARTY_3PARTY_UPDATE';
/**
*
* @var AuthorizationHelper
*/
protected $authorizationHelper;
public const CREATE = 'CHILL_3PARTY_3PARTY_CREATE';
public const UPDATE = 'CHILL_3PARTY_3PARTY_UPDATE';
public const SHOW = 'CHILL_3PARTY_3PARTY_SHOW';
public function __construct(AuthorizationHelper $authorizationHelper)
{
$this->authorizationHelper = $authorizationHelper;
}
protected function supports($attribute, $subject)
{
if ($subject instanceof ThirdParty) {
return \in_array($attribute, $this->getRoles());
} elseif ($subject === NULL) {
return $attribute === self::CREATE || $attribute === self::SHOW ;
}
return false;
}
/**
*
* @param string $attribute
* @param ThirdParty|null $subject
* @param TokenInterface $token
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
return true;
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
return true;
$centers = $this->authorizationHelper
->getReachableCenters($user, new Role($attribute));
if ($subject === NULL) {
return count($centers) > 0;
} elseif ($subject instanceof ThirdParty) {
return count(\array_intersect($centers, $subject->getCenters()->toArray())) > 0;
}
return false;
}
public function getRoles(): array
{
return [
self::CREATE, self::UPDATE, self::SHOW
self::CREATE, self::UPDATE, self::SHOW,
];
}
public function getRolesWithHierarchy(): array
{
return [
'Third Party' => $this->getRoles()
'Third Party' => $this->getRoles(),
];
}
@@ -95,4 +58,45 @@ class ThirdPartyVoter extends AbstractChillVoter implements ProvideRoleHierarchy
{
return $this->getRoles();
}
protected function supports($attribute, $subject)
{
if ($subject instanceof ThirdParty) {
return in_array($attribute, $this->getRoles());
}
if (null === $subject) {
return self::CREATE === $attribute || self::SHOW === $attribute;
}
return false;
}
/**
* @param string $attribute
* @param ThirdParty|null $subject
*/
protected function voteOnAttribute($attribute, $subject, TokenInterface $token): bool
{
return true;
$user = $token->getUser();
if (!$user instanceof User) {
return false;
}
return true;
$centers = $this->authorizationHelper
->getReachableCenters($user, new Role($attribute));
if (null === $subject) {
return count($centers) > 0;
}
if ($subject instanceof ThirdParty) {
return count(array_intersect($centers, $subject->getCenters()->toArray())) > 0;
}
return false;
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\ThirdPartyBundle\Serializer\Normalizer;
@@ -10,7 +17,6 @@ use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
class ThirdPartyNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
@@ -25,14 +31,14 @@ class ThirdPartyNormalizer implements NormalizerInterface, NormalizerAwareInterf
/**
* @param ThirdParty $thirdParty
*/
public function normalize($thirdParty, string $format = null, array $context = [])
public function normalize($thirdParty, ?string $format = null, array $context = [])
{
return [
'type' => 'thirdparty',
'text' => $this->thirdPartyRender->renderString($thirdParty, []),
'id' => $thirdParty->getId(),
'kind' => $thirdParty->getKind(),
'address' => $this->normalizer->normalize($thirdParty->getAddress(), $format, [ 'address_rendering' => 'short' ]),
'address' => $this->normalizer->normalize($thirdParty->getAddress(), $format, ['address_rendering' => 'short']),
'phonenumber' => $thirdParty->getTelephone(),
'email' => $thirdParty->getEmail(),
'isChild' => $thirdParty->isChild(),
@@ -42,9 +48,8 @@ class ThirdPartyNormalizer implements NormalizerInterface, NormalizerAwareInterf
];
}
public function supportsNormalization($data, string $format = null)
public function supportsNormalization($data, ?string $format = null)
{
return $data instanceof ThirdParty;
}
}

View File

@@ -1,23 +1,12 @@
<?php
/*
/**
* Chill is a software for social workers
*
* Copyright (C) 2014-2020 , Champs Libres Cooperative SCRLFS,
* <http://www.champs-libres.coop>
*
* 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 <http://www.gnu.org/licenses/>.
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\ThirdPartyBundle\Templating\Entity;
use Chill\MainBundle\Templating\Entity\AbstractChillEntityRender;
@@ -25,30 +14,22 @@ use Chill\MainBundle\Templating\TranslatableStringHelper;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Component\Templating\EngineInterface;
/**
*
*
*/
class ThirdPartyRender extends AbstractChillEntityRender
{
protected EngineInterface $engine;
protected TranslatableStringHelper $translatableStringHelper;
public function __construct(
EngineInterface $engine,
TranslatableStringHelper $translatableStringHelper
)
{
) {
$this->engine = $engine;
$this->translatableStringHelper = $translatableStringHelper;
}
/**
*
* @param ThirdParty $entity
* @param array $options
* @return string
*/
public function renderBox($entity, array $options): string
{
@@ -63,7 +44,7 @@ class ThirdPartyRender extends AbstractChillEntityRender
'customArea' => $options['customArea'] ?? [],
'showContacts' => $options['showContacts'] ?? false,
'showParent' => $options['showParent'] ?? true,
'isConfidential' => $options['isConfidential'] ?? false
'isConfidential' => $options['isConfidential'] ?? false,
];
return
@@ -71,31 +52,30 @@ class ThirdPartyRender extends AbstractChillEntityRender
$this->engine->render('@ChillThirdParty/Entity/thirdparty.html.twig', [
'thirdparty' => $entity,
'render' => $options['render'] ?? 'raw',
'options' => $params
'options' => $params,
]) .
$this->getDefaultClosingBox();
}
/**
*
* @param ThirdParty $entity
* @param array $options
* @return string
*/
public function renderString($entity, array $options): string
{
if ($entity->getCivility() !== NULL) {
if ($entity->getCivility() !== null) {
$civility = $this->translatableStringHelper
->localize($entity->getCivility()->getAbbreviation()).' ';
->localize($entity->getCivility()->getAbbreviation()) . ' ';
} else {
$civility = '';
}
if (!empty($entity->getAcronym())) {
$acronym = ' ('.$entity->getAcronym().')';
$acronym = ' (' . $entity->getAcronym() . ')';
} else {
$acronym = '';
}
return $civility.$entity->getName().$acronym;
return $civility . $entity->getName() . $acronym;
}
public function supports($entity, array $options): bool

View File

@@ -1,9 +1,20 @@
<?php
/**
* 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\ThirdPartyBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
/**
* @internal
* @coversNothing
*/
class ThirdPartyControllerTest extends WebTestCase
{
public function testIndex()
@@ -26,5 +37,4 @@ class ThirdPartyControllerTest extends WebTestCase
$crawler = $client->request('GET', '/update');
}
}

View File

@@ -1,11 +1,22 @@
<?php
/**
* 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\ThirdParty\Tests\Entity;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class ThirdPartyTest extends TestCase
{
public function testAddingRemovingActivityTypes()
@@ -34,8 +45,10 @@ class ThirdPartyTest extends TestCase
$tp->removeTypesAndCategories('type');
$tp->removeTypesAndCategories($cat2);
$this->assertTrue($tp->getCategories()->contains($cat1),
"test that cat1 is still present");
$this->assertTrue(
$tp->getCategories()->contains($cat1),
'test that cat1 is still present'
);
$this->assertFalse($tp->getCategories()->contains($cat2));
$this->assertCount(1, $tp->getCategories());
@@ -55,7 +68,7 @@ class ThirdPartyTest extends TestCase
'type1',
'type2',
$cat1 = new ThirdPartyCategory(),
$cat2 = new ThirdPartyCategory()
$cat2 = new ThirdPartyCategory(),
]);
$this->assertTrue($tp->getCategories()->contains($cat1));
@@ -88,5 +101,4 @@ class ThirdPartyTest extends TestCase
$this->assertContains('type1', $tp->getTypesAndCategories());
$this->assertNotContains('type2', $tp->getTypesAndCategories());
}
}

View File

@@ -1,56 +1,63 @@
<?php
/**
* 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\ThirdPartyBundle\ThirdPartyType;
use self;
use function array_keys;
/**
* Manages types of third parties
*
* Manages types of third parties.
*/
class ThirdPartyTypeManager
{
/**
*
* The prefix used to translate the key of provider.
*/
public const THIRD_PARTY_TRANSLATOR_KEY = 'chill_3party.key_label.';
/**
* @var ThirdPartyTypeProviderInterface[]
*/
protected $providers = [];
/**
* The prefix used to translate the key of provider
*/
const THIRD_PARTY_TRANSLATOR_KEY = 'chill_3party.key_label.';
/**
* Add a provider to the manager
*
* Add a provider to the manager.
*
* Method used during the load of the manager by Dependency Injection
*
*
* @param \Chill\ThirdPartyBundle\ThirdPartyType\ThirdPartyTypeProviderInterface $provider
* @return \self
*
* @return self
*/
public function addProvider(ThirdPartyTypeProviderInterface $provider): self
{
$this->providers[$provider->getKey()] = $provider;
return $this;
}
/**
* Get all providers
*
* @return array
* Get all providers.
*/
public function getProviders(): array
{
return $this->providers;
}
/**
* Get a list of types
*
* Get a list of types.
*
* @return string[]
*/
public function getTypes(): array
{
return \array_keys($this->providers);
return array_keys($this->providers);
}
}

View File

@@ -1,17 +1,21 @@
<?php
/**
* 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\ThirdPartyBundle\ThirdPartyType;
/**
* Provide third party type
* Provide third party type.
*/
interface ThirdPartyTypeProviderInterface
{
/**
* Return an unique key for this type.
*
* @return string
*/
public static function getKey(): string;
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -6,22 +15,12 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* add ThirdParty Entity
* add ThirdParty Entity.
*
* @Author Mathieu Jaumotte jaum_mathieu@collectifs.net
*/
final class Version20190307111314 extends AbstractMigration
{
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SEQUENCE chill_third_party_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_third_party (id INT NOT NULL, name VARCHAR(255) NOT NULL, telephone VARCHAR(64) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, comment TEXT DEFAULT NULL, type JSON DEFAULT NULL, PRIMARY KEY(id))');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
@@ -29,6 +28,14 @@ final class Version20190307111314 extends AbstractMigration
$this->addSql('DROP SEQUENCE chill_third_party_id_seq CASCADE');
$this->addSql('DROP TABLE chill_third_party');
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('CREATE SEQUENCE chill_third_party_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_third_party (id INT NOT NULL, name VARCHAR(255) NOT NULL, telephone VARCHAR(64) DEFAULT NULL, email VARCHAR(255) DEFAULT NULL, comment TEXT DEFAULT NULL, type JSON DEFAULT NULL, PRIMARY KEY(id))');
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -6,24 +15,24 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Move table third-party to another schema
* Move table third-party to another schema.
*/
final class Version20190307131650 extends AbstractMigration
{
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql("CREATE SCHEMA chill_3party");
$this->addSql("ALTER TABLE chill_third_party SET SCHEMA chill_3party");
$this->addSql("ALTER TABLE chill_3party.chill_third_party RENAME TO third_party");
$this->addSql("ALTER SEQUENCE chill_third_party_id_seq SET SCHEMA chill_3party");
$this->addSql("ALTER SEQUENCE chill_3party.chill_third_party_id_seq RENAME TO third_party_id_seq");
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->throwIrreversibleMigrationException("The down version of this migration is "
. "not written");
$this->throwIrreversibleMigrationException('The down version of this migration is '
. 'not written');
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA chill_3party');
$this->addSql('ALTER TABLE chill_third_party SET SCHEMA chill_3party');
$this->addSql('ALTER TABLE chill_3party.chill_third_party RENAME TO third_party');
$this->addSql('ALTER SEQUENCE chill_third_party_id_seq SET SCHEMA chill_3party');
$this->addSql('ALTER SEQUENCE chill_3party.chill_third_party_id_seq RENAME TO third_party_id_seq');
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -6,10 +15,18 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add "centers" and "active" to 3rd party
* Add "centers" and "active" to 3rd party.
*/
final class Version20190418090842 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('DROP TABLE chill_3party.party_center');
$this->addSql('ALTER TABLE chill_3party.third_party DROP active');
}
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
@@ -21,12 +38,4 @@ final class Version20190418090842 extends AbstractMigration
$this->addSql('ALTER TABLE chill_3party.party_center ADD CONSTRAINT FK_C65D43975932F377 FOREIGN KEY (center_id) REFERENCES centers (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_3party.third_party ADD active BOOLEAN NOT NULL');
}
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('DROP TABLE chill_3party.party_center');
$this->addSql('ALTER TABLE chill_3party.third_party DROP active');
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -6,21 +15,20 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Alter third_party.type to jsonb and rename to types
* Alter third_party.type to jsonb and rename to types.
*/
final class Version20190429171109 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql("ALTER TABLE chill_3party.third_party RENAME COLUMN type "
. "TO types");
$this->addSql("ALTER TABLE chill_3party.third_party ALTER COLUMN types "
. "SET DATA TYPE jsonb");
}
public function down(Schema $schema): void
{
$this->throwIrreversibleMigrationException("not implemented");
$this->throwIrreversibleMigrationException('not implemented');
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party RENAME COLUMN type '
. 'TO types');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER COLUMN types '
. 'SET DATA TYPE jsonb');
}
}

View File

@@ -1,4 +1,13 @@
<?php declare(strict_types=1);
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -6,10 +15,18 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add an address to parties
* Add an address to parties.
*/
final class Version20190502144206 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BF5B7AF75');
$this->addSql('ALTER TABLE chill_3party.third_party DROP address_id');
}
public function up(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
@@ -18,14 +35,5 @@ final class Version20190502144206 extends AbstractMigration
$this->addSql('COMMENT ON COLUMN chill_3party.third_party.types IS NULL');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT FK_D952467BF5B7AF75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_D952467BF5B7AF75 ON chill_3party.third_party (address_id)');
}
public function down(Schema $schema): void
{
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BF5B7AF75');
$this->addSql('ALTER TABLE chill_3party.third_party DROP address_id');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,10 +15,16 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Specify ON DELETE behaviour to handle deletion of parents in associated tables
* Specify ON DELETE behaviour to handle deletion of parents in associated tables.
*/
final class Version20210525211216 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT fk_d952467bf5b7af75');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467bf5b7af75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function getDescription(): string
{
return 'Specify ON DELETE behaviour to handle deletion of parents in associated tables';
@@ -22,10 +35,4 @@ final class Version20210525211216 extends AbstractMigration
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BF5B7AF75');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT FK_D952467BF5B7AF75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT fk_d952467bf5b7af75');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467bf5b7af75 FOREIGN KEY (address_id) REFERENCES chill_main_address (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,11 +15,36 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add new fields to ThirdParty Entity
* @author Mathieu Jaumotte mathieu.jaumotte@champs-libres.coop
* Add new fields to ThirdParty Entity.
*/
final class Version20210719105918 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.thirdparty_category DROP CONSTRAINT FK_7049563712469DE2');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B384D4799');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BBA930D69');
$this->addSql('DROP SEQUENCE chill_3party.party_category_id_seq CASCADE');
$this->addSql('DROP SEQUENCE chill_3party.party_civility_id_seq CASCADE');
$this->addSql('DROP SEQUENCE chill_3party.party_profession_id_seq CASCADE');
$this->addSql('DROP TABLE chill_3party.party_category');
$this->addSql('DROP TABLE chill_3party.party_civility');
$this->addSql('DROP TABLE chill_3party.party_profession');
$this->addSql('DROP TABLE chill_3party.thirdparty_category');
$this->addSql('ALTER INDEX chill_3party.idx_14dc44755932f377 RENAME TO idx_c65d43975932f377');
$this->addSql('ALTER INDEX chill_3party.idx_14dc4475c7d3a8e6 RENAME TO idx_c65d4397c7d3a8e6');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B727ACA70');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B16FE72E1');
$this->addSql('ALTER TABLE chill_3party.third_party DROP parent_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP civility');
$this->addSql('ALTER TABLE chill_3party.third_party DROP profession');
$this->addSql('ALTER TABLE chill_3party.third_party DROP updated_by');
$this->addSql('ALTER TABLE chill_3party.third_party DROP name_company');
$this->addSql('ALTER TABLE chill_3party.third_party DROP acronym');
$this->addSql('ALTER TABLE chill_3party.third_party DROP created_at');
$this->addSql('ALTER TABLE chill_3party.third_party DROP updated_at');
}
public function getDescription(): string
{
return 'Add new fields to ThirdParty Entity + new join tables';
@@ -50,30 +82,4 @@ final class Version20210719105918 extends AbstractMigration
$this->addSql('ALTER INDEX chill_3party.idx_c65d4397c7d3a8e6 RENAME TO IDX_14DC4475C7D3A8E6');
$this->addSql('ALTER INDEX chill_3party.idx_c65d43975932f377 RENAME TO IDX_14DC44755932F377');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.thirdparty_category DROP CONSTRAINT FK_7049563712469DE2');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B384D4799');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BBA930D69');
$this->addSql('DROP SEQUENCE chill_3party.party_category_id_seq CASCADE');
$this->addSql('DROP SEQUENCE chill_3party.party_civility_id_seq CASCADE');
$this->addSql('DROP SEQUENCE chill_3party.party_profession_id_seq CASCADE');
$this->addSql('DROP TABLE chill_3party.party_category');
$this->addSql('DROP TABLE chill_3party.party_civility');
$this->addSql('DROP TABLE chill_3party.party_profession');
$this->addSql('DROP TABLE chill_3party.thirdparty_category');
$this->addSql('ALTER INDEX chill_3party.idx_14dc44755932f377 RENAME TO idx_c65d43975932f377');
$this->addSql('ALTER INDEX chill_3party.idx_14dc4475c7d3a8e6 RENAME TO idx_c65d4397c7d3a8e6');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B727ACA70');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B16FE72E1');
$this->addSql('ALTER TABLE chill_3party.third_party DROP parent_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP civility');
$this->addSql('ALTER TABLE chill_3party.third_party DROP profession');
$this->addSql('ALTER TABLE chill_3party.third_party DROP updated_by');
$this->addSql('ALTER TABLE chill_3party.third_party DROP name_company');
$this->addSql('ALTER TABLE chill_3party.third_party DROP acronym');
$this->addSql('ALTER TABLE chill_3party.third_party DROP created_at');
$this->addSql('ALTER TABLE chill_3party.third_party DROP updated_at');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,10 +15,15 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add created_by to third party
* Add created_by to third party.
*/
final class Version20211006200924 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP created_by');
}
public function getDescription(): string
{
return 'Add link to creator (created_by) to thirdParty';
@@ -19,19 +31,14 @@ final class Version20211006200924 extends AbstractMigration
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party ADD created_by INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER created_at DROP DEFAULT');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER updated_at DROP DEFAULT');
$this->addSql('COMMENT ON COLUMN chill_3party.third_party.created_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN chill_3party.third_party.updated_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT FK_D952467BDE12AB56 FOREIGN KEY (created_by) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_D952467BDE12AB56 ON chill_3party.third_party (created_by)');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP created_by');
$this->addSql('ALTER TABLE chill_3party.third_party ADD created_by INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER created_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER created_at DROP DEFAULT');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER updated_at TYPE TIMESTAMP(0) WITHOUT TIME ZONE');
$this->addSql('ALTER TABLE chill_3party.third_party ALTER updated_at DROP DEFAULT');
$this->addSql('COMMENT ON COLUMN chill_3party.third_party.created_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('COMMENT ON COLUMN chill_3party.third_party.updated_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT FK_D952467BDE12AB56 FOREIGN KEY (created_by) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_D952467BDE12AB56 ON chill_3party.third_party (created_by)');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,10 +15,31 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* migrate data from 3party.civility to chill_main_civility table
* migrate data from 3party.civility to chill_main_civility table.
*/
final class Version20211007150459 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->throwIrreversibleMigrationException('Reversible migration not implemented');
// for reference:
$this->addSql('CREATE SEQUENCE chill_3party.party_civility_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_3party.party_civility (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B23D6A298');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BFDEF8996');
$this->addSql('ALTER TABLE chill_3party.third_party ADD civility INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party ADD profession INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party DROP civility_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP profession_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP kind');
$this->addSql('ALTER TABLE chill_3party.third_party DROP canonicalized');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467b384d4799 FOREIGN KEY (civility) REFERENCES chill_3party.party_civility (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467bba930d69 FOREIGN KEY (profession) REFERENCES chill_3party.party_profession (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE UNIQUE INDEX uniq_d952467b384d4799 ON chill_3party.third_party (civility)');
$this->addSql('CREATE UNIQUE INDEX uniq_d952467bba930d69 ON chill_3party.third_party (profession)');
}
public function getDescription(): string
{
return 'migrate data from 3party.civility to chill_main_civility table';
@@ -45,25 +73,4 @@ final class Version20211007150459 extends AbstractMigration
$this->addSql('CREATE INDEX IDX_D952467B23D6A298 ON chill_3party.third_party (civility_id)');
$this->addSql('CREATE INDEX IDX_D952467BFDEF8996 ON chill_3party.third_party (profession_id)');
}
public function down(Schema $schema): void
{
$this->throwIrreversibleMigrationException('Reversible migration not implemented');
// for reference:
$this->addSql('CREATE SEQUENCE chill_3party.party_civility_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
$this->addSql('CREATE TABLE chill_3party.party_civility (id INT NOT NULL, name JSON NOT NULL, active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467B23D6A298');
$this->addSql('ALTER TABLE chill_3party.third_party DROP CONSTRAINT FK_D952467BFDEF8996');
$this->addSql('ALTER TABLE chill_3party.third_party ADD civility INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party ADD profession INT DEFAULT NULL');
$this->addSql('ALTER TABLE chill_3party.third_party DROP civility_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP profession_id');
$this->addSql('ALTER TABLE chill_3party.third_party DROP kind');
$this->addSql('ALTER TABLE chill_3party.third_party DROP canonicalized');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467b384d4799 FOREIGN KEY (civility) REFERENCES chill_3party.party_civility (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE chill_3party.third_party ADD CONSTRAINT fk_d952467bba930d69 FOREIGN KEY (profession) REFERENCES chill_3party.party_profession (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE UNIQUE INDEX uniq_d952467b384d4799 ON chill_3party.third_party (civility)');
$this->addSql('CREATE UNIQUE INDEX uniq_d952467bba930d69 ON chill_3party.third_party (profession)');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,10 +15,20 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Create trigger for canonicalisation on 3party + indexes
* Create trigger for canonicalisation on 3party + indexes.
*/
final class Version20211007165001 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('DROP TRIGGER canonicalize_fullname_on_update ON chill_3party.third_party');
$this->addSql('DROP TRIGGER canonicalize_fullname_on_insert ON chill_3party.third_party');
$this->addSql('DROP FUNCTION chill_3party.canonicalize()');
$this->addSql('
DROP INDEX chill_3party.chill_custom_canonicalized_trgm_idx_gist
');
}
public function getDescription(): string
{
return 'Create trigger for canonicalisation on 3party + indexes';
@@ -54,33 +71,23 @@ final class Version20211007165001 extends AbstractMigration
END
$$
");
$this->addSql("
$this->addSql('
CREATE TRIGGER canonicalize_fullname_on_insert
BEFORE INSERT
ON chill_3party.third_party
FOR EACH ROW
EXECUTE procedure chill_3party.canonicalize();
");
$this->addSql("
');
$this->addSql('
CREATE TRIGGER canonicalize_fullname_on_update
BEFORE UPDATE
ON chill_3party.third_party
FOR EACH ROW
EXECUTE procedure chill_3party.canonicalize();
");
$this->addSql("
');
$this->addSql('
CREATE INDEX chill_custom_canonicalized_trgm_idx_gist
ON chill_3party.third_party USING GIST (canonicalized gist_trgm_ops) WHERE active IS TRUE
");
}
public function down(Schema $schema): void
{
$this->addSql('DROP TRIGGER canonicalize_fullname_on_update ON chill_3party.third_party');
$this->addSql('DROP TRIGGER canonicalize_fullname_on_insert ON chill_3party.third_party');
$this->addSql('DROP FUNCTION chill_3party.canonicalize()');
$this->addSql("
DROP INDEX chill_3party.chill_custom_canonicalized_trgm_idx_gist
");
');
}
}

View File

@@ -1,5 +1,12 @@
<?php
/**
* 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.
*/
declare(strict_types=1);
namespace Chill\Migrations\ThirdParty;
@@ -8,10 +15,15 @@ use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Add anonymous flag for contacts
* Add anonymous flag for contacts.
*/
final class Version20211007194942 extends AbstractMigration
{
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP contact_data_anonymous');
}
public function getDescription(): string
{
return 'Add anonymous flag for contacts';
@@ -21,9 +33,4 @@ final class Version20211007194942 extends AbstractMigration
{
$this->addSql('ALTER TABLE chill_3party.third_party ADD contact_data_anonymous BOOLEAN DEFAULT \'false\' NOT NULL;');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE chill_3party.third_party DROP contact_data_anonymous');
}
}