em = $em; $this->vmfg_index = []; $this->v_index = []; $this->batt_index = []; parent::__construct(); } protected function configure() { $this->setName('vehicle:import') ->setDescription('Import a CSV file with vehicles and batteries.') ->setHelp('Creates vehicles and batteries based on imported CSV.') ->addArgument('file', InputArgument::REQUIRED, 'Path to the CSV file.'); } protected function populateVehicleIndex() { $vs = $this->em->getRepository(Vehicle::class)->findAll(); $this->v_index = []; $this->vmfg_index = []; foreach ($vs as $v) { $mfg_name = $v->getManufacturer()->getName(); $this->vmfg_index[$mfg_name] = $v->getManufacturer(); if (!isset($this->v_index[$mfg_name])) $this->v_index[$mfg_name] = []; $this->v_index[$mfg_name][$v->getMake() . '|' . $v->getModelYearFrom() . '|' . $v->getModelYearTo()] = $v; } } protected function populateBatteryIndex() { $bs = $this->em->getRepository(Battery::class)->findAll(); $this->batt_index = []; foreach ($bs as $b) { $key = $this->getBatteryKey($b->getSize()->getName(), $b->getModel()->getName()); $this->batt_index[$key] = $b; } } protected function getBatteryKey($size_name, $model_name) { return trim(strtolower(str_replace(' ', '', $size_name))) . '|' . trim(strtolower(str_replace(' ', '', $model_name))); } protected function execute(InputInterface $input, OutputInterface $output) { $csv_file = $input->getArgument('file'); $this->populateVehicleIndex(); $this->populateBatteryIndex(); // attempt to open file try { $fh = fopen($csv_file, "r"); } catch (Exception $e) { throw new Exception('The file "' . $csv_file . '" could be read.'); } // get entity manager $em = $this->em; $vbrands = []; $batteries = []; $bmodels = []; // loop through rows $row_num = 1; while (($fields = fgetcsv($fh)) !== false) { $output->writeln("Parsing row " . $row_num . "..."); // parse it $brand = trim($fields[0]); if (!isset($vbrands[$brand])) { // build array $vbrands[$brand] = [ 'vehicles' => [], ]; } $make = trim($fields[1]); $model = trim($fields[2]); if (empty($model)) $model = 'NONE'; $vbrands[$brand]['vehicles'][$row_num] = [ 'make' => $make, 'model' => $model, ]; // battery $batt_key = $this->getBatteryKey($fields[self::F_B_SIZE], $fields[self::F_B_MODEL]); if (!isset($this->batt_index[$batt_key])) $output->writeln('Could not find battery - ' . $fields[self::F_B_SIZE] . ' - ' . $fields[self::F_B_MODEL]); else $vbrands[$brand]['vehicles'][$row_num]['battery'] = $this->batt_index[$batt_key]; $row_num++; } // print_r($b_models); // print_r($batteries); // save to db // vehicles $vehicle_index = []; foreach ($vbrands as $brand_name => $vbrand) { // get manufacturer or make one if (!isset($this->vmfg_index[$brand_name])) { // manufacturer $mfg = new VehicleManufacturer(); $mfg->setName($brand_name); $em->persist($mfg); } else { $mfg = $this->vmfg_index[$brand_name]; } // vehicles foreach ($vbrand['vehicles'] as $row_num => $vdata) { $model = $vdata['model']; if ($model == 'NONE') { $m_year_from = 0; $m_year_to = 0; } else { $ex_model = explode('-', $model); $m_year_from = trim($ex_model[0]); if (isset($ex_model[1])) $m_year_to = trim($ex_model[1]); else $m_year_to = 0; } if (!isset($this->v_index[$brand_name][$vdata['make'] . '|' . intval($m_year_from) . '|' . intval($m_year_to)])) { echo "NO MATCH $m_year_from - $m_year_to"; echo $vdata['make'] . '|' . intval($m_year_from) . '|' . intval($m_year_to); echo "\n"; // vehicle $vehicle = new Vehicle(); $vehicle->setManufacturer($mfg) ->setMake($vdata['make']) ->setModelYearFrom($m_year_from) ->setModelYearTo($m_year_to); $em->persist($vehicle); } else { $vehicle = $this->v_index[$brand_name][$vdata['make'] . '|' . intval($m_year_from) . '|' . intval($m_year_to)]; } // battery $vdata['battery']->addVehicle($vehicle); // $vehicle->addBattery($vdata['battery']); // update our data for battery linking $vehicle_index[$row_num] = $vehicle; } $em->flush(); } $em->flush(); return 0; } }