mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-13 05:44:24 +00:00
Merge branch 'master' into export
This commit is contained in:
commit
11439f96c2
@ -3,7 +3,7 @@ services:
|
|||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- composer config github-oauth.github.com $GITHUB_TOKEN
|
- composer config github-oauth.github.com $GITHUB_TOKEN
|
||||||
- composer install --no-interaction --ignore-platform-reqs
|
- composer install --no-interaction
|
||||||
- cp Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml Tests/Fixtures/App/app/config/parameters.yml
|
- cp Tests/Fixtures/App/app/config/parameters.gitlab-ci.yml Tests/Fixtures/App/app/config/parameters.yml
|
||||||
- php Tests/Fixtures/App/app/console.php --env=test cache:warmup
|
- php Tests/Fixtures/App/app/console.php --env=test cache:warmup
|
||||||
- php Tests/Fixtures/App/app/console.php doctrine:migrations:migrate --env=test --no-interaction
|
- php Tests/Fixtures/App/app/console.php doctrine:migrations:migrate --env=test --no-interaction
|
||||||
|
259
Controller/PersonAddressController.php
Normal file
259
Controller/PersonAddressController.php
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016, 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\PersonBundle\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Chill\MainBundle\Form\Type\AddressType;
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Doctrine\Common\Collections\Criteria;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for addresses associated with person
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
* @author Champs Libres <info@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PersonAddressController extends Controller
|
||||||
|
{
|
||||||
|
|
||||||
|
public function listAction($person_id)
|
||||||
|
{
|
||||||
|
$person = $this->getDoctrine()->getManager()
|
||||||
|
->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($person_id);
|
||||||
|
|
||||||
|
if ($person === NULL) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person,
|
||||||
|
"You are not allowed to edit this person.");
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:Address:list.html.twig', array(
|
||||||
|
'person' => $person
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newAction($person_id)
|
||||||
|
{
|
||||||
|
$person = $this->getDoctrine()->getManager()
|
||||||
|
->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($person_id);
|
||||||
|
|
||||||
|
if ($person === NULL) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
|
"You are not allowed to edit this person.");
|
||||||
|
|
||||||
|
$address = new Address();
|
||||||
|
|
||||||
|
$form = $this->createCreateForm($person, $address);
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:Address:new.html.twig', array(
|
||||||
|
'person' => $person,
|
||||||
|
'form' => $form->createView()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createAction($person_id, Request $request)
|
||||||
|
{
|
||||||
|
$person = $this->getDoctrine()->getManager()
|
||||||
|
->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($person_id);
|
||||||
|
|
||||||
|
if ($person === NULL) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
|
"You are not allowed to edit this person.");
|
||||||
|
|
||||||
|
$address = new Address();
|
||||||
|
|
||||||
|
$form = $this->createCreateForm($person, $address);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$address = $form->getData();
|
||||||
|
$person->addAddress($address);
|
||||||
|
|
||||||
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
$em->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success',
|
||||||
|
$this->get('translator')->trans('The new address was created successfully')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_address_list', array(
|
||||||
|
'person_id' => $person->getId()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:Address:new.html.twig', array(
|
||||||
|
'person' => $person,
|
||||||
|
'form' => $form->createView()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function editAction($person_id, $address_id)
|
||||||
|
{
|
||||||
|
$person = $this->getDoctrine()->getManager()
|
||||||
|
->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($person_id);
|
||||||
|
|
||||||
|
if ($person === NULL) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
|
"You are not allowed to edit this person.");
|
||||||
|
|
||||||
|
$address = $this->findAddressById($person, $address_id);
|
||||||
|
|
||||||
|
$form = $this->createEditForm($person, $address);
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:Address:edit.html.twig', array(
|
||||||
|
'person' => $person,
|
||||||
|
'address' => $address,
|
||||||
|
'form' => $form->createView()
|
||||||
|
));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateAction($person_id, $address_id, Request $request)
|
||||||
|
{
|
||||||
|
$person = $this->getDoctrine()->getManager()
|
||||||
|
->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($person_id);
|
||||||
|
|
||||||
|
if ($person === NULL) {
|
||||||
|
throw $this->createNotFoundException("Person with id $person_id not"
|
||||||
|
. " found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
|
"You are not allowed to edit this person.");
|
||||||
|
|
||||||
|
$address = $this->findAddressById($person, $address_id);
|
||||||
|
|
||||||
|
$form = $this->createEditForm($person, $address);
|
||||||
|
|
||||||
|
$form->handleRequest($request);
|
||||||
|
|
||||||
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
|
$this->getDoctrine()->getManager()
|
||||||
|
->flush();
|
||||||
|
|
||||||
|
$this->addFlash('success', $this->get('translator')->trans(
|
||||||
|
"The address has been successfully updated"));
|
||||||
|
|
||||||
|
return $this->redirectToRoute('chill_person_address_list', array(
|
||||||
|
'person_id' => $person->getId()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->render('ChillPersonBundle:Address:edit.html.twig', array(
|
||||||
|
'person' => $person,
|
||||||
|
'address' => $address,
|
||||||
|
'form' => $form->createView()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param Person $person
|
||||||
|
* @param Address $address
|
||||||
|
* @return \Symfony\Component\Form\Form
|
||||||
|
*/
|
||||||
|
protected function createEditForm(Person $person, Address $address)
|
||||||
|
{
|
||||||
|
$form = $this->createForm(AddressType::class, $address, array(
|
||||||
|
'method' => 'POST',
|
||||||
|
'action' => $this->generateUrl('chill_person_address_update', array(
|
||||||
|
'person_id' => $person->getId(),
|
||||||
|
'address_id' => $address->getId()
|
||||||
|
))
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->add('submit', 'submit', array(
|
||||||
|
'label' => 'Submit'
|
||||||
|
));
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param Person $person
|
||||||
|
* @param Address $address
|
||||||
|
* @return \Symfony\Component\Form\Form
|
||||||
|
*/
|
||||||
|
protected function createCreateForm(Person $person, Address $address)
|
||||||
|
{
|
||||||
|
$form = $this->createForm(AddressType::class, $address, array(
|
||||||
|
'method' => 'POST',
|
||||||
|
'action' => $this->generateUrl('chill_person_address_create', array(
|
||||||
|
'person_id' => $person->getId()
|
||||||
|
))
|
||||||
|
));
|
||||||
|
|
||||||
|
$form->add('submit', 'submit', array(
|
||||||
|
'label' => 'Submit'
|
||||||
|
));
|
||||||
|
|
||||||
|
return $form;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param Person $person
|
||||||
|
* @param int $address_id
|
||||||
|
* @return Address
|
||||||
|
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException if the address id does not exists or is not associated with given person
|
||||||
|
*/
|
||||||
|
protected function findAddressById(Person $person, $address_id)
|
||||||
|
{
|
||||||
|
// filtering address
|
||||||
|
$criteria = Criteria::create()
|
||||||
|
->where(Criteria::expr()->eq('id', $address_id))
|
||||||
|
->setMaxResults(1);
|
||||||
|
$addresses = $person->getAddresses()->matching($criteria);
|
||||||
|
|
||||||
|
if (count($addresses) === 0) {
|
||||||
|
throw $this->createNotFoundException("Address with id $address_id "
|
||||||
|
. "matching person $person_id not found ");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $addresses->first();
|
||||||
|
}
|
||||||
|
}
|
@ -75,7 +75,7 @@ class PersonController extends Controller
|
|||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
'You are not allowed to edit this person');
|
'You are not allowed to edit this person');
|
||||||
|
|
||||||
$form = $this->createForm(new PersonType(), $person,
|
$form = $this->createForm(PersonType::class, $person,
|
||||||
array(
|
array(
|
||||||
"action" => $this->generateUrl('chill_person_general_update',
|
"action" => $this->generateUrl('chill_person_general_update',
|
||||||
array("person_id" => $person_id)),
|
array("person_id" => $person_id)),
|
||||||
@ -98,7 +98,7 @@ class PersonController extends Controller
|
|||||||
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
$this->denyAccessUnlessGranted('CHILL_PERSON_UPDATE', $person,
|
||||||
'You are not allowed to edit this person');
|
'You are not allowed to edit this person');
|
||||||
|
|
||||||
$form = $this->createForm(new PersonType(), $person,
|
$form = $this->createForm(PersonType::class, $person,
|
||||||
array("cFGroup" => $this->getCFGroup()));
|
array("cFGroup" => $this->getCFGroup()));
|
||||||
|
|
||||||
if ($request->getMethod() === 'POST') {
|
if ($request->getMethod() === 'POST') {
|
||||||
@ -302,7 +302,9 @@ class PersonController extends Controller
|
|||||||
|
|
||||||
$dql = 'SELECT p from ChillPersonBundle:Person p WHERE '
|
$dql = 'SELECT p from ChillPersonBundle:Person p WHERE '
|
||||||
. 'LOWER(p.firstName) LIKE LOWER(:firstName)'
|
. 'LOWER(p.firstName) LIKE LOWER(:firstName)'
|
||||||
. ' OR LOWER(p.lastName) LIKE LOWER(:lastName)';
|
. ' OR LOWER(p.lastName) LIKE LOWER(:lastName)'
|
||||||
|
. ' OR LOWER(p.firstName) LIKE LOWER(:lastName)'
|
||||||
|
. ' OR LOWER(p.lastName) LIKE LOWER(:firstName)';
|
||||||
|
|
||||||
$query->setParameter('firstName', $form['firstName']->getData())
|
$query->setParameter('firstName', $form['firstName']->getData())
|
||||||
->setParameter('lastName', $form['lastName']->getData());
|
->setParameter('lastName', $form['lastName']->getData());
|
||||||
|
@ -26,6 +26,8 @@ use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
|||||||
use Doctrine\Common\Persistence\ObjectManager;
|
use Doctrine\Common\Persistence\ObjectManager;
|
||||||
use Chill\PersonBundle\Entity\Person;
|
use Chill\PersonBundle\Entity\Person;
|
||||||
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
|
||||||
|
use Chill\MainBundle\DataFixtures\ORM\LoadPostalCodes;
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load people into database
|
* Load people into database
|
||||||
@ -38,6 +40,13 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
|
|
||||||
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
use \Symfony\Component\DependencyInjection\ContainerAwareTrait;
|
||||||
|
|
||||||
|
protected $faker;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->faker = \Faker\Factory::create('fr_FR');
|
||||||
|
}
|
||||||
|
|
||||||
public function prepare()
|
public function prepare()
|
||||||
{
|
{
|
||||||
//prepare days, month, years
|
//prepare days, month, years
|
||||||
@ -114,12 +123,27 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
$firstName = $this->firstNamesFemale[array_rand($this->firstNamesFemale)];
|
$firstName = $this->firstNamesFemale[array_rand($this->firstNamesFemale)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add an address on 80% of the created people
|
||||||
|
if (rand(0,100) < 80) {
|
||||||
|
$address = $this->getRandomAddress();
|
||||||
|
// on 30% of those person, add multiple addresses
|
||||||
|
if (rand(0,10) < 4) {
|
||||||
|
$address = array(
|
||||||
|
$address,
|
||||||
|
$this->getRandomAddress()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$address = null;
|
||||||
|
}
|
||||||
|
|
||||||
$person = array(
|
$person = array(
|
||||||
'FirstName' => $firstName,
|
'FirstName' => $firstName,
|
||||||
'LastName' => $lastName,
|
'LastName' => $lastName,
|
||||||
'Gender' => $sex,
|
'Gender' => $sex,
|
||||||
'Nationality' => (rand(0,100) > 50) ? NULL: 'BE',
|
'Nationality' => (rand(0,100) > 50) ? NULL: 'BE',
|
||||||
'center' => (rand(0,1) == 0) ? 'centerA': 'centerB',
|
'center' => (rand(0,1) == 0) ? 'centerA': 'centerB',
|
||||||
|
'Address' => $address,
|
||||||
'maritalStatus' => $this->maritalStatusRef[array_rand($this->maritalStatusRef)]
|
'maritalStatus' => $this->maritalStatusRef[array_rand($this->maritalStatusRef)]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -142,10 +166,18 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
'Email' => "Email d'un ami: roger@tt.com",
|
'Email' => "Email d'un ami: roger@tt.com",
|
||||||
'CountryOfBirth' => 'BE',
|
'CountryOfBirth' => 'BE',
|
||||||
'Nationality' => 'BE',
|
'Nationality' => 'BE',
|
||||||
'CFData' => array()
|
'CFData' => array(),
|
||||||
|
'Address' => null
|
||||||
), $specific);
|
), $specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new person from array data
|
||||||
|
*
|
||||||
|
* @param array $person
|
||||||
|
* @param ObjectManager $manager
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
private function addAPerson(array $person, ObjectManager $manager)
|
private function addAPerson(array $person, ObjectManager $manager)
|
||||||
{
|
{
|
||||||
$p = new Person();
|
$p = new Person();
|
||||||
@ -164,13 +196,51 @@ class LoadPeople extends AbstractFixture implements OrderedFixtureInterface, Con
|
|||||||
$value = $this->getReference($value);
|
$value = $this->getReference($value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
call_user_func(array($p, 'set'.$key), $value);
|
|
||||||
|
//try to add the data using the setSomething function,
|
||||||
|
// if not possible, fallback to addSomething function
|
||||||
|
if (method_exists($p, 'set'.$key)) {
|
||||||
|
call_user_func(array($p, 'set'.$key), $value);
|
||||||
|
} elseif (method_exists($p, 'add'.$key)) {
|
||||||
|
// if we have a "addSomething", we may have multiple items to add
|
||||||
|
// so, we set the value in an array if it is not an array, and
|
||||||
|
// will call the function addSomething multiple times
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$value = array($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($value as $v) {
|
||||||
|
if ($v !== NULL) {
|
||||||
|
call_user_func(array($p, 'add'.$key), $v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$manager->persist($p);
|
$manager->persist($p);
|
||||||
echo "add person'".$p->__toString()."'\n";
|
echo "add person'".$p->__toString()."'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creata a random address
|
||||||
|
*
|
||||||
|
* @return Address
|
||||||
|
*/
|
||||||
|
private function getRandomAddress()
|
||||||
|
{
|
||||||
|
return (new Address())
|
||||||
|
->setStreetAddress1($this->faker->streetAddress)
|
||||||
|
->setStreetAddress2(
|
||||||
|
rand(0,9) > 5 ? $this->faker->streetAddress : ''
|
||||||
|
)
|
||||||
|
->setPostcode($this->getReference(
|
||||||
|
LoadPostalCodes::$refs[array_rand(LoadPostalCodes::$refs)]
|
||||||
|
))
|
||||||
|
->setValidFrom($this->faker->dateTimeBetween('-5 years'))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
private function getCountry($countryCode)
|
private function getCountry($countryCode)
|
||||||
{
|
{
|
||||||
if ($countryCode === NULL) {
|
if ($countryCode === NULL) {
|
||||||
|
@ -32,10 +32,25 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
// set configuration for validation
|
// set configuration for validation
|
||||||
$container->setParameter('chill_person.validation.birtdate_not_before',
|
$container->setParameter('chill_person.validation.birtdate_not_before',
|
||||||
$config['validation']['birthdate_not_after']);
|
$config['validation']['birthdate_not_after']);
|
||||||
|
|
||||||
|
$this->handlePersonFieldsParameters($container, $config['person_fields']);
|
||||||
|
|
||||||
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
|
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
|
||||||
$loader->load('services.yml');
|
$loader->load('services.yml');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
|
||||||
|
{
|
||||||
|
if (array_key_exists('enabled', $config)) {
|
||||||
|
unset($config['enabled']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$container->setParameter('chill_person.person_fields', $config);
|
||||||
|
|
||||||
|
foreach ($config as $key => $value) {
|
||||||
|
$container->setParameter('chill_person.person_fields.'.$key, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private function declarePersonAsCustomizable (ContainerBuilder $container)
|
private function declarePersonAsCustomizable (ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
@ -67,6 +82,18 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
|
|||||||
$asseticConfig['bundles'][] = 'ChillPersonBundle';
|
$asseticConfig['bundles'][] = 'ChillPersonBundle';
|
||||||
$container->prependExtensionConfig('assetic',
|
$container->prependExtensionConfig('assetic',
|
||||||
array('bundles' => array('ChillPersonBundle')));
|
array('bundles' => array('ChillPersonBundle')));
|
||||||
|
|
||||||
|
//add person_fields parameter as global
|
||||||
|
$chillPersonConfig = $container->getExtensionConfig($this->getAlias());
|
||||||
|
$config = $this->processConfiguration(new Configuration(), $chillPersonConfig);
|
||||||
|
$twigConfig = array(
|
||||||
|
'globals' => array(
|
||||||
|
'chill_person' => array(
|
||||||
|
'fields' => $config['person_fields']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$container->prependExtensionConfig('twig', $twigConfig);
|
||||||
|
|
||||||
$this-> declarePersonAsCustomizable($container);
|
$this-> declarePersonAsCustomizable($container);
|
||||||
|
|
||||||
|
@ -27,40 +27,71 @@ class Configuration implements ConfigurationInterface
|
|||||||
$rootNode
|
$rootNode
|
||||||
->canBeDisabled()
|
->canBeDisabled()
|
||||||
->children()
|
->children()
|
||||||
->arrayNode('search')
|
->arrayNode('search')
|
||||||
->canBeDisabled()
|
->canBeDisabled()
|
||||||
->children()
|
->children()
|
||||||
->booleanNode('use_double_metaphone')
|
->booleanNode('use_double_metaphone')
|
||||||
->defaultFalse()
|
->defaultFalse()
|
||||||
->end()
|
->end() // use_double_metaphone, parent = children for 'search'
|
||||||
->booleanNode('use_trigrams')
|
->booleanNode('use_trigrams')
|
||||||
->defaultFalse()
|
->defaultFalse()
|
||||||
->end()
|
->end() // use_trigrams, parent = children of 'search'
|
||||||
->end()
|
->end() //children for 'search', parent = array node 'search'
|
||||||
->end()
|
->end() // array 'search', parent = children of root
|
||||||
->arrayNode('validation')
|
->arrayNode('validation')
|
||||||
->canBeDisabled()
|
->canBeDisabled()
|
||||||
->children()
|
->children()
|
||||||
->scalarNode('birthdate_not_after')
|
->scalarNode('birthdate_not_after')
|
||||||
->info($this->validationBirthdateNotAfterInfos)
|
->info($this->validationBirthdateNotAfterInfos)
|
||||||
->defaultValue('P1D')
|
->defaultValue('P1D')
|
||||||
->validate()
|
->validate()
|
||||||
->ifTrue(function($period) {
|
->ifTrue(function($period) {
|
||||||
try {
|
try {
|
||||||
$interval = new \DateInterval($period);
|
$interval = new \DateInterval($period);
|
||||||
} catch (\Exception $ex) {
|
} catch (\Exception $ex) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
})
|
})
|
||||||
->thenInvalid('Invalid period for birthdate validation : "%s" '
|
->thenInvalid('Invalid period for birthdate validation : "%s" '
|
||||||
. 'The parameter should match duration as defined by ISO8601 : '
|
. 'The parameter should match duration as defined by ISO8601 : '
|
||||||
. 'https://en.wikipedia.org/wiki/ISO_8601#Durations')
|
. 'https://en.wikipedia.org/wiki/ISO_8601#Durations')
|
||||||
->end()
|
->end() // birthdate_not_after, parent = children of validation
|
||||||
->end()
|
|
||||||
->end();
|
->end() // children for 'validation', parent = validation
|
||||||
|
->end() //validation, parent = children of root
|
||||||
|
->end() // children of root, parent = root
|
||||||
|
->arrayNode('person_fields')
|
||||||
|
->canBeDisabled()
|
||||||
|
->children()
|
||||||
|
->append($this->addFieldNode('place_of_birth'))
|
||||||
|
->append($this->addFieldNode('email'))
|
||||||
|
->append($this->addFieldNode('phonenumber'))
|
||||||
|
->append($this->addFieldNode('nationality'))
|
||||||
|
->append($this->addFieldNode('country_of_birth'))
|
||||||
|
->append($this->addFieldNode('marital_status'))
|
||||||
|
->append($this->addFieldNode('spoken_languages'))
|
||||||
|
->append($this->addFieldNode('address'))
|
||||||
|
->end() //children for 'person_fields', parent = array 'person_fields'
|
||||||
|
->end() // person_fields, parent = children of root
|
||||||
|
->end() // children of 'root', parent = root
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
return $treeBuilder;
|
return $treeBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function addFieldNode($key)
|
||||||
|
{
|
||||||
|
$tree = new TreeBuilder();
|
||||||
|
$node = $tree->root($key, 'enum');
|
||||||
|
|
||||||
|
$node
|
||||||
|
->values(array('hidden', 'visible'))
|
||||||
|
->defaultValue('visible')
|
||||||
|
->info("If the field $key must be shown")
|
||||||
|
->end();
|
||||||
|
//var_dump($node);
|
||||||
|
return $node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,8 @@ use Chill\MainBundle\Entity\Country;
|
|||||||
use Chill\PersonBundle\Entity\MaritalStatus;
|
use Chill\PersonBundle\Entity\MaritalStatus;
|
||||||
use Doctrine\Common\Collections\ArrayCollection;
|
use Doctrine\Common\Collections\ArrayCollection;
|
||||||
use Chill\MainBundle\Entity\HasCenterInterface;
|
use Chill\MainBundle\Entity\HasCenterInterface;
|
||||||
|
use Chill\MainBundle\Entity\Address;
|
||||||
|
use Doctrine\Common\Collections\Criteria;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Person
|
* Person
|
||||||
@ -100,9 +102,16 @@ class Person implements HasCenterInterface {
|
|||||||
/** @var array Array where customfield's data are stored */
|
/** @var array Array where customfield's data are stored */
|
||||||
private $cFData;
|
private $cFData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Doctrine\Common\Collections\Collection
|
||||||
|
*/
|
||||||
|
private $addresses;
|
||||||
|
|
||||||
public function __construct(\DateTime $opening = null) {
|
public function __construct(\DateTime $opening = null) {
|
||||||
$this->accompanyingPeriods = new ArrayCollection();
|
$this->accompanyingPeriods = new ArrayCollection();
|
||||||
$this->spokenLanguages = new ArrayCollection();
|
$this->spokenLanguages = new ArrayCollection();
|
||||||
|
$this->addresses = new ArrayCollection();
|
||||||
|
|
||||||
if ($opening === null) {
|
if ($opening === null) {
|
||||||
$opening = new \DateTime();
|
$opening = new \DateTime();
|
||||||
@ -597,6 +606,45 @@ class Person implements HasCenterInterface {
|
|||||||
return $this->spokenLanguages;
|
return $this->spokenLanguages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addAddress(Address $address)
|
||||||
|
{
|
||||||
|
$this->addresses[] = $address;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function removeAddress(Address $address)
|
||||||
|
{
|
||||||
|
$this->addresses->removeElement($address);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, the addresses are ordered by date, descending (the most
|
||||||
|
* recent first)
|
||||||
|
*
|
||||||
|
* @return \Chill\MainBundle\Entity\Address[]
|
||||||
|
*/
|
||||||
|
public function getAddresses()
|
||||||
|
{
|
||||||
|
return $this->addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastAddress(\DateTime $date = null)
|
||||||
|
{
|
||||||
|
if ($date === null) {
|
||||||
|
$date = new \DateTime('now');
|
||||||
|
}
|
||||||
|
|
||||||
|
$addresses = $this->getAddresses();
|
||||||
|
|
||||||
|
if ($addresses == null) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $addresses->first();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation callback that checks if the accompanying periods are valid
|
* Validation callback that checks if the accompanying periods are valid
|
||||||
*
|
*
|
||||||
|
@ -28,6 +28,25 @@ use Chill\PersonBundle\Form\Type\GenderType;
|
|||||||
|
|
||||||
class PersonType extends AbstractType
|
class PersonType extends AbstractType
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* array of configuration for person_fields.
|
||||||
|
*
|
||||||
|
* Contains whether we should add fields some optional fields (optional per
|
||||||
|
* instance)
|
||||||
|
*
|
||||||
|
* @var string[]
|
||||||
|
*/
|
||||||
|
protected $config = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string[] $personFieldsConfiguration configuration of visibility of some fields
|
||||||
|
*/
|
||||||
|
public function __construct(array $personFieldsConfiguration)
|
||||||
|
{
|
||||||
|
$this->config = $personFieldsConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FormBuilderInterface $builder
|
* @param FormBuilderInterface $builder
|
||||||
* @param array $options
|
* @param array $options
|
||||||
@ -38,27 +57,48 @@ class PersonType extends AbstractType
|
|||||||
->add('firstName')
|
->add('firstName')
|
||||||
->add('lastName')
|
->add('lastName')
|
||||||
->add('birthdate', 'date', array('required' => false, 'widget' => 'single_text', 'format' => 'dd-MM-yyyy'))
|
->add('birthdate', 'date', array('required' => false, 'widget' => 'single_text', 'format' => 'dd-MM-yyyy'))
|
||||||
->add('placeOfBirth', 'text', array('required' => false))
|
|
||||||
->add('gender', new GenderType(), array(
|
->add('gender', new GenderType(), array(
|
||||||
'required' => true
|
'required' => true
|
||||||
))
|
))
|
||||||
->add('memo', 'textarea', array('required' => false))
|
->add('memo', 'textarea', array('required' => false))
|
||||||
->add('phonenumber', 'textarea', array('required' => false))
|
;
|
||||||
->add('email', 'textarea', array('required' => false))
|
|
||||||
->add('countryOfBirth', 'select2_chill_country', array(
|
if ($this->config['place_of_birth'] === 'visible') {
|
||||||
|
$builder->add('placeOfBirth', 'text', array('required' => false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->config['phonenumber'] === 'visible') {
|
||||||
|
$builder->add('phonenumber', 'textarea', array('required' => false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->config['email'] === 'visible') {
|
||||||
|
$builder->add('email', 'textarea', array('required' => false));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->config['country_of_birth'] === 'visible') {
|
||||||
|
$builder->add('countryOfBirth', 'select2_chill_country', array(
|
||||||
'required' => false
|
'required' => false
|
||||||
))
|
));
|
||||||
->add('nationality', 'select2_chill_country', array(
|
}
|
||||||
|
|
||||||
|
if ($this->config['nationality'] === 'visible') {
|
||||||
|
$builder->add('nationality', 'select2_chill_country', array(
|
||||||
'required' => false
|
'required' => false
|
||||||
))
|
));
|
||||||
->add('spokenLanguages', 'select2_chill_language', array(
|
}
|
||||||
|
|
||||||
|
if ($this->config['spoken_languages'] === 'visible') {
|
||||||
|
$builder->add('spokenLanguages', 'select2_chill_language', array(
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'multiple' => true
|
'multiple' => true
|
||||||
))
|
));
|
||||||
->add('maritalStatus', 'select2_chill_marital_status', array(
|
}
|
||||||
|
|
||||||
|
if ($this->config['marital_status'] === 'visible'){
|
||||||
|
$builder->add('maritalStatus', 'select2_chill_marital_status', array(
|
||||||
'required' => false
|
'required' => false
|
||||||
))
|
));
|
||||||
;
|
}
|
||||||
|
|
||||||
if($options['cFGroup']) {
|
if($options['cFGroup']) {
|
||||||
$builder
|
$builder
|
||||||
|
161
Form/Type/PickPersonType.php
Normal file
161
Form/Type/PickPersonType.php
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Champs-Libres <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\PersonBundle\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
use Chill\MainBundle\Entity\Center;
|
||||||
|
use Chill\PersonBundle\Entity\PersonRepository;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||||
|
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
|
||||||
|
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
|
||||||
|
use Symfony\Component\Security\Core\Role\Role;
|
||||||
|
use Chill\MainBundle\Entity\GroupCenter;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type allow to pick a person.
|
||||||
|
*
|
||||||
|
* The form is embedded in a select2 input.
|
||||||
|
*
|
||||||
|
* The people may be filtered :
|
||||||
|
*
|
||||||
|
* - with the `centers` option, only the people associated with the given center(s)
|
||||||
|
* are seen. May be an instance of `Chill\MainBundle\Entity\Center`, or an array of
|
||||||
|
* `Chill\MainBundle\Entity\Center`. By default, all the reachable centers as selected.
|
||||||
|
* - with the `role` option, only the people belonging to the reachable center for the
|
||||||
|
* given role are displayed.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PickPersonType extends AbstractType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var PersonRepository
|
||||||
|
*/
|
||||||
|
protected $personRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Chill\MainBundle\Entity\User
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var AuthorizationHelper
|
||||||
|
*/
|
||||||
|
protected $authorizationHelper;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
PersonRepository $personRepository,
|
||||||
|
TokenStorageInterface $tokenStorage,
|
||||||
|
AuthorizationHelper $authorizationHelper
|
||||||
|
)
|
||||||
|
{
|
||||||
|
$this->personRepository = $personRepository;
|
||||||
|
$this->user = $tokenStorage->getToken()->getUser();
|
||||||
|
$this->authorizationHelper = $authorizationHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$qb = $options['query_builder'];
|
||||||
|
|
||||||
|
if ($options['role'] === NULL) {
|
||||||
|
$centers = array_map(function (GroupCenter $g) {
|
||||||
|
|
||||||
|
return $g->getCenter();
|
||||||
|
}, $this->user->getGroupCenters()->toArray());
|
||||||
|
} else {
|
||||||
|
$centers = $this->authorizationHelper
|
||||||
|
->getReachableCenters($this->user, $options['role']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($options['centers'] === NULL) {
|
||||||
|
// we select all selected centers
|
||||||
|
$selectedCenters = $centers;
|
||||||
|
} else {
|
||||||
|
$selectedCenters = array();
|
||||||
|
$options['centers'] = is_array($options['centers']) ?
|
||||||
|
$options['centers'] : array($options['centers']);
|
||||||
|
|
||||||
|
foreach ($options['centers'] as $c) {
|
||||||
|
// check that every member of the array is a center
|
||||||
|
if (!$c instanceof Center) {
|
||||||
|
throw new \RuntimeException('Every member of the "centers" '
|
||||||
|
. 'option must be an instance of '.Center::class);
|
||||||
|
}
|
||||||
|
if (!in_array($c->getId(), array_map(
|
||||||
|
function(Center $c) { return $c->getId();},
|
||||||
|
$centers))) {
|
||||||
|
throw new AccessDeniedException('The given center is not reachable');
|
||||||
|
}
|
||||||
|
$selectedCenters[] = $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$qb
|
||||||
|
->orderBy('p.firstName', 'ASC')
|
||||||
|
->orderBy('p.lastName', 'ASC')
|
||||||
|
->where($qb->expr()->in('p.center', ':centers'))
|
||||||
|
->setParameter('centers', $selectedCenters)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
parent::configureOptions($resolver);
|
||||||
|
|
||||||
|
// add the possibles options for this type
|
||||||
|
$resolver->setDefined('centers')
|
||||||
|
->addAllowedTypes('centers', array('array', Center::class, 'null'))
|
||||||
|
->setDefault('centers', null)
|
||||||
|
->setDefined('role')
|
||||||
|
->addAllowedTypes('role', array(Role::class, 'null'))
|
||||||
|
->setDefault('role', null)
|
||||||
|
;
|
||||||
|
|
||||||
|
// add the default options
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'class' => Person::class,
|
||||||
|
'choice_label' => function(Person $p) {
|
||||||
|
return $p->getFirstname().' '.$p->getLastname();
|
||||||
|
},
|
||||||
|
'placeholder' => 'Pick a person',
|
||||||
|
'choice_attr' => function(Person $p) {
|
||||||
|
return array(
|
||||||
|
'data-center' => $p->getCenter()->getId()
|
||||||
|
);
|
||||||
|
},
|
||||||
|
'attr' => array('class' => 'select2 '),
|
||||||
|
'query_builder' => $this->personRepository->createQueryBuilder('p')
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParent()
|
||||||
|
{
|
||||||
|
return \Symfony\Bridge\Doctrine\Form\Type\EntityType::class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -72,4 +72,10 @@ Chill\PersonBundle\Entity\Person:
|
|||||||
inverseJoinColumns:
|
inverseJoinColumns:
|
||||||
language_id:
|
language_id:
|
||||||
referencedColumnName: id
|
referencedColumnName: id
|
||||||
|
addresses:
|
||||||
|
targetEntity: Chill\MainBundle\Entity\Address
|
||||||
|
orderBy: { 'validFrom': 'DESC' }
|
||||||
|
joinTable:
|
||||||
|
name: chill_person_persons_to_addresses
|
||||||
|
cascade: [persist, remove, merge, detach]
|
||||||
lifecycleCallbacks: { }
|
lifecycleCallbacks: { }
|
||||||
|
@ -69,6 +69,27 @@ chill_person_accompanying_period_close:
|
|||||||
chill_person_accompanying_period_open:
|
chill_person_accompanying_period_open:
|
||||||
path: /{_locale}/person/{person_id}/accompanying-period/open
|
path: /{_locale}/person/{person_id}/accompanying-period/open
|
||||||
defaults: { _controller: ChillPersonBundle:AccompanyingPeriod:open }
|
defaults: { _controller: ChillPersonBundle:AccompanyingPeriod:open }
|
||||||
|
|
||||||
|
chill_person_address_list:
|
||||||
|
path: /{_locale}/person/{person_id}/address/list
|
||||||
|
defaults: { _controller: ChillPersonBundle:PersonAddress:list }
|
||||||
|
|
||||||
|
chill_person_address_create:
|
||||||
|
path: /{_locale}/person/{person_id}/address/create
|
||||||
|
defaults: { _controller: ChillPersonBundle:PersonAddress:create }
|
||||||
|
methods: [POST]
|
||||||
|
|
||||||
|
chill_person_address_new:
|
||||||
|
path: /{_locale}/person/{person_id}/address/new
|
||||||
|
defaults: { _controller: ChillPersonBundle:PersonAddress:new }
|
||||||
|
|
||||||
|
chill_person_address_edit:
|
||||||
|
path: /{_locale}/person/{person_id}/address/{address_id}/edit
|
||||||
|
defaults: { _controller: ChillPersonBundle:PersonAddress:edit }
|
||||||
|
|
||||||
|
chill_person_address_update:
|
||||||
|
path: /{_locale}/person/{person_id}/address/{address_id}/update
|
||||||
|
defaults: { _controller: ChillPersonBundle:PersonAddress:update }
|
||||||
|
|
||||||
chill_person_export:
|
chill_person_export:
|
||||||
path: /{_locale}/person/export/
|
path: /{_locale}/person/export/
|
||||||
|
@ -1,7 +1,14 @@
|
|||||||
parameters:
|
parameters:
|
||||||
# cl_chill_person.example.class: Chill\PersonBundle\Example
|
# cl_chill_person.example.class: Chill\PersonBundle\Example
|
||||||
|
|
||||||
services:
|
services:
|
||||||
|
chill.person.form.person_creation:
|
||||||
|
class: Chill\PersonBundle\Form\PersonType
|
||||||
|
arguments:
|
||||||
|
- %chill_person.person_fields%
|
||||||
|
tags:
|
||||||
|
- { name: form.type }
|
||||||
|
|
||||||
chill.person.accompanying_period_closing_motive:
|
chill.person.accompanying_period_closing_motive:
|
||||||
class: Chill\PersonBundle\Form\Type\ClosingMotiveType
|
class: Chill\PersonBundle\Form\Type\ClosingMotiveType
|
||||||
scope: request
|
scope: request
|
||||||
@ -93,4 +100,19 @@ services:
|
|||||||
arguments:
|
arguments:
|
||||||
- "@translator"
|
- "@translator"
|
||||||
tags:
|
tags:
|
||||||
- { name: chill.export_aggregator, alias: person_gender_aggregator }
|
- { name: chill.export_aggregator, alias: person_gender_aggregator }
|
||||||
|
|
||||||
|
chill.person.form.type.pick_person:
|
||||||
|
class: Chill\PersonBundle\Form\Type\PickPersonType
|
||||||
|
arguments:
|
||||||
|
- "@chill.person.repository.person"
|
||||||
|
- "@security.token_storage"
|
||||||
|
- "@chill.main.security.authorization.helper"
|
||||||
|
tags:
|
||||||
|
- { name: form.type }
|
||||||
|
|
||||||
|
chill.person.repository.person:
|
||||||
|
class: Chill\PersonBundle\Entity\PersonRepository
|
||||||
|
factory: ['@doctrine.orm.entity_manager', getRepository]
|
||||||
|
arguments:
|
||||||
|
- 'Chill\PersonBundle\Entity\Person'
|
||||||
|
49
Resources/migrations/Version20160310161006.php
Normal file
49
Resources/migrations/Version20160310161006.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Application\Migrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Migrations\AbstractMigration;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a many-to-many relationship between person and addresses
|
||||||
|
*/
|
||||||
|
class Version20160310161006 extends AbstractMigration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function up(Schema $schema)
|
||||||
|
{
|
||||||
|
// 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 TABLE chill_person_persons_to_addresses ('
|
||||||
|
. 'person_id INT NOT NULL, '
|
||||||
|
. 'address_id INT NOT NULL, '
|
||||||
|
. 'PRIMARY KEY(person_id, address_id))');
|
||||||
|
$this->addSql('CREATE INDEX IDX_4655A196217BBB47 '
|
||||||
|
. 'ON chill_person_persons_to_addresses (person_id)');
|
||||||
|
$this->addSql('CREATE INDEX IDX_4655A196F5B7AF75 '
|
||||||
|
. 'ON chill_person_persons_to_addresses (address_id)');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_persons_to_addresses '
|
||||||
|
. 'ADD CONSTRAINT FK_4655A196217BBB47 '
|
||||||
|
. 'FOREIGN KEY (person_id) '
|
||||||
|
. 'REFERENCES Person (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
$this->addSql('ALTER TABLE chill_person_persons_to_addresses '
|
||||||
|
. 'ADD CONSTRAINT FK_4655A196F5B7AF75 '
|
||||||
|
. 'FOREIGN KEY (address_id) '
|
||||||
|
. 'REFERENCES chill_main_address (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Schema $schema
|
||||||
|
*/
|
||||||
|
public function down(Schema $schema)
|
||||||
|
{
|
||||||
|
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
|
||||||
|
|
||||||
|
$this->addSql('DROP TABLE chill_person_persons_to_addresses');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -68,8 +68,24 @@ Reset: 'Remise à zéro'
|
|||||||
'Create accompanying period': 'Nouvelle ouverture-fermeture à une autre date'
|
'Create accompanying period': 'Nouvelle ouverture-fermeture à une autre date'
|
||||||
'Closing motive': 'Motif de clôture'
|
'Closing motive': 'Motif de clôture'
|
||||||
'Person details': 'Détails de la personne'
|
'Person details': 'Détails de la personne'
|
||||||
|
'Update details for %name%': 'Modifier détails de %name%'
|
||||||
Accompanying period list: Périodes d'accompagnement
|
Accompanying period list: Périodes d'accompagnement
|
||||||
|
|
||||||
|
# pickAPersonType
|
||||||
|
Pick a person: Choisir une personne
|
||||||
|
|
||||||
|
#address
|
||||||
|
Since %date%: Depuis le %date%
|
||||||
|
No address given: Pas d'adresse renseignée
|
||||||
|
The address has been successfully updated: L'adresse a été mise à jour avec succès
|
||||||
|
Update address for %name%: Mettre à jour une adresse pour %name%
|
||||||
|
Addresses'history for %name%: Historique des adresses de %name%
|
||||||
|
Addresses'history: Historique des adresses
|
||||||
|
New address for %name% : Nouvelle adresse pour %name%
|
||||||
|
The new address was created successfully: La nouvelle adresse a été créée
|
||||||
|
Add an address: Ajouter une adresse
|
||||||
|
Back to the person details: Retour aux détails de la personne
|
||||||
|
|
||||||
#timeline
|
#timeline
|
||||||
'An accompanying period is opened for %person% on %date%': Une période d'accompagnement a été ouverte le %date% pour %person%
|
'An accompanying period is opened for %person% on %date%': Une période d'accompagnement a été ouverte le %date% pour %person%
|
||||||
'An accompanying period is closed for %person% on %date%': Une période d'accompagnement a été fermée le %date% pour %person%
|
'An accompanying period is closed for %person% on %date%': Une période d'accompagnement a été fermée le %date% pour %person%
|
||||||
|
47
Resources/views/Address/edit.html.twig
Normal file
47
Resources/views/Address/edit.html.twig
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{#
|
||||||
|
* Copyright (C) 2014, 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/>.
|
||||||
|
#}
|
||||||
|
{% extends "ChillPersonBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
|
{% block title 'Update address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1>{{ 'Update address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}</h1>
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_row(form.streetAddress1) }}
|
||||||
|
{{ form_row(form.streetAddress2) }}
|
||||||
|
{{ form_row(form.postCode) }}
|
||||||
|
{{ form_row(form.validFrom) }}
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_person_address_list', { 'person_id' : person.id } ) }}" class="sc-button btn-cancel">
|
||||||
|
{{ 'Back to the list'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ form_row(form.submit, { 'attr' : { 'class': 'sc-button bt-edit' } } ) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock personcontent %}
|
84
Resources/views/Address/list.html.twig
Normal file
84
Resources/views/Address/list.html.twig
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{#
|
||||||
|
* Copyright (C) 2014, 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/>.
|
||||||
|
#}
|
||||||
|
{% extends "ChillPersonBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% import 'ChillMainBundle:Address:macro.html.twig' as address_macros %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'Addresses\'history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1>{{ 'Addresses\'history for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}</h1>
|
||||||
|
|
||||||
|
<table class="records_list">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ 'Valid from'|trans }}</th>
|
||||||
|
<th>{{ 'Address'|trans }}</th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% if person.addresses|length == 0 %}
|
||||||
|
<tr>
|
||||||
|
<td colspan="3">
|
||||||
|
<span class="chill-no-data-statement">{{ 'No address given'|trans }}</span>
|
||||||
|
<a href="{{ path('chill_person_address_new', { 'person_id' : person.id } ) }}">
|
||||||
|
{{ 'Add an address'|trans }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% else %}
|
||||||
|
{% for address in person.addresses %}
|
||||||
|
<tr>
|
||||||
|
<td><strong>{{ 'Since %date%'|trans( { '%date%' : address.validFrom|localizeddate('long', 'none') } ) }}</strong></td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
{{ address_macros._render(address, { 'with_valid_from' : false } ) }}
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_person_address_edit', { 'person_id': person.id, 'address_id' : address.id } ) }}" class="sc-button bt-edit">
|
||||||
|
{{ 'Edit'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_person_view', { 'person_id' : person.id } ) }}" class="sc-button btn-cancel">
|
||||||
|
{{ 'Back to the person details'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_person_address_new', { 'person_id' : person.id } ) }}" class="sc-button btn-create">
|
||||||
|
{{ 'Add an address'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{% endblock personcontent %}
|
47
Resources/views/Address/new.html.twig
Normal file
47
Resources/views/Address/new.html.twig
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{#
|
||||||
|
* Copyright (C) 2014, 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/>.
|
||||||
|
#}
|
||||||
|
{% extends "ChillPersonBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
|
{% block title %}{{ 'New address for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName } )|capitalize }}{% endblock %}
|
||||||
|
|
||||||
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1>{{ 'New address for %name%'|trans({ '%name%': person.firstName ~ ' ' ~ person.lastName } ) }}</h1>
|
||||||
|
|
||||||
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
{{ form_row(form.streetAddress1) }}
|
||||||
|
{{ form_row(form.streetAddress2) }}
|
||||||
|
{{ form_row(form.postCode) }}
|
||||||
|
{{ form_row(form.validFrom) }}
|
||||||
|
|
||||||
|
<ul class="record_actions">
|
||||||
|
<li>
|
||||||
|
<a href="{{ path('chill_person_address_list', { 'person_id' : person.id } ) }}" class="sc-button btn-cancel">
|
||||||
|
{{ 'Back to the list'|trans }}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
{{ form_row(form.submit, { 'attr' : { 'class': 'sc-button bt-create' } } ) }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
{{ form_end(form) }}
|
||||||
|
|
||||||
|
{% endblock personcontent %}
|
@ -18,14 +18,21 @@
|
|||||||
|
|
||||||
{% set activeRouteKey = '' %}
|
{% set activeRouteKey = '' %}
|
||||||
|
|
||||||
{% block title %}ChillPersonBundle:Person:see{% endblock %}
|
{% block title %}{{ 'Update details for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName } )|capitalize }}{% endblock %}
|
||||||
|
|
||||||
{% block personcontent %}
|
{% block personcontent %}
|
||||||
|
|
||||||
|
<h1>{{ 'Update details for %name%'|trans({ '%name%': person.firstName|capitalize ~ ' ' ~ person.lastName|capitalize } ) }}</h1>
|
||||||
|
|
||||||
{% form_theme form 'ChillMainBundle:Form:fields.html.twig' %}
|
{% form_theme form 'ChillMainBundle:Form:fields.html.twig' %}
|
||||||
|
|
||||||
{{ form_start(form) }}
|
{{ form_start(form) }}
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend><h2>{{ 'Memo'|trans }}</h2></legend>
|
||||||
|
{{ form_row(form.memo, {'label' : 'Memo'} ) }}
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><h2>{{ 'General information'|trans }}</h2></legend>
|
<legend><h2>{{ 'General information'|trans }}</h2></legend>
|
||||||
{{ form_row(form.firstName, {'label' : 'First name'}) }}
|
{{ form_row(form.firstName, {'label' : 'First name'}) }}
|
||||||
@ -36,25 +43,41 @@
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><h2>{{ 'Birth information'|trans }}</h2></legend>
|
<legend><h2>{{ 'Birth information'|trans }}</h2></legend>
|
||||||
{{ form_row(form.birthdate, {'label': 'Date of birth'} ) }}
|
{{ form_row(form.birthdate, {'label': 'Date of birth'} ) }}
|
||||||
|
{%- if form.placeOfBirth is defined -%}
|
||||||
{{ form_row(form.placeOfBirth, { 'label' : 'Place of birth'} ) }}
|
{{ form_row(form.placeOfBirth, { 'label' : 'Place of birth'} ) }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if form.countryOfBirth is defined -%}
|
||||||
{{ form_row(form.countryOfBirth, { 'label' : 'Country of birth' } ) }}
|
{{ form_row(form.countryOfBirth, { 'label' : 'Country of birth' } ) }}
|
||||||
|
{%- endif -%}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
|
{%- if form.nationality is defined or form.spokenLanguages is defined or form.maritalStatus is defined -%}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><h2>{{ 'Administrative information'|trans }}</h2></legend>
|
<legend><h2>{{ 'Administrative information'|trans }}</h2></legend>
|
||||||
|
{%- if form.nationality is defined -%}
|
||||||
{{ form_row(form.nationality, { 'label' : 'Nationality'|trans} ) }}
|
{{ form_row(form.nationality, { 'label' : 'Nationality'|trans} ) }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if form.spokenLanguages is defined -%}
|
||||||
{{ form_row(form.spokenLanguages, {'label' : 'Spoken languages'}) }}
|
{{ form_row(form.spokenLanguages, {'label' : 'Spoken languages'}) }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if form.maritalStatus is defined -%}
|
||||||
{{ form_row(form.maritalStatus, { 'label' : 'Marital status'} ) }}
|
{{ form_row(form.maritalStatus, { 'label' : 'Marital status'} ) }}
|
||||||
|
{%- endif -%}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- if form.email is defined or form.phonenumber is defined -%}
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<legend><h2>{{ 'Contact information'|trans }}</h2></legend>
|
<legend><h2>{{ 'Contact information'|trans }}</h2></legend>
|
||||||
|
{%- if form.email is defined -%}
|
||||||
{{ form_row(form.email, {'label': 'Email'}) }}
|
{{ form_row(form.email, {'label': 'Email'}) }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if form.phonenumber is defined -%}
|
||||||
{{ form_row(form.phonenumber, {'label': 'Phonenumber'}) }}
|
{{ form_row(form.phonenumber, {'label': 'Phonenumber'}) }}
|
||||||
|
{%- endif -%}
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
{{ form_row(form.memo, {'label' : 'Memo'} ) }}
|
|
||||||
|
|
||||||
{{ form_rest(form) }}
|
{{ form_rest(form) }}
|
||||||
|
|
||||||
|
1
Resources/views/Person/macro.html.twig
Normal file
1
Resources/views/Person/macro.html.twig
Normal file
@ -0,0 +1 @@
|
|||||||
|
{% macro render(p, withLink=false) %}<span class="entity entity-person person-person"><a href="{{ path('chill_person_view', { 'person_id' : p.id } ) }}">{{ p.firstName }} {{ p.lastName }}</a></span>{% endmacro %}
|
@ -16,6 +16,8 @@
|
|||||||
#}
|
#}
|
||||||
{% extends "ChillPersonBundle::layout.html.twig" %}
|
{% extends "ChillPersonBundle::layout.html.twig" %}
|
||||||
|
|
||||||
|
{% import 'ChillMainBundle:Address:macro.html.twig' as address %}
|
||||||
|
|
||||||
{% set activeRouteKey = 'chill_person_view' %}
|
{% set activeRouteKey = 'chill_person_view' %}
|
||||||
|
|
||||||
{#
|
{#
|
||||||
@ -23,7 +25,8 @@ This view should receive those arguments:
|
|||||||
- person
|
- person
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{% block title %}ChillPersonBundle:Person:see{% endblock %}
|
{% block title %}{{ 'Person details'|trans|capitalize ~ ' ' ~ person.firstName|capitalize ~
|
||||||
|
' ' ~ person.lastName }}{% endblock %}
|
||||||
{#
|
{#
|
||||||
we define variables to include an edit form repeated multiple time across
|
we define variables to include an edit form repeated multiple time across
|
||||||
the page
|
the page
|
||||||
@ -34,8 +37,21 @@ This view should receive those arguments:
|
|||||||
|
|
||||||
|
|
||||||
{% block personcontent %}
|
{% block personcontent %}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="grid-10 push-1 grid-mobile-12 grid-tablet-12 push-mobile-0 push-tablet-0 parent">
|
<div class="grid-10 push-1 grid-mobile-12 grid-tablet-12 push-mobile-0 push-tablet-0 parent">
|
||||||
|
{% if person.memo is not empty %}
|
||||||
|
<div class="grid-12">
|
||||||
|
<figure class="person-details">
|
||||||
|
<h2 class="chill-red">{{ 'Memo'|trans|upper }}</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<blockquote>{{ person.memo|nl2br }}</blockquote>
|
||||||
|
</p>
|
||||||
|
</figure>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="grid-6">
|
<div class="grid-6">
|
||||||
<figure class="person-details">
|
<figure class="person-details">
|
||||||
<h2 class="chill-red">{{ 'General information'|trans|upper }}</h2>
|
<h2 class="chill-red">{{ 'General information'|trans|upper }}</h2>
|
||||||
@ -72,8 +88,12 @@ This view should receive those arguments:
|
|||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
</dd>
|
</dd>
|
||||||
|
|
||||||
|
{%- if chill_person.fields.place_of_birth == 'visible' -%}
|
||||||
<dt>{{ 'Place of birth'|trans }} :</dt>
|
<dt>{{ 'Place of birth'|trans }} :</dt>
|
||||||
<dd>{{ person.placeOfBirth }}</dd>
|
<dd>{{ person.placeOfBirth }}</dd>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.country_of_birth == 'visible' -%}
|
||||||
|
<dt>{{ 'Country of birth'|trans }} :</dt>
|
||||||
<dd>{% spaceless %}
|
<dd>{% spaceless %}
|
||||||
{% if person.countryOfBirth is not null %}
|
{% if person.countryOfBirth is not null %}
|
||||||
{{ person.countryOfBirth.name|localize_translatable_string }}
|
{{ person.countryOfBirth.name|localize_translatable_string }}
|
||||||
@ -81,6 +101,7 @@ This view should receive those arguments:
|
|||||||
{{ 'Unknown country of birth'|trans }}
|
{{ 'Unknown country of birth'|trans }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}</dd>
|
{% endspaceless %}</dd>
|
||||||
|
{%- endif -%}
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||||
@ -91,10 +112,12 @@ This view should receive those arguments:
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid-10 push-1 grid-mobile-12 grid-tablet-12 push-mobile-0 push-tablet-0 parent">
|
<div class="grid-10 push-1 grid-mobile-12 grid-tablet-12 push-mobile-0 push-tablet-0 parent">
|
||||||
|
{%- if chill_person.fields.nationality == 'visible' or chill_person.fields.spoken_languages == 'visible'-%}
|
||||||
<div class="grid-6">
|
<div class="grid-6">
|
||||||
<figure class="person-details">
|
<figure class="person-details">
|
||||||
<h2 class="chill-orange">{{ 'Administrative information'|trans|upper }}</h2>
|
<h2 class="chill-orange">{{ 'Administrative information'|trans|upper }}</h2>
|
||||||
|
|
||||||
|
{%- if chill_person.fields.nationality == 'visible' -%}
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{{ 'Nationality'|trans }} :</dt>
|
<dt>{{ 'Nationality'|trans }} :</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -105,6 +128,8 @@ This view should receive those arguments:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.spoken_languages == 'visible' -%}
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{{'Spoken languages'|trans}} :</dt>
|
<dt>{{'Spoken languages'|trans}} :</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -117,6 +142,8 @@ This view should receive those arguments:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.marital_status == 'visible' -%}
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{{'Marital status'|trans}} :</dt>
|
<dt>{{'Marital status'|trans}} :</dt>
|
||||||
<dd>
|
<dd>
|
||||||
@ -127,24 +154,53 @@ This view should receive those arguments:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||||
{{ include(edit_tmp_name, edit_tmp_args) }}
|
{{ include(edit_tmp_name, edit_tmp_args) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</figure>
|
</figure>
|
||||||
</div>
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.email == 'visible' or chill_person.fields.phonenumber == 'visible' -%}
|
||||||
<div class="grid-6">
|
<div class="grid-6">
|
||||||
<figure class="person-details">
|
<figure class="person-details">
|
||||||
<h2 class="chill-blue"><i class="fa fa-envelope-o"></i> {{ 'Contact information'|trans|upper }}</h2>
|
<h2 class="chill-blue"><i class="fa fa-envelope-o"></i> {{ 'Contact information'|trans|upper }}</h2>
|
||||||
|
|
||||||
|
{%- if chill_person.fields.address == 'visible' -%}
|
||||||
|
<dl>
|
||||||
|
<dt>{{ 'Address'|trans }}</dt>
|
||||||
|
<dd>
|
||||||
|
{%- if person.lastAddress is not empty -%}
|
||||||
|
{{ address._render(person.lastAddress) }}
|
||||||
|
<a href="{{ path('chill_person_address_edit', { 'person_id': person.id, 'address_id' : person.lastAddress.id } ) }}">
|
||||||
|
{{ 'Edit'|trans }}
|
||||||
|
</a><br/>
|
||||||
|
<a href="{{ path('chill_person_address_list', { 'person_id': person.id } ) }}">
|
||||||
|
{{ 'Addresses\'history'|trans }}
|
||||||
|
</a>
|
||||||
|
{%- else -%}
|
||||||
|
<span class="chill-no-data-statement">{{ 'No address given'|trans }}</span>
|
||||||
|
<a href="{{ path('chill_person_address_new', { 'person_id' : person.id } ) }}" class="">
|
||||||
|
{{ 'Add an address'|trans }}
|
||||||
|
</a>
|
||||||
|
{%- endif -%}
|
||||||
|
</dd>
|
||||||
|
</dl>
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- if chill_person.fields.email == 'visible' -%}
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{{ 'Email'|trans }} :</dt>
|
<dt>{{ 'Email'|trans }} :</dt>
|
||||||
<dd><pre>{{ person.email}} </pre></dd>
|
<dd><pre>{{ person.email}} </pre></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.phonenumber == 'visible' -%}
|
||||||
<dl>
|
<dl>
|
||||||
<dt>{{ 'Phonenumber'|trans }} :</dt>
|
<dt>{{ 'Phonenumber'|trans }} :</dt>
|
||||||
<dd><pre>{{ person.phonenumber}} </pre></dd>
|
<dd><pre>{{ person.phonenumber}} </pre></dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
{% if is_granted('CHILL_PERSON_UPDATE', person) %}
|
||||||
@ -152,6 +208,7 @@ This view should receive those arguments:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</figure>
|
</figure>
|
||||||
</div>
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% if cFGroup and (cFGroup.getActiveCustomFields|length > 0) %}
|
{% if cFGroup and (cFGroup.getActiveCustomFields|length > 0) %}
|
||||||
|
@ -70,6 +70,7 @@
|
|||||||
{{ person.birthdate|localizeddate('long', 'none') }}
|
{{ person.birthdate|localizeddate('long', 'none') }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{%- if chill_person.fields.nationality == 'visible' -%}
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<span class="open_sansbold">{{ 'Nationality'|trans|upper}} :</span>
|
<span class="open_sansbold">{{ 'Nationality'|trans|upper}} :</span>
|
||||||
{% if person.nationality is not null %}
|
{% if person.nationality is not null %}
|
||||||
@ -78,6 +79,8 @@
|
|||||||
{% trans %}Without nationality{% endtrans %}
|
{% trans %}Without nationality{% endtrans %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if chill_person.fields.spoken_languages == 'visible' -%}
|
||||||
<div class="grid-3">
|
<div class="grid-3">
|
||||||
<span class="open_sansbold">{{ 'Spoken languages'|trans|upper}} :</span>
|
<span class="open_sansbold">{{ 'Spoken languages'|trans|upper}} :</span>
|
||||||
{% if person.spokenLanguages|length == 0 %}
|
{% if person.spokenLanguages|length == 0 %}
|
||||||
@ -87,7 +90,8 @@
|
|||||||
{{ lang.name|localize_translatable_string }}{% if not loop.last %},{% endif %}
|
{{ lang.name|localize_translatable_string }}{% if not loop.last %},{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{%- endif -%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@ -104,4 +108,8 @@
|
|||||||
'args' : {'person_id': person.id },
|
'args' : {'person_id': person.id },
|
||||||
'activeRouteKey': activeRouteKey
|
'activeRouteKey': activeRouteKey
|
||||||
}) }}
|
}) }}
|
||||||
|
|
||||||
|
<div class="block-post-menu">
|
||||||
|
{{ chill_delegated_block('person_post_vertical_menu', { 'person': person } ) }}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
189
Tests/Controller/PersonAddressControllerTest.php
Normal file
189
Tests/Controller/PersonAddressControllerTest.php
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Champs-Libres <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\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PersonAddressControllerTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
|
||||||
|
protected $em;
|
||||||
|
|
||||||
|
/** @var Person The person on which the test is executed */
|
||||||
|
protected static $person;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Chill\MainBundle\Entity\PostalCode
|
||||||
|
*/
|
||||||
|
protected $postalCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\BrowserKit\Client
|
||||||
|
*/
|
||||||
|
protected $client;
|
||||||
|
|
||||||
|
public static function setUpBeforeClass()
|
||||||
|
{
|
||||||
|
static::bootKernel();
|
||||||
|
|
||||||
|
$em = static::$kernel->getContainer()
|
||||||
|
->get('doctrine.orm.entity_manager');
|
||||||
|
|
||||||
|
$center = $em->getRepository('ChillMainBundle:Center')
|
||||||
|
->findOneBy(array('name' => 'Center A'));
|
||||||
|
|
||||||
|
self::$person = (new Person())
|
||||||
|
->setLastName("Tested person")
|
||||||
|
->setFirstName("Test")
|
||||||
|
->setCenter($center)
|
||||||
|
->setGender(Person::MALE_GENDER);
|
||||||
|
|
||||||
|
$em->persist(self::$person);
|
||||||
|
$em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare client and create a random person
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
static::bootKernel();
|
||||||
|
|
||||||
|
$this->em = static::$kernel->getContainer()
|
||||||
|
->get('doctrine.orm.entity_manager');
|
||||||
|
|
||||||
|
$this->postalCode = $this->em->getRepository('ChillMainBundle:PostalCode')
|
||||||
|
->findOneBy(array('code' => 1000));
|
||||||
|
|
||||||
|
$this->client = static::createClient(array(), array(
|
||||||
|
'PHP_AUTH_USER' => 'center a_social',
|
||||||
|
'PHP_AUTH_PW' => 'password',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function tearDownAfter()
|
||||||
|
{
|
||||||
|
$this->refreshPerson();
|
||||||
|
$this->em->remove(self::$person);
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload the person from the db
|
||||||
|
*/
|
||||||
|
protected function refreshPerson()
|
||||||
|
{
|
||||||
|
self::$person = $this->em->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find(self::$person->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEmptyList()
|
||||||
|
{
|
||||||
|
$crawler = $this->client->request('GET', '/fr/person/'.
|
||||||
|
self::$person->getId().'/address/list');
|
||||||
|
|
||||||
|
$this->assertTrue($this->client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$this->assertEquals(1, $crawler->filter('td:contains("Pas d\'adresse renseignée")')
|
||||||
|
->count(),
|
||||||
|
"assert that a message say 'no address given'");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testEmptyList
|
||||||
|
*/
|
||||||
|
public function testCreateAddress()
|
||||||
|
{
|
||||||
|
$crawler = $this->client->request('GET', '/fr/person/'.
|
||||||
|
self::$person->getId().'/address/new');
|
||||||
|
|
||||||
|
$this->assertTrue($this->client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$form = $crawler->selectButton('Envoi')->form(array(
|
||||||
|
'address[streetAddress1]' => 'Rue de la Paix, 50',
|
||||||
|
'address[streetAddress2]' => $this->postalCode->getId(),
|
||||||
|
'address[validFrom]' => '15-01-2016'
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->client->submit($form);
|
||||||
|
|
||||||
|
$crawler = $this->client->followRedirect();
|
||||||
|
|
||||||
|
$this->assertRegexp('|/fr/person/[0-9]{1,}/address/list|',
|
||||||
|
$this->client->getHistory()->current()->getUri(),
|
||||||
|
"assert that the current page is on |/fr/person/[0-9]{1,}/address/list|");
|
||||||
|
$this->assertEquals(1, $crawler
|
||||||
|
->filter('div.flash_message.success')
|
||||||
|
->count(),
|
||||||
|
"Asserting that the response page contains a success flash message");
|
||||||
|
$this->assertEquals(1, $crawler
|
||||||
|
->filter('td:contains("Rue de la Paix, 50")')
|
||||||
|
->count(),
|
||||||
|
"Asserting that the page contains the new address");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testCreateAddress
|
||||||
|
*/
|
||||||
|
public function testUpdateAddress()
|
||||||
|
{
|
||||||
|
$this->refreshPerson();
|
||||||
|
$address = self::$person->getLastAddress();
|
||||||
|
|
||||||
|
$crawler = $this->client->request('GET', '/fr/person/'.self::$person->getId()
|
||||||
|
.'/address/'.$address->getId().'/edit');
|
||||||
|
|
||||||
|
$this->assertTrue($this->client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$form = $crawler->selectButton('Envoi')->form(array(
|
||||||
|
'address[streetAddress1]' => 'Rue du Trou Normand, 15',
|
||||||
|
'address[validFrom]' => '15-01-2015'
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->client->submit($form);
|
||||||
|
|
||||||
|
$crawler = $this->client->followRedirect();
|
||||||
|
|
||||||
|
$this->assertRegexp('|/fr/person/[0-9]{1,}/address/list|',
|
||||||
|
$this->client->getHistory()->current()->getUri(),
|
||||||
|
"assert that the current page is on |/fr/person/[0-9]{1,}/address/list|");
|
||||||
|
$this->assertGreaterThan(0, $crawler
|
||||||
|
->filter('div.flash_message.success')
|
||||||
|
->count(),
|
||||||
|
"Asserting that the response page contains a success flash message");
|
||||||
|
$this->assertEquals(1, $crawler
|
||||||
|
->filter('td:contains("Rue du Trou Normand")')
|
||||||
|
->count(),
|
||||||
|
"Asserting that the page contains the new address");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -240,6 +240,31 @@ class PersonControllerCreateTest extends WebTestCase
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testReviewExistingDetectionInversedLastNameWithFirstName()
|
||||||
|
{
|
||||||
|
$client = $this->getAuthenticatedClient();
|
||||||
|
|
||||||
|
$crawler = $client->request('GET', '/fr/person/new');
|
||||||
|
|
||||||
|
//test the page is loaded before continuing
|
||||||
|
$this->assertTrue($client->getResponse()->isSuccessful());
|
||||||
|
|
||||||
|
$form = $crawler->selectButton("Ajouter la personne")->form();
|
||||||
|
$form = $this->fillAValidCreationForm($form, 'Charline', 'dd');
|
||||||
|
$client->submit($form);
|
||||||
|
|
||||||
|
$this->assertContains('Depardieu', $client->getCrawler()->text(),
|
||||||
|
"check that the page has detected the lastname of a person existing in database");
|
||||||
|
|
||||||
|
//inversion
|
||||||
|
$form = $crawler->selectButton("Ajouter la personne")->form();
|
||||||
|
$form = $this->fillAValidCreationForm($form, 'dd', 'Charline');
|
||||||
|
$client->submit($form);
|
||||||
|
|
||||||
|
$this->assertContains('Depardieu', $client->getCrawler()->text(),
|
||||||
|
"check that the page has detected the lastname of a person existing in database");
|
||||||
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass()
|
public static function tearDownAfterClass()
|
||||||
{
|
{
|
||||||
static::bootKernel();
|
static::bootKernel();
|
||||||
|
@ -96,6 +96,24 @@ class PersonControllerUpdateTest extends WebTestCase
|
|||||||
"The person edit form is accessible");
|
"The person edit form is accessible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the configurable fields are present
|
||||||
|
*
|
||||||
|
* @group configurable_fields
|
||||||
|
*/
|
||||||
|
public function testHiddenFielsArePresent()
|
||||||
|
{
|
||||||
|
$crawler = $this->client->request('GET', $this->editUrl);
|
||||||
|
|
||||||
|
$configurables = array('placeOfBirth', 'phonenumber', 'email',
|
||||||
|
'countryOfBirth', 'nationality', 'spokenLanguages', 'maritalStatus');
|
||||||
|
$form = $crawler->selectButton('Submit')->form(); //;
|
||||||
|
|
||||||
|
foreach($configurables as $key) {
|
||||||
|
$this->assertTrue($form->has('chill_personbundle_person['.$key.']'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the edit page of a given person is not accessible for a user
|
* Test if the edit page of a given person is not accessible for a user
|
||||||
* of another center of the person
|
* of another center of the person
|
||||||
|
211
Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php
Normal file
211
Tests/Controller/PersonControllerUpdateWithHiddenFieldsTest.php
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a suite of a modules, Chill is a software for social workers
|
||||||
|
* Copyright (C) 2014, 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
|
//ini_set('memory_limit', '-1');
|
||||||
|
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the edition of persons
|
||||||
|
*
|
||||||
|
* As I am logged in as "center a_social"
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PersonControllerUpdateWithHiddenFieldsTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
|
||||||
|
private $em;
|
||||||
|
|
||||||
|
/** @var Person The person on which the test is executed */
|
||||||
|
private $person;
|
||||||
|
|
||||||
|
/** @var string The url using for editing the person's information */
|
||||||
|
private $editUrl;
|
||||||
|
|
||||||
|
/** @var string The url using for seeing the person's information */
|
||||||
|
private $viewUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare client and create a random person
|
||||||
|
*/
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
static::bootKernel(array('environment' => 'test_with_hidden_fields'));
|
||||||
|
|
||||||
|
$this->em = static::$kernel->getContainer()
|
||||||
|
->get('doctrine.orm.entity_manager');
|
||||||
|
|
||||||
|
$center = $this->em->getRepository('ChillMainBundle:Center')
|
||||||
|
->findOneBy(array('name' => 'Center A'));
|
||||||
|
|
||||||
|
$this->person = (new Person())
|
||||||
|
->setLastName("My Beloved")
|
||||||
|
->setFirstName("Jesus")
|
||||||
|
->setCenter($center)
|
||||||
|
->setGender(Person::MALE_GENDER);
|
||||||
|
|
||||||
|
$this->em->persist($this->person);
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
$this->editUrl = '/en/person/'.$this->person->getId().'/general/edit';
|
||||||
|
$this->viewUrl = '/en/person/'.$this->person->getId().'/general';
|
||||||
|
|
||||||
|
$this->client = static::createClient(
|
||||||
|
array(
|
||||||
|
'environment' => 'test_with_hidden_fields'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'PHP_AUTH_USER' => 'center a_social',
|
||||||
|
'PHP_AUTH_PW' => 'password',
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload the person from the db
|
||||||
|
*/
|
||||||
|
protected function refreshPerson()
|
||||||
|
{
|
||||||
|
$this->person = $this->em->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($this->person->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the edit page are accessible
|
||||||
|
*/
|
||||||
|
public function testEditPageIsSuccessful()
|
||||||
|
{
|
||||||
|
$this->client->request('GET', $this->editUrl);
|
||||||
|
$this->assertTrue($this->client->getResponse()->isSuccessful(),
|
||||||
|
"The person edit form is accessible");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the configurable fields are absent
|
||||||
|
*
|
||||||
|
* @group configurable_fields
|
||||||
|
*/
|
||||||
|
public function testHiddenFielsAreAbsent()
|
||||||
|
{
|
||||||
|
$crawler = $this->client->request('GET', $this->editUrl);
|
||||||
|
|
||||||
|
$configurables = array('placeOfBirth', 'phonenumber', 'email',
|
||||||
|
'countryOfBirth', 'nationality', 'spokenLanguages', 'maritalStatus');
|
||||||
|
$form = $crawler->selectButton('Submit')->form(); //;
|
||||||
|
|
||||||
|
foreach($configurables as $key) {
|
||||||
|
$this->assertFalse($form->has('chill_personbundle_person['.$key.']'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the edition of a field
|
||||||
|
*
|
||||||
|
* Given I fill the field with $value
|
||||||
|
* And I submit the form
|
||||||
|
* Then I am redirected to the 'general' page
|
||||||
|
* And the person is updated in the db
|
||||||
|
*
|
||||||
|
* @dataProvider validTextFieldsProvider
|
||||||
|
* @param string $field
|
||||||
|
* @param string $value
|
||||||
|
* @param \Closure $callback
|
||||||
|
*/
|
||||||
|
public function testEditTextField($field, $value, \Closure $callback)
|
||||||
|
{
|
||||||
|
$crawler = $this->client->request('GET', $this->editUrl);
|
||||||
|
|
||||||
|
$form = $crawler->selectButton('Submit')
|
||||||
|
->form();
|
||||||
|
//transform countries into value if needed
|
||||||
|
switch ($field) {
|
||||||
|
case 'nationality':
|
||||||
|
case 'countryOfBirth':
|
||||||
|
if ($value !== NULL) {
|
||||||
|
$country = $this->em->getRepository('ChillMainBundle:Country')
|
||||||
|
->findOneByCountryCode($value);
|
||||||
|
$transformedValue = $country->getId();
|
||||||
|
} else {
|
||||||
|
$transformedValue = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$transformedValue = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->get('chill_personbundle_person['.$field. ']')
|
||||||
|
->setValue($transformedValue);
|
||||||
|
|
||||||
|
$this->client->submit($form);
|
||||||
|
$this->refreshPerson();
|
||||||
|
|
||||||
|
$this->assertTrue($this->client->getResponse()->isRedirect($this->viewUrl),
|
||||||
|
'the page is redirected to general view');
|
||||||
|
$this->assertEquals($value, $callback($this->person),
|
||||||
|
'the value '.$field.' is updated in db');
|
||||||
|
|
||||||
|
$crawler = $this->client->followRedirect();
|
||||||
|
$this->assertGreaterThan(0, $crawler->filter('.success')->count(),
|
||||||
|
'a element .success is shown');
|
||||||
|
|
||||||
|
if($field == 'birthdate' or $field == 'memo' or $field == 'countryOfBirth' or $field == 'nationality'
|
||||||
|
or $field == 'gender') {
|
||||||
|
// we do not perform test on the web page contents.
|
||||||
|
} else {
|
||||||
|
$this->assertGreaterThan(0, $crawler->filter('html:contains("'.$value.'")')->count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provide valid values to test, with field name and
|
||||||
|
* a function to find the value back from person entity
|
||||||
|
*
|
||||||
|
* @return mixed[]
|
||||||
|
*/
|
||||||
|
public function validTextFieldsProvider()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
['firstName', 'random Value', function(Person $person) { return $person->getFirstName(); } ],
|
||||||
|
['lastName' , 'random Value', function(Person $person) { return $person->getLastName(); } ],
|
||||||
|
['birthdate', '15-12-1980', function(Person $person) { return $person->getBirthdate()->format('d-m-Y'); }],
|
||||||
|
['memo', 'jfkdlmq jkfldmsq jkmfdsq', function(Person $person) { return $person->getMemo(); }],
|
||||||
|
['birthdate', '', function(Person $person) { return $person->getBirthdate(); }],
|
||||||
|
['gender', Person::FEMALE_GENDER, function(Person $person) { return $person->getGender(); }],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
$this->refreshPerson();
|
||||||
|
$this->em->remove($this->person);
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getVeryLongText()
|
||||||
|
{
|
||||||
|
return <<<EOT
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse molestie at enim id auctor. Vivamus malesuada elit ipsum, ac mollis ex facilisis sit amet. Phasellus accumsan, quam ut aliquet accumsan, augue ligula consequat erat, condimentum iaculis orci magna egestas eros. In vel blandit sapien. Duis ut dui vitae tortor iaculis malesuada vitae vitae lorem. Morbi efficitur dolor orci, a rhoncus urna blandit quis. Aenean at placerat dui, ut tincidunt nulla. In ultricies tempus ligula ac rutrum. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce urna nibh, placerat vel auctor sed, maximus quis magna. Vivamus quam ante, consectetur vel feugiat quis, aliquet id ante. Integer gravida erat dignissim ante commodo mollis. Donec imperdiet mauris elit, nec blandit dolor feugiat ut. Proin iaculis enim ut tortor pretium commodo. Etiam aliquet hendrerit dolor sed fringilla. Vestibulum facilisis nibh tincidunt dui egestas, vitae congue mi imperdiet. Duis vulputate ultricies lectus id cursus. Fusce bibendum sem dignissim, bibendum purus quis, mollis ex. Cras ac est justo. Duis congue mattis ipsum, vitae sagittis justo dictum sit amet. Duis aliquam pharetra sem, non laoreet ante laoreet ac. Mauris ornare mi tempus rutrum consequat.
|
||||||
|
EOT;
|
||||||
|
}
|
||||||
|
}
|
@ -61,6 +61,8 @@ class PersonControllerViewTest extends WebTestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if the view page is accessible
|
* Test if the view page is accessible
|
||||||
|
*
|
||||||
|
* @group configurable_fields
|
||||||
*/
|
*/
|
||||||
public function testViewPerson()
|
public function testViewPerson()
|
||||||
{
|
{
|
||||||
@ -76,6 +78,10 @@ class PersonControllerViewTest extends WebTestCase
|
|||||||
|
|
||||||
$this->assertGreaterThan(0, $crawler->filter('html:contains("Tested Person")')->count());
|
$this->assertGreaterThan(0, $crawler->filter('html:contains("Tested Person")')->count());
|
||||||
$this->assertGreaterThan(0, $crawler->filter('html:contains("Réginald")')->count());
|
$this->assertGreaterThan(0, $crawler->filter('html:contains("Réginald")')->count());
|
||||||
|
$this->assertContains('Email addresses', $crawler->text());
|
||||||
|
$this->assertContains('Phonenumber', $crawler->text());
|
||||||
|
$this->assertContains('Langues parlées', $crawler->text());
|
||||||
|
$this->assertContains(/* Etat */ 'civil', $crawler->text());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
107
Tests/Controller/PersonControllerViewWithHiddenFieldsTest.php
Normal file
107
Tests/Controller/PersonControllerViewWithHiddenFieldsTest.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Julien Fastré <julien.fastre@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\PersonBundle\Tests\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use Chill\PersonBundle\Entity\Person;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
* @author Marc Ducobu <marc.ducobu@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PersonControllerViewTestWithHiddenFields extends WebTestCase
|
||||||
|
{
|
||||||
|
/** @var \Doctrine\ORM\EntityManagerInterface The entity manager */
|
||||||
|
private $em;
|
||||||
|
|
||||||
|
/** @var Person A person used on which to run the test */
|
||||||
|
private $person;
|
||||||
|
|
||||||
|
/** @var String The url to view the person details */
|
||||||
|
private $viewUrl;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
static::bootKernel(array('environment' => 'test_with_hidden_fields'));
|
||||||
|
|
||||||
|
$this->em = static::$kernel->getContainer()
|
||||||
|
->get('doctrine.orm.entity_manager');
|
||||||
|
|
||||||
|
$center = $this->em->getRepository('ChillMainBundle:Center')
|
||||||
|
->findOneBy(array('name' => 'Center A'));
|
||||||
|
|
||||||
|
$this->person = (new Person())
|
||||||
|
->setLastName("Tested Person")
|
||||||
|
->setFirstName("Réginald")
|
||||||
|
->setCenter($center)
|
||||||
|
->setGender(Person::MALE_GENDER);
|
||||||
|
|
||||||
|
$this->em->persist($this->person);
|
||||||
|
$this->em->flush();
|
||||||
|
|
||||||
|
$this->viewUrl = '/en/person/'.$this->person->getId().'/general';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if the view page is accessible
|
||||||
|
*
|
||||||
|
* @group configurable_fields
|
||||||
|
*/
|
||||||
|
public function testViewPerson()
|
||||||
|
{
|
||||||
|
$client = static::createClient(
|
||||||
|
array('environment' => 'test_with_hidden_fields'),
|
||||||
|
array(
|
||||||
|
'PHP_AUTH_USER' => 'center a_social',
|
||||||
|
'PHP_AUTH_PW' => 'password',
|
||||||
|
'HTTP_ACCEPT_LANGUAGE' => 'fr'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$crawler = $client->request('GET', $this->viewUrl);
|
||||||
|
$response = $client->getResponse();
|
||||||
|
|
||||||
|
$this->assertTrue($response->isSuccessful());
|
||||||
|
|
||||||
|
$this->assertGreaterThan(0, $crawler->filter('html:contains("Tested Person")')->count());
|
||||||
|
$this->assertGreaterThan(0, $crawler->filter('html:contains("Réginald")')->count());
|
||||||
|
$this->assertNotContains('Email addresses', $crawler->text());
|
||||||
|
$this->assertNotContains('Phonenumber', $crawler->text());
|
||||||
|
$this->assertNotContains('Langues parlées', $crawler->text());
|
||||||
|
$this->assertNotContains(/* Etat */ 'civil', $crawler->text());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reload the person from the db
|
||||||
|
*/
|
||||||
|
protected function refreshPerson()
|
||||||
|
{
|
||||||
|
$this->person = $this->em->getRepository('ChillPersonBundle:Person')
|
||||||
|
->find($this->person->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function tearDown()
|
||||||
|
{
|
||||||
|
$this->refreshPerson();
|
||||||
|
$this->em->remove($this->person);
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
# config/config_test.yml
|
||||||
|
imports:
|
||||||
|
- { resource: config.yml } #here we import a config.yml file, this is not required
|
||||||
|
|
||||||
|
framework:
|
||||||
|
test: ~
|
||||||
|
session:
|
||||||
|
storage_id: session.storage.filesystem
|
||||||
|
|
||||||
|
chill_person:
|
||||||
|
person_fields:
|
||||||
|
nationality: hidden
|
||||||
|
email: hidden
|
||||||
|
place_of_birth: hidden
|
||||||
|
phonenumber: hidden
|
||||||
|
country_of_birth: hidden
|
||||||
|
marital_status: hidden
|
||||||
|
spoken_languages: hidden
|
181
Tests/Form/Type/PickPersonTypeTest.php
Normal file
181
Tests/Form/Type/PickPersonTypeTest.php
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2016 Champs-Libres <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\PersonBundle\Tests\Form\Type;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||||
|
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||||
|
use Chill\PersonBundle\Form\Type\PickPersonType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Julien Fastré <julien.fastre@champs-libres.coop>
|
||||||
|
*/
|
||||||
|
class PickPersonTypeTest extends KernelTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Chill\MainBundle\Entity\User
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
||||||
|
*/
|
||||||
|
protected $container;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\Form\FormFactoryInterface
|
||||||
|
*/
|
||||||
|
protected $formFactory;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
self::bootKernel();
|
||||||
|
|
||||||
|
$this->container = self::$kernel->getContainer();
|
||||||
|
|
||||||
|
$this->user = $this->container->get('doctrine.orm.entity_manager')
|
||||||
|
->getRepository('ChillMainBundle:User')
|
||||||
|
->findOneBy(array('username' => 'multi_center'));
|
||||||
|
|
||||||
|
$this->formFactory = $this->container->get('form.factory');
|
||||||
|
|
||||||
|
$token = (new UsernamePasswordToken($this->user, 'password', 'firewall'));
|
||||||
|
$this->container->get('security.token_storage')
|
||||||
|
->setToken($token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithoutOption()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory
|
||||||
|
->createBuilder(PickPersonType::class, null, array())
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
$this->assertInstanceOf(\Symfony\Component\Form\FormInterface::class,
|
||||||
|
$form);
|
||||||
|
|
||||||
|
// transform into a view to have data-center attr
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$centerIds = array();
|
||||||
|
|
||||||
|
/* @var $centerIds \Symfony\Component\Form\ChoiceList\View\ChoiceView */
|
||||||
|
foreach($view->vars['choices'] as $choice) {
|
||||||
|
$centerIds[] = $choice->attr['data-center'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals(2, count(array_unique($centerIds)),
|
||||||
|
"test that the form contains people from 2 centers");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the form with an option 'centers' with an unique center
|
||||||
|
* entity (not in an array)
|
||||||
|
*/
|
||||||
|
public function testWithOptionCenter()
|
||||||
|
{
|
||||||
|
$center = $this->container->get('doctrine.orm.entity_manager')
|
||||||
|
->getRepository('ChillMainBundle:Center')
|
||||||
|
->findOneBy(array('name' => 'Center A'))
|
||||||
|
;
|
||||||
|
|
||||||
|
$form = $this->formFactory
|
||||||
|
->createBuilder(PickPersonType::class, null, array(
|
||||||
|
'centers' => $center
|
||||||
|
))
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
// transform into a view to have data-center attr
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
/* @var $centerIds \Symfony\Component\Form\ChoiceList\View\ChoiceView */
|
||||||
|
foreach($view->vars['choices'] as $choice) {
|
||||||
|
$centerIds[] = $choice->attr['data-center'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals(1, count(array_unique($centerIds)),
|
||||||
|
"test that the form contains people from only one centers");
|
||||||
|
|
||||||
|
$this->assertEquals($center->getId(), array_unique($centerIds)[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the form with multiple centers
|
||||||
|
*/
|
||||||
|
public function testWithOptionCenters()
|
||||||
|
{
|
||||||
|
$centers = $this->container->get('doctrine.orm.entity_manager')
|
||||||
|
->getRepository('ChillMainBundle:Center')
|
||||||
|
->findAll()
|
||||||
|
;
|
||||||
|
|
||||||
|
$form = $this->formFactory
|
||||||
|
->createBuilder(PickPersonType::class, null, array(
|
||||||
|
'centers' => $centers
|
||||||
|
))
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
// transform into a view to have data-center attr
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
/* @var $centerIds \Symfony\Component\Form\ChoiceList\View\ChoiceView */
|
||||||
|
foreach($view->vars['choices'] as $choice) {
|
||||||
|
$centerIds[] = $choice->attr['data-center'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertEquals(2, count(array_unique($centerIds)),
|
||||||
|
"test that the form contains people from only one centers");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test with an invalid center type in the option 'centers' (in an array)
|
||||||
|
*
|
||||||
|
* @expectedException \RuntimeException
|
||||||
|
*/
|
||||||
|
public function testWithInvalidOptionCenters()
|
||||||
|
{
|
||||||
|
|
||||||
|
$form = $this->formFactory
|
||||||
|
->createBuilder(PickPersonType::class, null, array(
|
||||||
|
'centers' => array('string')
|
||||||
|
))
|
||||||
|
->getForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testWithOptionRoleInvalid()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory
|
||||||
|
->createBuilder(PickPersonType::class, null, array(
|
||||||
|
'role' => new \Symfony\Component\Security\Core\Role\Role('INVALID')
|
||||||
|
))
|
||||||
|
->getForm();
|
||||||
|
|
||||||
|
// transform into a view to have data-center attr
|
||||||
|
$view = $form->createView();
|
||||||
|
|
||||||
|
$this->assertEquals(0, count($view->vars['choices']));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,13 +16,12 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": "~5.5",
|
"php": "~5.6|~7",
|
||||||
"twig/extensions": "~1.0",
|
"twig/extensions": "~1.0",
|
||||||
"symfony/assetic-bundle": "~2.3",
|
"symfony/assetic-bundle": "~2.3",
|
||||||
"symfony/monolog-bundle": "^2.7",
|
"symfony/monolog-bundle": "^2.7",
|
||||||
"symfony/framework-bundle": "~2.7",
|
|
||||||
"symfony/yaml": "~2.7",
|
"symfony/yaml": "~2.7",
|
||||||
"symfony/symfony": "~2.7",
|
"symfony/symfony": "~2.8",
|
||||||
"doctrine/dbal": "~2.5",
|
"doctrine/dbal": "~2.5",
|
||||||
"doctrine/orm": "~2.4",
|
"doctrine/orm": "~2.4",
|
||||||
"doctrine/common": "~2.4",
|
"doctrine/common": "~2.4",
|
||||||
@ -31,12 +30,10 @@
|
|||||||
"chill-project/custom-fields": "dev-master@dev",
|
"chill-project/custom-fields": "dev-master@dev",
|
||||||
"doctrine/doctrine-fixtures-bundle": "~2.2",
|
"doctrine/doctrine-fixtures-bundle": "~2.2",
|
||||||
"champs-libres/composer-bundle-migration": "~1.0",
|
"champs-libres/composer-bundle-migration": "~1.0",
|
||||||
"doctrine/doctrine-migrations-bundle": "dev-master@dev",
|
"doctrine/doctrine-migrations-bundle": "~1.1",
|
||||||
"doctrine/migrations": "~1.0@dev"
|
"doctrine/migrations": "~1.0@dev"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"symfony/dom-crawler": "2.5",
|
|
||||||
"symfony/security": "~2.5",
|
|
||||||
"symfony/phpunit-bridge": "^2.7",
|
"symfony/phpunit-bridge": "^2.7",
|
||||||
"fzaninotto/faker": "~1"
|
"fzaninotto/faker": "~1"
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user