'Ads/Builders', self::SECTION_SUBWAYS => 'Ads/Subways', self::SECTION_REGIONS => 'Ads/Regions', self::SECTION_ROOMTYPES => 'Ads/RoomTypes', self::SECTION_FLATTYPES => 'Ads/FlatTypes', self::SECTION_BANKS => 'Ads/Banks', self::SECTION_BANK_PROGRAMS => 'Ads/BankPrograms', self::SECTION_BANK_PROGRAM_RATES => 'Ads/BankProgramRates', self::SECTION_CLASSES => 'Ads/Classes', self::SECTION_BLOCKS => 'Ads/Blocks', self::SECTION_BUILDINGS => 'Ads/Buildings', self::SECTION_APARTMENTS => 'Ads/Apartments', self::SECTION_BLOCKSUBWAYS => 'Ads/BlockSubways', self::SECTION_MORTGAGES => 'Ads/Mortgages' ]; private $filename = ''; private $builders = []; private $currentPath = []; public function setBuilder($sectionId, ModelBuilder $builder) { assert('isset(self::$sectionsXpath[$sectionId])'); $this->builders[$sectionId] = $builder; } /** * @var ImporterService */ private $importerService; public function __construct($filename) { if (!is_file($filename)) { throw new Exception('File not found'); } $this->importerService = new ImporterService(); $this->filename = $filename; } private function getAttributesArray(\XmlReader $reader) { $attrs = []; while ($reader->moveToNextAttribute()) { $attrs[$reader->localName] = $reader->value; } return $attrs; } private function getNextSection(\XmlReader $reader) { $sectionsByXpaths = array_flip(self::$sectionsXpath); if ($reader->nodeType == \XmlReader::END_ELEMENT) { $this->closeElement($reader->localName); } while ($reader->read()) { switch ($reader->nodeType) { case \XMLReader::ELEMENT: $this->currentPath[] = $reader->localName; $curPath = implode('/', $this->currentPath); if (isset($sectionsByXpaths[$curPath])) { return $sectionsByXpaths[$curPath]; } break; case \XMLReader::END_ELEMENT: $this->closeElement($reader->localName); break; } } return 0; } private function closeElement($elementName) { while ($this->currentPath && array_pop($this->currentPath) !== $elementName); } private function getElements(\XmlReader $reader, ModelBuilder $builder) { $newElementsCount = 0; $count = 0; while ($reader->read() && $reader->nodeType != \XmlReader::END_ELEMENT) { if ($reader->nodeType == \XmlReader::ELEMENT) { $model = $builder->getModel($data = $this->getAttributesArray($reader)); assert('$model instanceof ImportRecord'); // price history for nb charts if ($model instanceof Apartment) { if ($ap_model = Apartment_sale::findOne((int)$data['id'])) { if ($ap_model->meter_price != (int)$data['metrecostbase']) { $sql = "INSERT INTO price_history (ap_id, discount_meter_price, created_at) VALUES ('" . $ap_model->id . "', '" . $ap_model->discount_meter_price . "', '" . $ap_model->updated_at . "')"; try { mysql_query($sql); } catch (Exception $e) { echo $e->getMessage(); return false; } $ap_model->discount_meter_price = (int)$data['metrecostwithdiscounts']; // $ap_model->updated_at = date('Y-m-d H:i:s'); } $ap_model->save(); } else { $ap_model = new Apartment_sale; $ap_model->id = $data['id']; $ap_model->block_id = (int)$data['blockid']; $ap_model->building_id = (int)$data['buildingid']; $ap_model->room_type_id = (int)$data['rooms']+1; $ap_model->space_total = Convertor::strToFloat($data['stotal']); $ap_model->height = Convertor::strToFloat($data['height']); $ap_model->number = $data['number']; $ap_model->section = $data['section']; $ap_model->base_price = (int)$data['flatcostbase']; $ap_model->meter_price = (int)$data['metrecostbase']; $ap_model->price = (int)$data['flatcostwithdiscounts']; $ap_model->discount_price = (int)$data['flatcostwithdiscounts']; $ap_model->discount_meter_price = (int)$data['metrecostwithdiscounts']; $ap_model->space_kitchen = $data['skitchen']; $ap_model->space_corridor = $data['scorridor']; $ap_model->space_room = $data['sroom']; $ap_model->space_balcony = $data['sbalcony']; $ap_model->space_watercloset = $data['swatercloset']; $ap_model->flat_type_id = (int)$data['flattypeid']+1; $ap_model->decoration_id = DecorationType::getIdByName($data['decoration']); $ap_model->subsidy = (int)$data['subsidy']; $ap_model->creditend = (int)$data['creditend']; $ap_model->flat_floor = (int)$data['flatfloor']; $ap_model->save(); } } // price history for nb charts END $isNew = $model->getIsNewRecord(); if ($model->save()) { if ($isNew) { ++$newElementsCount; } ++$count; } else { echo 'Cannt save model!'; //print_r($model->attributes); //print_r($model->errors); } } } return [$newElementsCount, $count]; } public function loadData(Callable $afterSectionLoad=null) { $reader = new \XmlReader(); $reader->open($this->filename); $this->importerService->setStatus(1); $this->importerService->setForceImport(0); try { while($sectionId = $this->getNextSection($reader)) { if (!isset($this->builders[$sectionId])) { continue; } $builder = $this->builders[$sectionId]; $modelClass = $builder->getModelClassName(); $startTime = time(); // на случай если все произошло очень быстро sleep(1); list($newElementsCount, $count) = $this->getElements($reader, $builder); $wastedTime = time() - $startTime; $model = new $modelClass(); $delElementsCount = null; if ($model instanceof Apartment) { $cond = '(UNIX_TIMESTAMP(updated_at) > 0 AND UNIX_TIMESTAMP() - UNIX_TIMESTAMP(updated_at) > ' .$wastedTime . ') or (UNIX_TIMESTAMP(updated_at) = 0 and UNIX_TIMESTAMP() - UNIX_TIMESTAMP(created_at) > ' .$wastedTime . ')'; $result = mysql_query("SELECT * FROM apartments WHERE ".$cond); $data = []; while ($obj = mysql_fetch_assoc($result)) { $sql = "UPDATE apartments_sales SET is_sold=1 WHERE id='" . $obj['id']."'"; try { mysql_query($sql); } catch (Exception $e) { echo $e->getMessage(); return false; } } $delElementsCount = $modelClass::deleteAll($cond); } if ($afterSectionLoad) { $afterSectionLoad($modelClass, $wastedTime, $newElementsCount, $delElementsCount, $count); } } } catch (\Exception $e) { //todo log error echo $e; } finally { $this->importerService->setStatus(0); $reader->close(); } } }