entityManager = $entityManager; $this->validator = $validator; parent::__construct(); } protected function configure() { $this->setName('chill:main:postal-code:populate') ->setDescription('Add the postal code from a csv file.') ->setHelp('This script will try to avoid existing postal code ' . "using the postal code and name. \n" . 'The CSV file must have the following columns: ' . 'postal code, label, country code.' . 'Optionally, the csv file can have the following ' . 'columns after the country code: reference code, latitude, longitude, source. ' . 'The latitude and longitude columns are supposed to be in WGS84 and expressed in decimal degrees. ' . 'The CSV file should not have any header row.') ->addArgument('csv_file', InputArgument::REQUIRED, 'the path to ' . 'the csv file. See the help for specifications.') ->addOption( 'delimiter', 'd', InputOption::VALUE_OPTIONAL, 'The delimiter character of the csv file', ',' ) ->addOption( 'enclosure', null, InputOption::VALUE_OPTIONAL, 'The enclosure character of the csv file', '"' ) ->addOption( 'escape', null, InputOption::VALUE_OPTIONAL, 'The escape character of the csv file', '\\' ); } protected function execute(InputInterface $input, OutputInterface $output) { $csv = $this->getCSVResource($input); if ($output->getVerbosity() === OutputInterface::VERBOSITY_VERY_VERBOSE) { $output->writeln('The content of the file is ...'); $output->write(file_get_contents($input->getArgument('csv_file'))); } $num = 0; $line = 0; while ( false !== ($row = fgetcsv( $csv, 0, $input->getOption('delimiter'), $input->getOption('enclosure'), $input->getOption('escape') )) ) { try { $this->addPostalCode($row, $output); ++$num; } catch (ExistingPostalCodeException $ex) { $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); } catch (CountryCodeNotFoundException $ex) { $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); } catch (PostalCodeNotValidException $ex) { $output->writeln(' on line ' . $line . ' : ' . $ex->getMessage() . ''); } ++$line; } $this->entityManager->flush(); $output->writeln('' . $num . ' were added !'); } private function addPostalCode($row, OutputInterface $output) { if ('FR' === $row[2] && strlen($row[0]) === 4) { // CP in FRANCE are on 5 digit // For CP starting with a zero, the starting zero can be remove if stored as number in a csv // add a zero if CP from FR and on 4 digit $row[0] = '0' . $row[0]; } if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { $output->writeln('handling row: ' . $row[0] . ' | ' . $row[1] . ' | ' . $row[2]); } $em = $this->entityManager; $country = $em ->getRepository(Country::class) ->findOneBy(['countryCode' => $row[2]]); if (null === $country) { throw new CountryCodeNotFoundException(sprintf( 'The country with code %s is not found. Aborting to insert postal code with %s - %s', $row[2], $row[0], $row[1] )); } // try to find an existing postal code $existingPC = $em ->getRepository(PostalCode::class) ->findBy(['code' => $row[0], 'name' => $row[1]]); if (count($existingPC) > 0) { throw new ExistingPostalCodeException(sprintf( 'A postal code with code : %s and name : %s already exists, skipping', $row[0], $row[1] )); } $postalCode = (new PostalCode()) ->setCode($row[0]) ->setName($row[1]) ->setCountry($country); if (null !== $row[3]) { $postalCode->setRefPostalCodeId($row[3]); } if (null !== $row[4] & null !== $row[5]) { $postalCode->setCenter(Point::fromLonLat((float) $row[5], (float) $row[4])); } if (null !== $row[6]) { $postalCode->setPostalCodeSource($row[6]); } $errors = $this->validator->validate($postalCode); if ($errors->count() === 0) { $em->persist($postalCode); } else { $msg = ''; foreach ($errors as $error) { $msg .= ' ' . $error->getMessage(); } throw new PostalCodeNotValidException($msg); } if ($output->getVerbosity() >= OutputInterface::VERBOSITY_VERBOSE) { $output->writeln(sprintf( 'Creating postal code with code: %s, name: %s, countryCode: %s', $postalCode->getCode(), $postalCode->getName(), $postalCode->getCountry()->getCountryCode() )); } } private function getCSVResource(InputInterface $input) { $fs = new Filesystem(); $filename = $input->getArgument('csv_file'); if (!$fs->exists($filename)) { throw new RuntimeException('The file does not exists or you do not ' . 'have the right to read it.'); } $resource = fopen($filename, 'rb'); if (false === $resource) { throw new RuntimeException("The file '{$filename}' could not be opened."); } return $resource; } } class ExistingPostalCodeException extends Exception { } class CountryCodeNotFoundException extends Exception { } class PostalCodeNotValidException extends Exception { }