mirror of
				https://gitlab.com/Chill-Projet/chill-bundles.git
				synced 2025-11-04 03:08:25 +00:00 
			
		
		
		
	Merge branch 'master' into privacyEvent
This commit is contained in:
		
							
								
								
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
 | 
			
		||||
Master branch
 | 
			
		||||
=============
 | 
			
		||||
 | 
			
		||||
- Improve import of person to allow multiple centers by file ;
 | 
			
		||||
- Launch an event on person import ;
 | 
			
		||||
- Allow person to have a `null` gender ;
 | 
			
		||||
- Allow filters and aggregator to handle null gender ;
 | 
			
		||||
- remove inexistant `person.css` file
 | 
			
		||||
 | 
			
		||||
@@ -29,6 +29,13 @@ use Symfony\Component\Filesystem\Filesystem;
 | 
			
		||||
use Symfony\Component\Console\Question\ChoiceQuestion;
 | 
			
		||||
use Symfony\Component\Console\Helper\Table;
 | 
			
		||||
use Chill\PersonBundle\Entity\Person;
 | 
			
		||||
use Chill\MainBundle\Entity\Address;
 | 
			
		||||
use Chill\MainBundle\Entity\PostalCode;
 | 
			
		||||
use Chill\MainBundle\Entity\Center;
 | 
			
		||||
use Chill\CustomFieldsBundle\Service\CustomFieldProvider;
 | 
			
		||||
use Symfony\Component\Console\Question\ConfirmationQuestion;
 | 
			
		||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 | 
			
		||||
use Symfony\Component\EventDispatcher\Event;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 
 | 
			
		||||
@@ -67,6 +74,12 @@ class ImportPeopleFromCSVCommand extends ContainerAwareCommand
 | 
			
		||||
     */
 | 
			
		||||
    protected $em;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @var EventDispatcherInterface
 | 
			
		||||
     */
 | 
			
		||||
    protected $eventDispatcher;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * the line currently read
 | 
			
		||||
     *
 | 
			
		||||
@@ -80,6 +93,12 @@ class ImportPeopleFromCSVCommand extends ContainerAwareCommand
 | 
			
		||||
     */
 | 
			
		||||
    protected $customFieldMapping = array();
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     *
 | 
			
		||||
     * @var CustomFieldProvider
 | 
			
		||||
     */
 | 
			
		||||
    protected $customFieldProvider;
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Contains an array of information searched in the file.
 | 
			
		||||
     * 
 | 
			
		||||
