/** * * @param string $filename */ public function uploadBulk($filename) { // Open file if (!stat($filename)) { throw new \Application\Exceptions\UnexpectedException("Error opening file {$filename}"); } $fd = fopen($filename, 'r'); $sep = \App_Parser_CsvParser::getCsvSeparator($fd); // Request $sims = array(); $validator = new SimBulkValidate(); $validHeaders = $this->getUploadBulkHeaders(); $filter = \Zend_Controller_Action_HelperBroker::getStaticHelper('FilterNotAllowedFields'); // CSV $header = fgetcsv($fd, 0, $sep); // Header $prows = 0; // Packet rows $irows = 1; // Iteration rows $nrows = 1; // Total rows $ncols = count($header); // Total columns $validH = false; foreach ($header as $h) { if (isset($validHeaders[$h])) { $validH = true; break; } } // Check lines readed if (!$validH) { \App::log()->debug("[UpdateBulk] No valid headers"); throw new ValidateException("No valid headers", ValidationCodes::FILE_NO_VALID_HEADERS); } if (in_array('locationManual_latitude', $header) && !in_array('locationManual_longitude', $header) || in_array('locationManual_longitude', $header) && !in_array('locationManual_latitude', $header)) { \App::log()->debug("[UpdateBulk] No valid headers: location requires latitude and longitude"); throw new ValidateException("No valid headers: location requires latitude and longitude", ValidationCodes::FILE_NO_VALID_HEADERS_LOCATION); } $bulkCount = \App::config('ericssonserviceCallItemCount', self::BULK_UPDATE_DEFAULT); // I'm not sure... I don't like it. set_time_limit(0); $watcher = $this->getMapper()->createFileWatcher(); $txId = uniqid("bulk"); $watcher->entityIds = array($txId); $watcher->params->action = "bulkSimUpdate"; WatcherService::getInstance()->create($watcher); $errors = array(); $warnings = array(); $ntxs = 0; // Rows while (($line = fgetcsv($fd, 0, $sep)) !== false) { // Next line has been readed $nrows++; // Check columns if (count($line) !== $ncols) { $errors[] = new Model\ErrorModel(array('line' => $nrows, 'description' => "Incorrect format (number of columns)", 'level' => Model\ErrorModel::ERROR_LEVEL_ERROR, 'code' => ValidationCodes::FILE_READING_ERR)); continue; } // Create sim $data = array(); foreach ($header as $key => $name) { // \App::log()->debug("[UpdateBulk] $name : $key"); if (!isset($validHeaders[$name])) { // Ignore invalid columns // \App::log()->warn("[UpdateBulk] Ignoring $name column"); continue; } $value = $line[$key]; if (preg_match('/^=\\"(?P<value>.*)\\"$/', $value, $matches)) { $value = $matches['value']; } // GLOBALPORTAL-28668 // if (!empty($value)) { // \App::log()->debug("[UpdateBulk] $name : $value"); if (isset($value) && (!empty($value) || is_numeric($value))) { // \App::log()->debug("[UpdateBulk] TRUE $name : $value"); // Remove field? // See SimBaseMapper _mapModelToEricssonModel method, // SimValidate and App_Validate_ReferenceIndex to understand it if ($value === '-' && $name !== 'staticIpApnIndex') { $value = ''; } // Process field if (strpos($name, 'apn_') !== false) { // In order to remove the current value of a SIM´s field, // the character - must be indicated $index = (int) substr($name, strlen('apn_apn')) - 1; $data['apns'][$index] = $value; } else { if (strpos($name, 'locationManual_') !== false) { $value = str_replace(',', '.', $value); if (!is_numeric($value)) { $warnings[] = new Model\ErrorModel(array('line' => $nrows, 'column' => $name, 'description' => "Invalid value", 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => ValidationCodes::INVALID_VALUE)); } else { $subname = substr($name, strlen('locationManual_')); $value = floatval(str_replace(',', '.', $value)); $data['locationManual'][$subname] = (int) round($value * pow(10, 6)); } } else { if ($name == 'LTE_status') { if ($value != SimModel::LTE_ACTIVE && $value != SimModel::LTE_INACTIVE) { $warnings[] = new Model\ErrorModel(array('line' => $nrows, 'column' => $name, 'description' => "Invalid value", 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => ValidationCodes::INVALID_VALUE)); } else { $data['lteEnabled'] = $value == SimModel::LTE_ACTIVE ? true : false; } } else { $data[$name] = $value; } } } } } // Create and validate sim $sim = new SimModel($data); $v = $this->validate($sim, false, $validator); if ($v === true) { // Backup id $ids = $sim->getIds(); $type = key($ids); $value = current($ids); //Inject organization $org = \App::getOrgUserLogged(); switch ($org->getType()) { case OrgMasterModel::ORG_TYPE: $sim->setMaster($org); break; case OrgServiceProviderModel::ORG_TYPE: $sim->setServiceProviderCommercial($org); $sim->setServiceProviderEnabler($org); break; case OrgCustomerModel::ORG_TYPE: $sim->setCustomer($org); break; case OrgAggregatorModel::ORG_TYPE: $sim->setAggregator($org); break; case OrgEndUserModel::ORG_TYPE: $sim->setEndUser($org); break; } // Filter by permissions $filter->direct('update_field', $sim); // Recover id and add sim to request $sim->{$type} = $value; $sims[] = $sim; $prows++; } else { \App::log()->warn("[UpdateBulk] Ignoring invalid sim: " . json_encode($v)); // Sending first validation error ONLY? foreach ($validator->getValidationCodes() as $field => $code) { $errors[] = new Model\ErrorModel(array('line' => $nrows, 'description' => $field, 'level' => Model\ErrorModel::ERROR_LEVEL_WARN, 'code' => $code ?: ValidationCodes::MODEL_SIM)); } } // Wait until packet is full if ($prows == $bulkCount) { // Send to Ericsson $this->_uploadBulk($sims, $errors, $irows, $nrows, $watcher); $ntxs++; // Reset packet list $sims = array(); $prows = 0; // Update CSV line position $irows = $nrows + 1; } } // Ensure all sims have been sent (last packet) if (!empty($sims)) { // Send to Ericsson $this->_uploadBulk($sims, $errors, $irows, $nrows, $watcher); $ntxs++; // Reset packet list (memory propouses) $sims = array(); } // Check lines readed if ($nrows < 2) { \App::log()->debug("[UpdateBulk] Ignoring empty file"); $watcher->delete(); throw new ValidateException("Missing file rows"); } $event = $this->getMapper()->constructEventToTransaction(); $event->entityId = $txId; // Add error code suffix if (isset($errors) && is_array($errors)) { foreach ($errors as $errMess) { require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php'; $errMess->code = \ErrorController::finishErrorCode($errMess->code); } } $eventData = array('simParsed' => $nrows - 1); if (!empty($errors) || !empty($warnings)) { $eventData['hasFailures'] = true; if (!empty($errors)) { $eventData['message']['failed'] = $errors; } if (!empty($warnings)) { $eventData['message']['warnings'] = $warnings; } } else { $eventData['hasFailures'] = false; } $event->eventData = $eventData; $compressor = new ErrorModelCompressEvent(); $compressor->compress($event); WatcherService::getInstance()->publishEvent($event); $nerr = count($errors); \App::audit("Bulk update ({$nrows} sims in {$ntxs} requests with {$nerr} errors)", null); return $watcher->reload(); }
public function filesAction() { if (!$this->getRequest()->isPost()) { throw new AppEx\ForbiddenException("Files action must be a post request."); } $front = Zend_Controller_Front::getInstance(); $front->registerPlugin(new \Tid_Zend_Controller_Plugin_UploadMax()); try { $upload = new Zend_File_Transfer('App_File_Transfer_Adapter_HttpMultipartMixed', false, array('ignoreNoFile' => true)); } catch (Zend_File_Transfer_Exception $e) { throw new AppEx\InvalidArgumentException($e->getMessage()); } $upload->addValidator('Count', true, array('min' => 1, 'max' => 1))->addValidator('Extension', true, array('xml', 'csv', 'txt'))->addValidator('MimeType', true, array('application/xml', 'text/plain', 'headerCheck' => true)); if ($upload->isValid()) { if ($upload->receive()) { try { $fileinfo = current($upload->getFileInfo()); $filename = $fileinfo['tmp_name']; // Attempt to parse data from file $parseResult = $this->_stockSrv->getData($filename, $upload->getMimeType()); $data = $parseResult['data']; $errors = $parseResult['errors']; if (!empty($errors) && is_array($errors)) { foreach ($errors as $errMess) { require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php'; $errMess->code = ErrorController::finishErrorCode($errMess->code); } } $method = 'create' . ucfirst($data['_type']); if (!empty($data['_type']) && is_callable(array($this->_stockSrv, $method))) { // Check permissions according to the data type $dumbSim = new Application\Model\SimModel(); $this->_helper->allowed($data['_perm'], $dumbSim); try { $watcher = $this->_stockSrv->{$method}($parseResult); } catch (AppEx\GlobalServiceException $ex) { $ex->addErrorMessages($errors); throw $ex; } $txId = uniqid('parser'); WatcherService::getInstance()->pushEntityId($watcher, $txId); $event = new EventModel(); $event->entityId = $txId; $event->entityType = 'transaction'; $event->namespace = 'connectivity'; $event->eventData = $errors; $event->created = time(); $event->forceFinish = true; WatcherService::getInstance()->publishEvent($event); // WatcherService::getInstance()->setStatus($watcher->id, WatcherModel::STATUS_FINISHED); $errors_ex = $this->_loadErrorsFromWatcher($watcher); if (!empty($errors_ex)) { $errors = Zend_Json::encode($errors_ex); App::log()->warn("Error on file upload in stock:\n" . $errors); throw new AppEx\StockParserException("Some errors uploading file to stock.", array('errorMessages' => $errors_ex)); } } else { throw new AppEx\UnexpectedException('Unknown data type (' . $data['_type'] . ')'); } } catch (PermissionException $e) { throw $e; } catch (StockParserException $e) { throw $e; } catch (GlobalServiceException $e) { $txId = uniqid('parser'); if (!isset($watcher)) { $watcher = $this->_stockSrv->createFileWatcher(); $watcher->entityIds = array($txId); $watcher->params->type = 'sim'; $watcher->params->action = 'stockUpload'; $watcher->save(); } else { WatcherService::getInstance()->pushEntityId($watcher, $txId); } $event = new EventModel(); $event->entityId = $txId; $event->entityType = 'transaction'; $event->namespace = 'connectivity'; $event->created = time(); $event->modified = time(); $event->pushEventData = true; $eventData = array(); $errors = $e->getErrorMessages(); $eventData['hasFailures'] = true; if (!empty($errors) && is_array($errors)) { require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php'; foreach ($errors as $errMess) { if ($errMess instanceof ErrorModel) { $errMess->code = ErrorController::finishErrorCode($errMess->code); } } $eventData['message'] = array('failed' => $errors); } $event->eventData = $eventData; $event->forceFinish = true; $compressor = new ErrorModelCompressEvent(); $compressor->compress($event); WatcherService::getInstance()->publishEvent($event); // WatcherService::getInstance()->setStatus($watcher->id, WatcherModel::STATUS_FINISHED); $errors = $this->_loadErrorsFromWatcher($watcher); if (!empty($errors)) { App::log()->warn("Error on file upload in stock:\n" . Zend_Json::encode($errors)); throw new AppEx\StockParserException("Some errors uploading file to stock.", array('errorMessages' => $errors)); } } } else { throw new AppEx\InvalidArgumentException('Could not receive file'); } } else { throw new AppEx\InvalidArgumentException('Invalid file: ' . implode(', ', $upload->getMessages())); } }
public function editSimList($data) { if ($data) { $mapper = StockMapper::getInstance(); $result = $mapper->editSimListEricsson($data); foreach ($data['list'] as $item) { $sim = new SimModel(array(isset($item['type']) ? $item['type'] : 'icc' => $item['id'])); \App::audit('SIM editing finished successfully', $sim); } if (!empty($result) && is_array($result)) { foreach ($result as $errMess) { require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php'; $errMess->code = \ErrorController::finishErrorCode($errMess->code); } } $watcher = $mapper->constructWatcherToTransaction(); $watcher->params->action = 'stockEditList'; $watcher->params->count = count($data['list']); $txId = uniqid('stockeditlist'); $watcher->entityIds = array($txId); WatcherService::getInstance()->create($watcher); $event = $mapper->constructEventToTransaction(); $event->entityId = $txId; $eventData = array('hasFailures' => false, 'message' => array('failed' => $result)); if (!empty($result)) { $eventData['hasFailures'] = true; } $event->eventData = $eventData; WatcherService::getInstance()->publishEvent($event); return $watcher; } else { throw new AppEx\ValidateException('Invalid SIM list'); } }
public function uploadLegacyAction() { $upload = $this->_helper->uploadFile(); try { // Attempt to parse data from file $parseResult = $this->_stockSrv->getDataLegacy($upload->getFileName(), $upload->getMimeType()); $data = $parseResult['data']; $errors = $parseResult['errors']; $method = 'create' . ucfirst($data['_type']); if (empty($data['_type']) || !is_callable(array($this->_stockSrv, $method))) { throw new AppEx\UnexpectedException('Unknown data type (' . $data['_type'] . ')'); } // Check permissions according to the data type $dumbSim = new Application\Model\SimModel(); $this->_helper->allowed($data['_perm'], $dumbSim); if (!empty($errors) && is_array($errors)) { require_once APPLICATION_PATH . '/modules/default/controllers/ErrorController.php'; foreach ($errors as $errMess) { $errMess->code = ErrorController::finishErrorCode($errMess->code); } } $watcher = $this->_stockSrv->{'create' . ucfirst($data['_type'])}($parseResult); $txId = uniqid('bulk'); WatcherService::getInstance()->pushEntityId($watcher, $txId); $this->_sendBulkEvent($txId, $errors); } catch (PermissionException $e) { throw $e; } catch (StockParserException $e) { throw $e; } catch (GlobalServiceException $e) { $watcher = $this->_fakeWatcherOnParseError($e, $watcher, 'legacy', 'stockUploadLegacy', $errors); } $watcher->reload(); $this->_helper->filterNotAllowedFields('read_field', $watcher); // ExtJS requires the response to be { success: true } $this->view->success = true; $this->view->watcher = $watcher; }