diff --git a/src/Bundle/ChillPersonBundle/src/Command/ImportPeopleFromCSVCommand.php b/src/Bundle/ChillPersonBundle/src/Command/ImportPeopleFromCSVCommand.php index d5e4c597c..073ebeacd 100644 --- a/src/Bundle/ChillPersonBundle/src/Command/ImportPeopleFromCSVCommand.php +++ b/src/Bundle/ChillPersonBundle/src/Command/ImportPeopleFromCSVCommand.php @@ -40,6 +40,7 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\Form\FormFactory; +use Symfony\Component\Form\FormFactoryInterface; /** * Class ImportPeopleFromCSVCommand @@ -53,52 +54,52 @@ class ImportPeopleFromCSVCommand extends Command * @var InputInterface */ protected $input; - + /** * @var OutputInterface */ protected $output; - + /** * @var \Psr\Log\LoggerInterface */ protected $logger; - + /** * @var \Chill\MainBundle\Templating\TranslatableStringHelper */ protected $helper; - + /** * @var \Doctrine\Persistence\ObjectManager */ protected $em; - + /** * @var EventDispatcherInterface */ protected $eventDispatcher; - + /** * the line currently read * * @var int */ protected $line; - + /** * @var array where key are column names, and value the custom field slug */ protected $customFieldMapping = array(); - + /** * @var CustomFieldProvider */ protected $customFieldProvider; - + /** * Contains an array of information searched in the file. - * + * * position 0: the information key (which will be used in this process) * position 1: the helper * position 2: the default value @@ -121,19 +122,19 @@ class ImportPeopleFromCSVCommand extends Command ['locality', 'The column header for locality', 'locality'], ['center', 'The column header for center', 'center'] ); - + /** * Different possible format to interpret a date * * @var string */ protected static $defaultDateInterpreter = "%d/%m/%Y|%e/%m/%y|%d/%m/%Y|%e/%m/%Y"; - + /** - * @var FormFactory + * @var FormFactoryInterface */ protected $formFactory; - + /** * ImportPeopleFromCSVCommand constructor. * @@ -142,7 +143,7 @@ class ImportPeopleFromCSVCommand extends Command * @param EntityManagerInterface $em * @param CustomFieldProvider $customFieldProvider * @param EventDispatcherInterface $eventDispatcher - * @param FormFactory $formFactory + * @param FormFactoryInterface $formFactory */ public function __construct( LoggerInterface $logger, @@ -150,7 +151,7 @@ class ImportPeopleFromCSVCommand extends Command EntityManagerInterface $em, CustomFieldProvider $customFieldProvider, EventDispatcherInterface $eventDispatcher, - FormFactory $formFactory + FormFactoryInterface $formFactory ) { $this->logger = $logger; $this->helper = $helper; @@ -158,10 +159,10 @@ class ImportPeopleFromCSVCommand extends Command $this->customFieldProvider = $customFieldProvider; $this->eventDispatcher = $eventDispatcher; $this->formFactory = $formFactory; - + parent::__construct('chill:person:import'); } - + /** * */ @@ -171,10 +172,10 @@ class ImportPeopleFromCSVCommand extends Command ->addArgument('csv_file', InputArgument::REQUIRED, "The CSV file to import") ->setDescription("Import people from a csv file") ->setHelp(<<addArgument('locale', InputArgument::REQUIRED, + ->addArgument('locale', InputArgument::REQUIRED, "The locale to use in displaying translatable strings from entities") ->addOption( - 'force-center', - null, + 'force-center', + null, InputOption::VALUE_REQUIRED, "The id of the center" ) @@ -197,10 +198,10 @@ EOF "Persist people in the database (default is not to persist people)" ) ->addOption( - 'delimiter', - 'd', - InputOption::VALUE_OPTIONAL, - "The delimiter character of the csv file", + 'delimiter', + 'd', + InputOption::VALUE_OPTIONAL, + "The delimiter character of the csv file", ",") ->addOption( 'enclosure', @@ -236,33 +237,33 @@ EOF "The path of the file to load the matching between label in CSV and answers" ) ; - + // mapping columns foreach (self::$mapping as $m) { $this->addOptionShortcut($m[0], $m[1], $m[2]); } - + // other information $this->addOptionShortcut('birthdate_format', 'Format preference for ' - . 'birthdate. See help for date formats preferences.', + . 'birthdate. See help for date formats preferences.', self::$defaultDateInterpreter); $this->addOptionShortcut('opening_date_format', 'Format preference for ' . 'opening date. See help for date formats preferences.', self::$defaultDateInterpreter); $this->addOptionShortcut('closing_date_format', 'Format preference for ' - . 'closing date. See help for date formats preferences.', + . 'closing date. See help for date formats preferences.', self::$defaultDateInterpreter); - + // mapping column to custom fields - $this->addOption('custom-field', NULL, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, + $this->addOption('custom-field', NULL, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, "Mapping a column to a custom fields key. Example: 1=cf_slug"); $this->addOption('skip-interactive-field-mapping', null, InputOption::VALUE_NONE, "Do not ask for interactive mapping"); } - + /** * This function is a shortcut to addOption. - * + * * @param string $name * @param string $description * @param string $default @@ -271,10 +272,10 @@ EOF protected function addOptionShortcut($name, $description, $default) { $this->addOption($name, null, InputOption::VALUE_OPTIONAL, $description, $default); - + return $this; } - + /** * @param InputInterface $input * @param OutputInterface $output @@ -285,17 +286,17 @@ EOF $this->input = $input; $this->output = $output; $this->logger = new ConsoleLogger($output); - + $csv = $this->openCSV(); - + // getting the first row if (($row = fgetcsv( - $csv, - $input->getOption('length'), - $input->getOption('delimiter'), - $input->getOption('enclosure'), + $csv, + $input->getOption('length'), + $input->getOption('delimiter'), + $input->getOption('enclosure'), $input->getOption('escape'))) !== false) { - + try { $this->matchColumnToCustomField($row); } finally { @@ -303,33 +304,33 @@ EOF fclose($csv); } } - + // load the matching between csv and label $this->loadAnswerMatching(); } - + /** * @param $row */ protected function matchColumnToCustomField($row) { - + $cfMappingsOptions = $this->input->getOption('custom-field'); /* @var $em \Doctrine\Persistence\ObjectManager */ $em = $this->em; - + foreach($cfMappingsOptions as $cfMappingStringOption) { list($rowNumber, $cfSlug) = preg_split('|=|', $cfMappingStringOption); - + // check that the column exists, getting the column name $column = $row[$rowNumber]; - + if (empty($column)) { $message = "The column with row $rowNumber is empty."; $this->logger->error($message); throw new \RuntimeException($message); } - + // check a custom field exists try { $customField = $em->createQuery("SELECT cf " @@ -357,15 +358,15 @@ EOF . "Stopping this command."); throw new \RuntimeException("The custom field with slug $cfSlug could not be found. " . "Stopping this command."); - } - + } + $this->logger->notice(sprintf("Matched custom field %s (question : '%s') on column %d (displayed in the file as '%s')", $customField->getSlug(), $this->helper->localize($customField->getName()), $rowNumber, $column)); - + $this->customFieldMapping[$rowNumber] = $customField; } } - + /** * Load the mapping between answer in CSV and value in choices from a json file */ @@ -383,7 +384,7 @@ EOF } } } - + /** * */ @@ -392,14 +393,14 @@ EOF 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); - + $fs = new Filesystem(); $filename = $this->input->getOption('dump-choice-matching'); - + $fs->dumpFile($filename, $str); } } - + /** * @param InputInterface $input * @param OutputInterface $output @@ -410,22 +411,22 @@ EOF { $this->input = $input; $this->output = $output; - + $this->logger->debug("Setting locale to ".$input->getArgument('locale')); setlocale(LC_TIME, $input->getArgument('locale')); - + // opening csv as resource $csv = $this->openCSV(); - + $num = 0; $line = $this->line = 1; - + try { while (($row = fgetcsv( - $csv, - $input->getOption('length'), - $input->getOption('delimiter'), - $input->getOption('enclosure'), + $csv, + $input->getOption('length'), + $input->getOption('delimiter'), + $input->getOption('enclosure'), $input->getOption('escape'))) !== false) { $this->logger->debug("Processing line ".$this->line); if ($line === 1 ) { @@ -434,11 +435,11 @@ EOF $headers = $this->processingHeaders($row); } else { $person = $this->createPerson($row, $headers); - + if (count($this->customFieldMapping) > 0) { $this->processingCustomFields($person, $row); } - + $event = new Event(); $event->person = $person; $event->rawHeaders = $rawHeaders; @@ -449,21 +450,21 @@ EOF $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 + + if ($this->input->getOption('force') === TRUE && $event->skipPerson === false) { $this->em->persist($person); } - + $num ++; } $line ++; $this->line++; } - + if ($this->input->getOption('force') === true) { $this->logger->debug('persisting entitites'); $this->em->flush(); @@ -475,9 +476,9 @@ EOF $this->dumpAnswerMatching(); } } - + /** - * + * * @return resource * @throws \RuntimeException */ @@ -485,23 +486,23 @@ EOF { $fs = new Filesystem(); $filename = $this->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, 'r'); - + if ($resource == FALSE) { throw new \RuntimeException("The file '$filename' could not be opened."); } - + return $resource; } - + /** - * + * * @param type $firstRow * @return array where keys are column number, and value is information mapped */ @@ -510,11 +511,11 @@ EOF $availableOptions = array_map(function($m) { return $m[0]; }, self::$mapping); $matchedColumnHeaders = array(); $headers = array(); - + foreach($availableOptions as $option) { $matchedColumnHeaders[$option] = $this->input->getOption($option); } - + foreach($firstRow as $key => $content) { $content = trim($content); if (in_array($content, $matchedColumnHeaders)) { @@ -524,11 +525,11 @@ EOF } else { $this->logger->notice("Column with content '$content' is ignored"); } - } - + } + return $headers; } - + /** * * @param array $row @@ -541,21 +542,21 @@ EOF // trying to get the opening date $openingDateString = trim($row[array_search('opening_date', $headers)]); $openingDate = $this->processDate($openingDateString, $this->input->getOption('opening_date_format')); - + $person = $openingDate instanceof \DateTime ? new Person($openingDate) : new Person(); // add the center $center = $this->getCenter($row, $headers); - + if ($center === null) { throw new \Exception("center not found"); } - + $person->setCenter($center); - + foreach($headers as $column => $info) { - + $value = trim($row[$column]); - + switch($info) { case 'firstname': $person->setFirstName($value); @@ -582,12 +583,12 @@ EOF $person->setEmail($value); break; case 'phonenumber': - $person->setPhonenumber($value); + $person->setPhonenumber($value); break; case 'mobilenumber': $person->setMobilenumber($value); break; - + // we just keep the column number for those data case 'postalcode': $postalCodeValue = $value; @@ -600,33 +601,33 @@ EOF break; } } - + // handle address if (\in_array('postalcode', $headers)) { - + if (! empty($postalCodeValue)) { - + $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; } - + /** * @param $row * @param $headers @@ -640,7 +641,7 @@ EOF } 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') @@ -654,7 +655,7 @@ EOF } } } - + /** * @param $centerName * @return Center|mixed|null|object @@ -664,68 +665,68 @@ EOF 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) { + $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]), + $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; } - + /** * @param $postalCode * @param $locality @@ -736,15 +737,15 @@ EOF 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 " @@ -754,48 +755,48 @@ EOF ->setParameter('locality', $locality) ->getResult() ; - + if (count($postalCodes) >= 1) { - if ($postalCodes[0]->getCode() === $postalCode + 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]), + . "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] = + + $this->cacheAnswersMapping['_postal_code_picked'][$postalCode][$locality] = $pc->getId(); - + return $pc; } - + /** * @param Person $person * @param $value @@ -804,29 +805,29 @@ EOF protected function processBirthdate(Person $person, $value) { if (empty($value)) { return; } - + $date = $this->processDate($value, $this->input->getOption('birthdate_format')); - + if ($date instanceof \DateTime) { // we correct birthdate if the date is in the future // the most common error is to set date 100 years to late (ex. 2063 instead of 1963) if ($date > new \DateTime('yesterday')) { $date = $date->sub(new \DateInterval('P100Y')); } - + $person->setBirthdate($date); - + return; } - + // if we arrive here, we could not process the date $this->logger->warning(sprintf( "Line %d : the birthdate could not be interpreted. Was %s.", $this->line, $value)); - + } - + /** * @param Person $person * @param $value @@ -835,39 +836,39 @@ EOF protected function processClosingDate(Person $person, $value) { if (empty($value)) { return; } - + // we skip if the opening date is now (or after yesterday) /* @var $period \Chill\PersonBundle\Entity\AccompanyingPeriod */ $period = $person->getCurrentAccompanyingPeriod(); - + if ($period->getOpeningDate() > new \DateTime('yesterday')) { $this->logger->debug(sprintf("skipping a closing date because opening date is after yesterday (%s)", $period->getOpeningDate()->format('Y-m-d'))); return; } - - + + $date = $this->processDate($value, $this->input->getOption('closing_date_format')); - + if ($date instanceof \DateTime) { // we correct birthdate if the date is in the future // the most common error is to set date 100 years to late (ex. 2063 instead of 1963) if ($date > new \DateTime('yesterday')) { $date = $date->sub(new \DateInterval('P100Y')); } - + $period->setClosingDate($date); $person->close(); return; } - + // if we arrive here, we could not process the date $this->logger->warning(sprintf( "Line %d : the closing date could not be interpreted. Was %s.", $this->line, $value)); } - + /** * @param Person $person * @param $row @@ -875,27 +876,27 @@ EOF */ protected function processingCustomFields(Person $person, $row) { - + /* @var $cfProvider \Chill\CustomFieldsBundle\Service\CustomFieldProvider */ $cfProvider = $this->customFieldProvider; $cfData = array(); - + /* @var $$customField \Chill\CustomFieldsBundle\Entity\CustomField */ foreach($this->customFieldMapping as $rowNumber => $customField) { $builder = $this->formFactory->createBuilder(); $cfProvider->getCustomFieldByType($customField->getType()) ->buildForm($builder, $customField); $form = $builder->getForm(); - + // get the type of the form $type = get_class($form->get($customField->getSlug()) ->getConfig()->getType()->getInnerType()); - $this->logger->debug(sprintf("Processing a form of type %s", + $this->logger->debug(sprintf("Processing a form of type %s", $type)); switch ($type) { case \Symfony\Component\Form\Extension\Core\Type\TextType::class: - $cfData[$customField->getSlug()] = + $cfData[$customField->getSlug()] = $this->processTextType($row[$rowNumber], $form, $customField); break; case \Symfony\Component\Form\Extension\Core\Type\ChoiceType::class: @@ -903,12 +904,12 @@ EOF $cfData[$customField->getSlug()] = $this->processChoiceType($row[$rowNumber], $form, $customField); } - + } - + $person->setCFData($cfData); } - + /** * Process a text type on a custom field * @@ -917,24 +918,24 @@ EOF * @return type */ protected function processTextType( - $value, - \Symfony\Component\Form\FormInterface $form, + $value, + \Symfony\Component\Form\FormInterface $form, \Chill\CustomFieldsBundle\Entity\CustomField $cf ) { $form->submit(array($cf->getSlug() => $value)); - + $value = $form->getData()[$cf->getSlug()]; - + $this->logger->debug(sprintf("Found value : %s for custom field with question " . "'%s'", $value, $this->helper->localize($cf->getName()))); - + return $value; } - + protected $cacheAnswersMapping = array(); - - + + /** * Process a custom field choice. * @@ -949,14 +950,14 @@ EOF */ protected function processChoiceType( $value, - \Symfony\Component\Form\FormInterface $form, + \Symfony\Component\Form\FormInterface $form, \Chill\CustomFieldsBundle\Entity\CustomField $cf ) { // getting the possible answer and their value : $view = $form->get($cf->getSlug())->createView(); $answers = $this->collectChoicesAnswers($view->vars['choices']); - + // if we do not have any answer on the question, throw an error. if (count($answers) === 0) { $message = sprintf( @@ -964,34 +965,34 @@ EOF $this->helper->localize($cf->getName()), $cf->getSlug() ); - + $this->logger->error($message, array( 'method' => __METHOD__, 'slug' => $cf->getSlug(), 'question' => $this->helper->localize($cf->getName()) )); - + throw new \RuntimeException($message); } - + if ($view->vars['required'] === false) { $answers[null] = '** no answer'; } - + // the answer does not exists in cache. Try to find it, or asks the user if (!isset($this->cacheAnswersMapping[$cf->getSlug()][$value])) { - + // try to find the answer (with array_keys and a search value $values = array_keys( - array_map(function($label) { return trim(strtolower($label)); }, $answers), + array_map(function($label) { return trim(strtolower($label)); }, $answers), trim(strtolower($value)), true ); - + if (count($values) === 1) { // we could guess an answer ! $this->logger->info("This question accept multiple answers"); - $this->cacheAnswersMapping[$cf->getSlug()][$value] = + $this->cacheAnswersMapping[$cf->getSlug()][$value] = $view->vars['multiple'] == false ? $values[0] : array($values[0]); $this->logger->info(sprintf("Guessed that value '%s' match with key '%s' " . "because the CSV and the label are equals.", @@ -1021,20 +1022,20 @@ EOF array_keys($matchingTableRowAnswer) ); $question->setErrorMessage("This choice is not possible"); - + if ($view->vars['multiple']) { $this->logger->debug("this question is multiple"); $question->setMultiselect(true); } - + $selected = $this->getHelper('question')->ask($this->input, $this->output, $question); - $this->output->writeln(sprintf('You have selected "%s"', - is_array($answers[$matchingTableRowAnswer[$selected]]) ? + $this->output->writeln(sprintf('You have selected "%s"', + is_array($answers[$matchingTableRowAnswer[$selected]]) ? implode(',', $answers[$matchingTableRowAnswer[$selected]]) : $answers[$matchingTableRowAnswer[$selected]]) ); - + // recording value in cache $this->cacheAnswersMapping[$cf->getSlug()][$value] = $matchingTableRowAnswer[$selected]; $this->logger->debug(sprintf("Setting the value '%s' in cache for customfield '%s' and answer '%s'", @@ -1045,19 +1046,19 @@ EOF $value)); } } - + $form->submit(array($cf->getSlug() => $this->cacheAnswersMapping[$cf->getSlug()][$value])); $value = $form->getData()[$cf->getSlug()]; - + $this->logger->debug(sprintf( - "Found value : %s for custom field with question '%s'", - is_array($value) ? implode(',', $value) : $value, + "Found value : %s for custom field with question '%s'", + is_array($value) ? implode(',', $value) : $value, $this->helper->localize($cf->getName())) ); - + return $value; } - + /** * Recursive method to collect the possibles answer from a ChoiceType (or * its inherited types). @@ -1069,7 +1070,7 @@ EOF private function collectChoicesAnswers($choices) { $answers = array(); - + /* @var $choice \Symfony\Component\Form\ChoiceList\View\ChoiceView */ foreach($choices as $choice) { if ($choice instanceof \Symfony\Component\Form\ChoiceList\View\ChoiceView) { @@ -1085,10 +1086,10 @@ EOF )); } } - + return $answers; } - + /** * @param $value * @param $formats @@ -1097,13 +1098,13 @@ EOF protected function processDate($value, $formats) { $possibleFormats = explode("|", $formats); - + foreach($possibleFormats as $format) { $this->logger->debug("Trying format $format", array(__METHOD__)); $dateR = strptime($value, $format); - + if (is_array($dateR) && $dateR['unparsed'] === '') { - $string = sprintf("%04d-%02d-%02d %02d:%02d:%02d", + $string = sprintf("%04d-%02d-%02d %02d:%02d:%02d", ($dateR['tm_year']+1900), ($dateR['tm_mon']+1), ($dateR['tm_mday']), @@ -1112,19 +1113,19 @@ EOF ($dateR['tm_sec'])); $date = \DateTime::createFromFormat("Y-m-d H:i:s", $string); $this->logger->debug(sprintf("Interpreting %s as date %s", $value, $date->format("Y-m-d H:i:s"))); - + return $date; } } - + // if we arrive here, we could not process the date $this->logger->debug(sprintf( "Line %d : a date could not be interpreted. Was %s.", $this->line, $value)); - + return false; } - - + + }