@@ -96,7 +115,11 @@ class ImportPeopleFromCSVCommand extends ContainerAwareCommand
 | 
			
		||||
        ['opening_date',    'The column header for opening date', 'opening_date'],
 | 
			
		||||
        ['closing_date',    'The column header for closing date', 'closing_date'],
 | 
			
		||||
        ['memo',            'The column header for memo',           'memo'],
 | 
			
		||||
        ['phonenumber',     'The column header for phonenumber',   'phonenumber']
 | 
			
		||||
        ['phonenumber',     'The column header for phonenumber',   'phonenumber'],
 | 
			
		||||
        ['street1',         'The column header for street 1',      'street1'],
 | 
			
		||||
        ['postalcode',      'The column header for postal code',   'postalcode'],
 | 
			
		||||
        ['locality',        'The column header for locality',      'locality'],
 | 
			
		||||
        ['center',          'The column header for center',        'center']
 | 
			
		||||
    );
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
@@ -106,11 +129,26 @@ class ImportPeopleFromCSVCommand extends ContainerAwareCommand
 | 
			
		||||
     */
 | 
			
		||||
    protected static $defaultDateInterpreter = "%d/%m/%Y|%e/%m/%y|%d/%m/%Y|%e/%m/%Y";
 | 
			
		||||
                                                
 | 
			
		||||
    
 | 
			
		||||
    public function __construct(
 | 
			
		||||
        \Psr\Log\LoggerInterface $logger, 
 | 
			
		||||
        \Chill\MainBundle\Templating\TranslatableStringHelper $helper, 
 | 
			
		||||
        \Doctrine\ORM\EntityManagerInterface $em,
 | 
			
		||||
        CustomFieldProvider $customFieldProvider,
 | 
			
		||||
        EventDispatcherInterface $eventDispatcher
 | 
			
		||||
    ) {
 | 
			
		||||
        $this->logger = $logger;
 | 
			
		||||
        $this->helper = $helper;
 | 
			
		||||
        $this->em = $em;
 | 
			
		||||
        $this->customFieldProvider = $customFieldProvider;
 | 
			
		||||
        $this->eventDispatcher = $eventDispatcher;
 | 
			
		||||
        
 | 
			
		||||
        parent::__construct('chill:person:import');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    protected function configure()
 | 
			
		||||
    {
 | 
			
		||||
        $this->setName('chill:person:import')
 | 
			
		||||
        $this
 | 
			
		||||
                ->addArgument('csv_file', InputArgument::REQUIRED, "The CSV file to import")
 | 
			
		||||
                ->setDescription("Import people from a csv file")
 | 
			
		||||
                ->setHelp(<<<EOF
 | 
			
		||||
@@ -118,13 +156,21 @@ Import people from a csv file. The first row must contains the header column and
 | 
			
		||||
 | 
			
		||||
Date format: the possible date format may be separatedby an |. The possible format will be tryed from the first to the last. The format should be explained as http://php.net/manual/en/function.strftime.php                     
 | 
			
		||||
                        
 | 
			
		||||
php app/console chill:person:import /tmp/hepc.csv fr_FR.utf8  --firstname="Prénom" --lastname="Nom" --birthdate="D.N." --birthdate_format="%d/%m/%Y" --opening_date_format="%B %Y|%Y" --closing_date="der.contact" --closing_date_format="%Y" --custom-field="3=code" -vvv
 | 
			
		||||
php app/console chill:person:import /tmp/hepc.csv fr_FR.utf8  \
 | 
			
		||||
        --firstname="Prénom" --lastname="Nom" \
 | 
			
		||||
        --birthdate="D.N." --birthdate_format="%d/%m/%Y" \
 | 
			
		||||
        --opening_date_format="%B %Y|%Y" --closing_date="der.contact" \
 | 
			
		||||
        --closing_date_format="%Y" --custom-field="3=code" -vvv
 | 
			
		||||
EOF
 | 
			
		||||
            )
 | 
			
		||||
                ->addArgument('locale', InputArgument::REQUIRED, 
 | 
			
		||||
                        "The locale to use in displaying translatable strings from entities")
 | 
			
		||||
                ->addArgument('center', InputArgument::REQUIRED,
 | 
			
		||||
                        "The id of the center")
 | 
			
		||||
                ->addOption(
 | 
			
		||||
                        'force-center', 
 | 
			
		||||
                        null, 
 | 
			
		||||
                        InputOption::VALUE_REQUIRED,
 | 
			
		||||
                        "The id of the center"
 | 
			
		||||
                        )
 | 
			
		||||
                ->addOption(
 | 
			
		||||
                        'force',
 | 
			
		||||
                        null,
 | 
			
		||||
@@ -161,7 +207,7 @@ EOF
 | 
			
		||||
                ->addOption(
 | 
			
		||||
                        'dump-choice-matching',
 | 
			
		||||
                        null,
 | 
			
		||||
                        InputOption::VALUE_OPTIONAL,
 | 
			
		||||
                        InputOption::VALUE_REQUIRED,
 | 
			
		||||
                        "The path of the file to dump the matching between label in CSV and answers"
 | 
			
		||||
                        )
 | 
			
		||||
                ->addOption(
 | 
			
		||||
@@ -245,9 +291,7 @@ EOF
 | 
			
		||||
        
 | 
			
		||||
        $cfMappingsOptions = $this->input->getOption('custom-field');
 | 
			
		||||
        /* @var $em \Doctrine\Common\Persistence\ObjectManager */
 | 
			
		||||
        $em = $this->getContainer()->get('doctrine.orm.entity_manager');
 | 
			
		||||
        /* @var $this->helper \Chill\MainBundle\Templating\TranslatableStringHelper */
 | 
			
		||||
        $this->helper = $this->getContainer()->get('chill.main.helper.translatable_string');
 | 
			
		||||
        $em = $this->em;
 | 
			
		||||
        
 | 
			
		||||
        foreach($cfMappingsOptions as $cfMappingStringOption) {
 | 
			
		||||
            list($rowNumber, $cfSlug) = preg_split('|=|', $cfMappingStringOption);
 | 
			
		||||
@@ -317,7 +361,7 @@ EOF
 | 
			
		||||
    
 | 
			
		||||
    protected function dumpAnswerMatching()
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->input->hasOption('dump-choice-matching')) {
 | 
			
		||||
        if ($this->input->hasOption('dump-choice-matching') && !empty($this->input->getOption('dump-choice-matching'))) {
 | 
			
		||||
            $this->logger->debug("Dump the matching between answer and choices");
 | 
			
		||||
            $str = json_encode($this->cacheAnswersMapping, JSON_PRETTY_PRINT);
 | 
			
		||||
            
 | 
			
		||||
@@ -330,7 +374,6 @@ EOF
 | 
			
		||||
    
 | 
			
		||||
    protected function execute(InputInterface $input, OutputInterface $output)
 | 
			
		||||
    {
 | 
			
		||||
        $this->logger = new ConsoleLogger($output);
 | 
			
		||||
        $this->input = $input;
 | 
			
		||||
        $this->output = $output;
 | 
			
		||||
        
 | 
			
		||||
@@ -356,13 +399,30 @@ EOF
 | 
			
		||||
                $this->logger->debug("Processing line ".$this->line);
 | 
			
		||||
                if ($line === 1 ) {
 | 
			
		||||
                    $this->logger->debug('Processing line 1, headers');
 | 
			
		||||
 | 
			
		||||
                    $rawHeaders = $row;
 | 
			
		||||
                    $headers = $this->processingHeaders($row);
 | 
			
		||||
                } else {
 | 
			
		||||
                    $person = $this->createPerson($row, $headers);
 | 
			
		||||
                    $this->processingCustomFields($person, $row);
 | 
			
		||||
                    
 | 
			
		||||
                    if ($this->input->getOption('force') === TRUE) {
 | 
			
		||||
                    if (count($this->customFieldMapping) > 0) {
 | 
			
		||||
                        $this->processingCustomFields($person, $row);
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
                    $event = new Event();
 | 
			
		||||
                    $event->person = $person;
 | 
			
		||||
                    $event->rawHeaders = $rawHeaders;
 | 
			
		||||
                    $event->row = $row;
 | 
			
		||||
                    $event->headers = $headers;
 | 
			
		||||
                    $event->skipPerson = false;
 | 
			
		||||
                    $event->force = $this->input->getOption('force');
 | 
			
		||||
                    $event->input = $this->input;
 | 
			
		||||
                    $event->output = $this->output;
 | 
			
		||||
                    $event->helperSet = $this->getHelperSet();
 | 
			
		||||
                    
 | 
			
		||||
                    $this->eventDispatcher->dispatch('chill_person.person_import', $event);
 | 
			
		||||
                    
 | 
			
		||||
                    if ($this->input->getOption('force') === TRUE 
 | 
			
		||||
                        && $event->skipPerson === false) {
 | 
			
		||||
                        $this->em->persist($person);
 | 
			
		||||
                    }
 | 
			
		||||
                    
 | 
			
		||||
@@ -451,13 +511,13 @@ EOF
 | 
			
		||||
        $openingDate = $this->processDate($openingDateString, $this->input->getOption('opening_date_format'));
 | 
			
		||||
        
 | 
			
		||||
        $person = $openingDate instanceof \DateTime ? new Person($openingDate) : new Person();
 | 
			
		||||
        
 | 
			
		||||
        // currently, import only men
 | 
			
		||||
        $person->setGender(Person::MALE_GENDER);
 | 
			
		||||
        
 | 
			
		||||
        // add the center
 | 
			
		||||
        $center = $this->em->getRepository('ChillMainBundle:Center')
 | 
			
		||||
                ->find($this->input->getArgument('center'));
 | 
			
		||||
        $center = $this->getCenter($row, $headers);
 | 
			
		||||
        
 | 
			
		||||
        if ($center === null) {
 | 
			
		||||
            throw new \Exception("center not found");
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $person->setCenter($center);
 | 
			
		||||
        
 | 
			
		||||
        foreach($headers as $column => $info) {
 | 
			
		||||
@@ -486,12 +546,198 @@ EOF
 | 
			
		||||
                case 'phonenumber':
 | 
			
		||||
                    $person->setPhonenumber($value); 
 | 
			
		||||
                    break;
 | 
			
		||||
                
 | 
			
		||||
                // we just keep the column number for those data
 | 
			
		||||
                case 'postalcode':
 | 
			
		||||
                    $postalCodeValue = $value;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'street1':
 | 
			
		||||
                    $street1Value = $value;
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'locality':
 | 
			
		||||
                    $localityValue = $value;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // handle address
 | 
			
		||||
        if (\in_array('postalcode', $headers)) {
 | 
			
		||||
            
 | 
			
		||||
            $address = new Address();
 | 
			
		||||
            $postalCode = $this->guessPostalCode($postalCodeValue, $localityValue ?? '');
 | 
			
		||||
            
 | 
			
		||||
            if ($postalCode === null) {
 | 
			
		||||
                throw new \Exception("The locality is not found");
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            $address->setPostcode($postalCode);
 | 
			
		||||
            
 | 
			
		||||
            if (\in_array('street1', $headers)) {
 | 
			
		||||
                $address->setStreetAddress1($street1Value);
 | 
			
		||||
            }
 | 
			
		||||
            $address->setValidFrom(new \DateTime('today'));
 | 
			
		||||
            
 | 
			
		||||
            $person->addAddress($address);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        return $person;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function getCenter($row, $headers)
 | 
			
		||||
    {
 | 
			
		||||
        if ($this->input->hasOption('force-center') && !empty($this->input->getOption('force-center'))) {
 | 
			
		||||
            return $this->em->getRepository('ChillMainBundle:Center')
 | 
			
		||||
                ->find($this->input->getOption('force-center'));
 | 
			
		||||
        } else {
 | 
			
		||||
            $columnCenter = \array_search('center', $headers);
 | 
			
		||||
            $centerName = \trim($row[$columnCenter]);
 | 
			
		||||
            
 | 
			
		||||
            try {
 | 
			
		||||
                return $this->em->createQuery('SELECT c FROM ChillMainBundle:Center c '
 | 
			
		||||
                    . 'WHERE c.name = :center_name')
 | 
			
		||||
                    ->setParameter('center_name', $centerName)
 | 
			
		||||
                    ->getSingleResult()
 | 
			
		||||
                    ;
 | 
			
		||||
            } catch (\Doctrine\ORM\NonUniqueResultException $e) {
 | 
			
		||||
                return $this->guessCenter($centerName);
 | 
			
		||||
            } catch (\Doctrine\ORM\NoResultException $e) {
 | 
			
		||||
                return $this->guessCenter($centerName);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function guessCenter($centerName)
 | 
			
		||||
    {
 | 
			
		||||
        if (!\array_key_exists('_center_picked', $this->cacheAnswersMapping)) {
 | 
			
		||||
            $this->cacheAnswersMapping['_center_picked'] = [];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (\array_key_exists($centerName, $this->cacheAnswersMapping['_center_picked'])) {
 | 
			
		||||
            $id = $this->cacheAnswersMapping['_center_picked'][$centerName];
 | 
			
		||||
            
 | 
			
		||||
            return $this->em->getRepository(Center::class)
 | 
			
		||||
                ->find($id);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $centers = $this->em->createQuery("SELECT c FROM ChillMainBundle:Center c "
 | 
			
		||||
            . "ORDER BY SIMILARITY(c.name, :center_name) DESC")
 | 
			
		||||
            ->setParameter('center_name', $centerName)
 | 
			
		||||
            ->setMaxResults(10)
 | 
			
		||||
            ->getResult()
 | 
			
		||||
            ;
 | 
			
		||||
        
 | 
			
		||||
        if (count($centers) > 1) {
 | 
			
		||||
            if (\strtolower($centers[0]->getName()) === \strtolower($centerName)) {
 | 
			
		||||
                return $centers[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $centersByName = [];
 | 
			
		||||
        $names = \array_map(function(Center $c) use (&$centersByName) { 
 | 
			
		||||
            $n = $c->getName();
 | 
			
		||||
            $centersByName[$n] = $c;
 | 
			
		||||
            return $n;
 | 
			
		||||
            
 | 
			
		||||
        }, $centers);
 | 
			
		||||
        $names[] = "none of them";
 | 
			
		||||
        
 | 
			
		||||
        $helper = $this->getHelper('question');
 | 
			
		||||
        $question = new ChoiceQuestion(sprintf("Which center match the name \"%s\" ? (default to \"%s\")", $centerName, $names[0]), 
 | 
			
		||||
            $names,
 | 
			
		||||
            0);
 | 
			
		||||
        
 | 
			
		||||
        $answer = $helper->ask($this->input, $this->output, $question);
 | 
			
		||||
        
 | 
			
		||||
        if ($answer === 'none of them') {
 | 
			
		||||
            $questionCreate = new ConfirmationQuestion("Would you like to create it ?", false);
 | 
			
		||||
            $create = $helper->ask($this->input, $this->output, $questionCreate);
 | 
			
		||||
            
 | 
			
		||||
            if ($create) {
 | 
			
		||||
                $center = (new Center())
 | 
			
		||||
                    ->setName($centerName)
 | 
			
		||||
                    ;
 | 
			
		||||
                
 | 
			
		||||
                if ($this->input->getOption('force') === TRUE) {
 | 
			
		||||
                    $this->em->persist($center);
 | 
			
		||||
                    $this->em->flush();
 | 
			
		||||
                }
 | 
			
		||||
                
 | 
			
		||||
                return $center;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $center = $centersByName[$answer];
 | 
			
		||||
        
 | 
			
		||||
        $this->cacheAnswersMapping['_center_picked'][$centerName] = $center->getId();
 | 
			
		||||
        
 | 
			
		||||
        return $center;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    protected function guessPostalCode($postalCode, $locality)
 | 
			
		||||
    {
 | 
			
		||||
        if (!\array_key_exists('_postal_code_picked', $this->cacheAnswersMapping)) {
 | 
			
		||||
            $this->cacheAnswersMapping['_postal_code_picked'] = [];
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (\array_key_exists($postalCode, $this->cacheAnswersMapping['_postal_code_picked'])) {
 | 
			
		||||
            if (\array_key_exists($locality, $this->cacheAnswersMapping['_postal_code_picked'][$postalCode])) {
 | 
			
		||||
                $id = $this->cacheAnswersMapping['_postal_code_picked'][$postalCode][$locality];
 | 
			
		||||
                
 | 
			
		||||
                return $this->em->getRepository(PostalCode::class)->find($id);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $postalCodes = $this->em->createQuery("SELECT pc FROM ".PostalCode::class." pc "
 | 
			
		||||
            . "WHERE pc.code = :postal_code "
 | 
			
		||||
            . "ORDER BY SIMILARITY(pc.name, :locality) DESC "
 | 
			
		||||
            )
 | 
			
		||||
            ->setMaxResults(10)
 | 
			
		||||
            ->setParameter('postal_code', $postalCode)
 | 
			
		||||
            ->setParameter('locality', $locality)
 | 
			
		||||
            ->getResult()
 | 
			
		||||
            ;
 | 
			
		||||
        
 | 
			
		||||
        if (count($postalCodes) >= 1) {
 | 
			
		||||
            if ($postalCodes[0]->getCode() === $postalCode 
 | 
			
		||||
                && $postalCodes[0]->getName() === $locality) {
 | 
			
		||||
                return $postalCodes[0];
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (count($postalCodes) === 0) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $postalCodeByName = [];
 | 
			
		||||
        $names = \array_map(function(PostalCode $pc) use (&$postalCodeByName) {
 | 
			
		||||
            $n = $pc->getName();
 | 
			
		||||
            $postalCodeByName[$n] = $pc;
 | 
			
		||||
            
 | 
			
		||||
            return $n;
 | 
			
		||||
        }, $postalCodes);
 | 
			
		||||
        $names[] = 'none of them';
 | 
			
		||||
        
 | 
			
		||||
        $helper = $this->getHelper('question');
 | 
			
		||||
        $question = new ChoiceQuestion(sprintf("Which postal code match the "
 | 
			
		||||
            . "name \"%s\" with postal code \"%s\" ? (default to \"%s\")", 
 | 
			
		||||
            $locality, $postalCode, $names[0]), 
 | 
			
		||||
            $names,
 | 
			
		||||
            0);
 | 
			
		||||
        
 | 
			
		||||
        $answer = $helper->ask($this->input, $this->output, $question);
 | 
			
		||||
        
 | 
			
		||||
        if ($answer === 'none of them') {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        $pc = $postalCodeByName[$answer];
 | 
			
		||||
        
 | 
			
		||||
        $this->cacheAnswersMapping['_postal_code_picked'][$postalCode][$locality] = 
 | 
			
		||||
            $pc->getId();
 | 
			
		||||
        
 | 
			
		||||
        return $pc;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    protected function processBirthdate(Person $person, $value)
 | 
			
		||||
    {
 | 
			
		||||
@@ -556,7 +802,7 @@ EOF
 | 
			
		||||
        /* @var $factory \Symfony\Component\Form\FormFactory */
 | 
			
		||||
        $factory = $this->getContainer()->get('form.factory');
 | 
			
		||||
        /* @var $cfProvider \Chill\CustomFieldsBundle\Service\CustomFieldProvider */
 | 
			
		||||
        $cfProvider = $this->getContainer()->get('chill.custom_field.provider');
 | 
			
		||||
        $cfProvider = $this->customFieldProvider;
 | 
			
		||||
        $cfData = array();
 | 
			
		||||
        
 | 
			
		||||
        /* @var $$customField \Chill\CustomFieldsBundle\Entity\CustomField */
 | 
			
		||||
@@ -722,7 +968,7 @@ EOF
 | 
			
		||||
                        $value));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        var_dump($this->cacheAnswersMapping[$cf->getSlug()][$value]);
 | 
			
		||||
        
 | 
			
		||||
        $form->submit(array($cf->getSlug() => $this->cacheAnswersMapping[$cf->getSlug()][$value]));
 | 
			
		||||
        $value = $form->getData()[$cf->getSlug()];
 | 
			
		||||
        
 | 
			
		||||
 
 | 
			
		||||
@@ -63,6 +63,7 @@ class ChillPersonExtension extends Extension implements PrependExtensionInterfac
 | 
			
		||||
        $loader->load('services/search.yml');
 | 
			
		||||
        $loader->load('services/menu.yml');
 | 
			
		||||
        $loader->load('services/privacyEvent.yml');
 | 
			
		||||
        $loader->load('services/command.yml');
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    private function handlePersonFieldsParameters(ContainerBuilder $container, $config)
 | 
			
		||||
 
 | 
			
		||||
@@ -83,6 +83,10 @@ class GenderAggregator implements AggregatorInterface
 | 
			
		||||
                    return $this->translator->trans('woman');
 | 
			
		||||
                case Person::MALE_GENDER   : 
 | 
			
		||||
                    return $this->translator->trans('man');
 | 
			
		||||
                case Person::BOTH_GENDER:
 | 
			
		||||
                    return $this->translator->trans('both');
 | 
			
		||||
                case null:
 | 
			
		||||
                    return $this->translator->trans('Not given');
 | 
			
		||||
                case '_header' : 
 | 
			
		||||
                    return $this->translator->trans('Gender');
 | 
			
		||||
                default:
 | 
			
		||||
 
 | 
			
		||||
@@ -51,17 +51,19 @@ class GenderFilter implements FilterInterface,
 | 
			
		||||
        $builder->add('accepted_genders', ChoiceType::class, array(
 | 
			
		||||
            'choices' => array(
 | 
			
		||||
                'Woman' => Person::FEMALE_GENDER,
 | 
			
		||||
                'Man' => Person::MALE_GENDER
 | 
			
		||||
                'Man' => Person::MALE_GENDER,
 | 
			
		||||
                'Both' => Person::BOTH_GENDER,
 | 
			
		||||
                'Not given' => 'null'
 | 
			
		||||
            ),
 | 
			
		||||
            'choices_as_values' => true,
 | 
			
		||||
            'multiple' => false,
 | 
			
		||||
            'expanded' => false
 | 
			
		||||
            'multiple' => true,
 | 
			
		||||
            'expanded' => true
 | 
			
		||||
        ));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function validateForm($data, ExecutionContextInterface $context)
 | 
			
		||||
    {
 | 
			
		||||
        if ($data['accepted_genders'] === null) {
 | 
			
		||||
        if (!is_array($data['accepted_genders']) || count($data['accepted_genders']) === 0 ) {
 | 
			
		||||
            $context->buildViolation("You should select an option")
 | 
			
		||||
                ->addViolation();
 | 
			
		||||
        }
 | 
			
		||||
@@ -70,8 +72,13 @@ class GenderFilter implements FilterInterface,
 | 
			
		||||
    public function alterQuery(QueryBuilder $qb, $data)
 | 
			
		||||
    {
 | 
			
		||||
        $where = $qb->getDQLPart('where');
 | 
			
		||||
        $clause = $qb->expr()->in('person.gender', ':person_gender');
 | 
			
		||||
 | 
			
		||||
        $isIn = $qb->expr()->in('person.gender', ':person_gender');
 | 
			
		||||
        
 | 
			
		||||
        if (!\in_array('null', $data['accepted_genders'])) {
 | 
			
		||||
            $clause = $isIn;
 | 
			
		||||
        } else {
 | 
			
		||||
            $clause = $qb->expr()->orX($isIn, $qb->expr()->isNull('person.gender'));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ($where instanceof Expr\Andx) {
 | 
			
		||||
            $where->add($clause);
 | 
			
		||||
@@ -80,7 +87,11 @@ class GenderFilter implements FilterInterface,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $qb->add('where', $where);
 | 
			
		||||
        $qb->setParameter('person_gender', $data['accepted_genders']);
 | 
			
		||||
        $qb->setParameter('person_gender', \array_filter(
 | 
			
		||||
            $data['accepted_genders'],
 | 
			
		||||
            function($el) {
 | 
			
		||||
                return $el !== 'null';
 | 
			
		||||
            }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,7 @@ Chill\PersonBundle\Entity\Person:
 | 
			
		||||
        gender:
 | 
			
		||||
            type: string
 | 
			
		||||
            length: 9
 | 
			
		||||
            nullable: true
 | 
			
		||||
        memo:
 | 
			
		||||
            type: text
 | 
			
		||||
            default: ''
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								Resources/config/services/command.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Resources/config/services/command.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
			
		||||
services:
 | 
			
		||||
    Chill\PersonBundle\Command\ImportPeopleFromCSVCommand:
 | 
			
		||||
        arguments:
 | 
			
		||||
            $logger: '@logger'
 | 
			
		||||
            $helper: '@Chill\MainBundle\Templating\TranslatableStringHelper'
 | 
			
		||||
            $em: '@Doctrine\ORM\EntityManagerInterface'
 | 
			
		||||
            $customFieldProvider: '@Chill\CustomFieldsBundle\Service\CustomFieldProvider'
 | 
			
		||||
            $eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
 | 
			
		||||
        tags:
 | 
			
		||||
            - { name: console.command }
 | 
			
		||||
							
								
								
									
										26
									
								
								Resources/migrations/Version20181005140249.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								Resources/migrations/Version20181005140249.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Application\Migrations;
 | 
			
		||||
 | 
			
		||||
use Doctrine\DBAL\Schema\Schema;
 | 
			
		||||
use Doctrine\Migrations\AbstractMigration;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set person gender not null
 | 
			
		||||
 */
 | 
			
		||||
final class Version20181005140249 extends AbstractMigration
 | 
			
		||||
{
 | 
			
		||||
    public function up(Schema $schema) : void
 | 
			
		||||
    {
 | 
			
		||||
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
 | 
			
		||||
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_person_person ALTER gender DROP NOT NULL');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function down(Schema $schema) : void
 | 
			
		||||
    {
 | 
			
		||||
        $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'postgresql', 'Migration can only be executed safely on \'postgresql\'.');
 | 
			
		||||
 | 
			
		||||
        $this->addSql('ALTER TABLE chill_person_person ALTER gender SET NOT NULL');
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -24,13 +24,6 @@
 | 
			
		||||
{% extends "ChillMainBundle::layoutWithVerticalMenu.html.twig" %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block css %}
 | 
			
		||||
    {% stylesheets  output="css/person.css" filter="cssrewrite"
 | 
			
		||||
        "bundles/chillperson/css/person.css"
 | 
			
		||||
    %}
 | 
			
		||||
        <link rel="stylesheet" href="{{ asset_url }}"/>
 | 
			
		||||
    {% endstylesheets %}
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block top_banner %}
 | 
			
		||||
    <div class="grid-12 parent" id="header-person-name" >
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user