addHelperPath('App/License/View/Helper/', 'App\License\View\Helper\\'); return parent::_init(); } public function exec() { $this->_initStep(); return parent::exec(); } protected function _initStep() { $this->step = $this->_doc->getOption('xStep'); if (!in_array($this->step, array_column($this->getSteps(), 'name'))) { throw new Exception('Unknown step "' . $this->step . '"'); } if (self::STEP_VERIFICATION == $this->step && !Qs_Request::isXmlHttpRequest()) { $this->getEventManager()->attach('contentReady', [$this, 'onVerificationStepContentReady']); $this->getEventManager()->attach('isValidStep', [$this, 'onValidVerificationStep']); } if (self::STEP_LICENSE == $this->step && !Qs_Request::isXmlHttpRequest()) { $this->getEventManager()->attach('initPlaceholders', [$this, 'onInitLicenseStepPlaceholders']); } return $this; } protected function _doStepAjax() { if (!$this->isPreviousStepCompleted()) { $this->_displayJson([ 'isValid' => false, 'formErrors' => [$this->getConfig('msgInternalError')], ]); } $form = $this->getStepForm(Qs_Request::getPost()); $response = $form->validateAjax(); $this->_displayJson($response); } protected function _doStep() { if (($vendorId = $this->_doc->getAuthData('vendorId')) && !(self::ACTION_RENEW == $this->getSessionOption('action')) && $this->_getDataObj()->getModel()->hasApprovedLicense($vendorId) ) { $this->_setBackUrl(User\View::getPage('url')); $this->_setBackError($this->getConfig('errorAlreadyHasApproveLicense')); $this->_doBack(); return $this; } if ($this->step == self::STEP_USER && $this->_doc->getAuthData('id')) { $this->redirectToStep(self::STEP_NAICS); } if (!$this->isPreviousStepCompleted()) { $this->redirectToStep($this->getPreviousStepName()); } if (Qs_Request::isGet()) { $this->getEventManager()->trigger('initData'); } $content = $this->renderStepContent(); $this->getEventManager()->trigger('contentReady', null, ['content' => &$content]); $placeholders = [ 'stepProgress' => $this->renderProgressBar(), 'stepTitleBar' => $this->renderStepTitle(), 'stepContent' => $content, ]; if (Qs_Request::isGet()) { $this->getEventManager()->trigger('initPlaceholders', null, ['placeholders' => &$placeholders]); } $this->_doc->setModulePlaceholders($this->getOption('type'), $placeholders); return $this; } protected function renderStepContent() { if (self::STEP_LICENSE == $this->step) { return $this->renderLicenseContent(); } $data = Qs_Request::isPost() ? Qs_Request::getPost() : $this->getStepData(); $form = $this->getStepForm($data); $form->setDefaults(); if (Qs_Request::isPost() && $form->validate()) { $data = $form->getValues(); $this->getEventManager()->trigger('isValidStep', null, ['data' => &$data]); $this->saveStepData($this->step, $data); $this->_getDataObj()->handleFiles(); if (($nextStep = $this->getNextStepName())) { $this->redirectToStep($nextStep); } } return $form->render(); } protected function renderLicenseContent() { if (!($licenseId = $this->getStepData(self::STEP_VERIFICATION, 'id'))) { $this->redirectToStep(self::STEP_VERIFICATION); } $item = [ 'receiptFile' => PdfView::getReceiptUrl($licenseId), 'accountUrl' => (new UserAuth())->getDefaultBackUrl(), 'tpl' => $this->getTemplate('vendor-license-step.tpl'), ]; return $this->_doc->fetchItem($item); } protected function getSteps() { if (null === $this->steps) { $this->getTraitSteps(); $disabledSteps = []; if ($this->getSessionOption('action') == self::ACTION_RENEW || $this->_doc->getAuthData('id')) { $disabledSteps = [self::STEP_USER, self::STEP_VENDOR, self::STEP_QUESTIONNAIRE]; } // Don't allow to go back on the license step if ($this->step == self::STEP_LICENSE) { $disabledSteps = array_column($this->steps, 'name'); } foreach ($this->steps as $index => &$step) { $step['enabled'] = !in_array($step['name'], $disabledSteps); } } return $this->steps; } protected function isPreviousStepCompleted() { if (false === ($previousStep = $this->getPreviousStepName())) { return true; } if (($this->getSessionOption('action') == self::ACTION_RENEW || $this->_doc->getAuthData('id')) && in_array($previousStep, [self::STEP_USER, self::STEP_VENDOR, self::STEP_QUESTIONNAIRE]) ) { return true; } $data = $this->getStepData($previousStep); return !empty($data); } protected function redirectToStep($step) { $this->redirect(self::getStepUrl($step)); return $this; } public static function getStepUrl($step) { if (false === ($page = Qs_SiteMap::findFirst(['xStep' => $step], ['type' => 'License\\']))) { throw new Exception('Can not find "' . $step . '" step url'); } return $page['url']; } protected function getStepForm(array $defaults = []) { if (null !== $this->form) { return $this->form; } $options = []; $options['class'] = 'step' . ucfirst($this->step); if (($previousStep = $this->getPreviousStepName($this->step)) && $this->getStep($previousStep, 'enabled') && ($url = self::getStepUrl($previousStep)) ) { $options['cancelUrl'] = $url; } if (!($className = $this->getCurrentStep('form'))) { throw new Exception('Step (' . $this->step . ') form is not defined'); } $options = array_merge($this->_getFormOptions(), $options); $options['defaults'] = $defaults; $form = new $className($options); if ($form instanceof VendorNaicsForm && ($naicsCodes = $form->getElement('naicsCodes'))) { $query = Qs_Request::getRequestValue('query'); $value = Qs_Array::get($defaults, 'naicsCodes', []); $naicsCodes->setAttrib('codes', $this->_getDataObj()->getNaicsCodes(null, $query)); $naicsCodes->setAttrib('chosenCodes', $this->_getDataObj()->getNaicsChosenCodes($value)); $naicsCodes->setAttrib('htmlAfterElement', $this->renderPaymentSummary()); } if ($form instanceof PaymentForm && ($element = $form->getElement('paymentSummary'))) { $element->setAttrib('html', $this->renderPaymentSummary()); } $this->form = $form; return $this->form; } protected function getPartRenderingForm(array $defaults = []) { return $this->getStepForm($defaults); } protected function _getFormOptions($type = null) { $options = parent::_getFormOptions($type); switch ($this->step) { case self::STEP_QUESTIONNAIRE: $options['questions'] = $this->_getDataObj()->getQuestions(); break; case self::STEP_PAYMENT: $options['bankApiUrl'] = BankApiView::getPage('fullAlias'); break; case self::STEP_VERIFICATION: $options['payment'] = $this->getStepData(self::STEP_PAYMENT); $options['payment']['summary'] = $this->getPaymentSummary(); break; default: break; } return $options; } protected function renderStepTitle() { $step = $this->getCurrentStep(); $title = $this->step == self::STEP_LICENSE ? $step['title'] . ' #' . $this->getStepData(self::STEP_VERIFICATION, 'id') : $step['title']; $item = [ 'currentStep' => $step, 'currentStepTitle' => $title, 'stepsCount' => count($this->getSteps()), 'tpl' => $this->getTemplate('step-title-bar.tpl'), ]; return $this->_doc->fetchItem($item); } protected function getPaymentSummary() { return $this->_getDataObj()->getPaymentSummary('y' == $this->getVendor('preferredVendor')); } protected function getVendor($field = null) { static $vendor; if (($vendorId = $this->_doc->getAuthData('vendorId'))) { if (null === $vendor) { $vendor = $this->_getDataObj()->getVendorModel()->get($vendorId); } return Qs_Array::get($vendor, $field); } $data = $this->getStepData(self::STEP_VENDOR); $this->_getDataObj()->getVendorModel()->mapCollections($data); return Qs_Array::get($data, $field); } protected function renderPaymentSummary() { $naicsCodes = $this->getStepData(self::STEP_NAICS, 'naicsCodes'); $item = [ 'summary' => $this->getPaymentSummary(), 'hidden' => empty($naicsCodes), 'tpl' => $this->getTemplate('payment-summary.tpl'), ]; return $this->_doc->fetchItem($item); } /** * @param Event $event * @return void */ public function onVerificationStepContentReady(Event $event) { $params = $event->getParams(); $params['content'] = $this->renderVerificationStepContent() . $params['content']; } public function renderVerificationStepContent() { $naicsCodes = $this->getStepData(self::STEP_NAICS, 'naicsCodes'); $item = [ 'vendor' => $this->getVendor(), 'paymentSummary' => $this->getPaymentSummary(), 'naicsCodes' => $this->_getDataObj()->getNaicsChosenCodes($naicsCodes), 'tpl' => $this->getTemplate('verification-step.tpl'), ]; $html = $this->_doc->fetchItem($item); return $html; } /** * @param Event $event * @return void * @throws Exception */ public function onValidVerificationStep(Event $event) { $params = $event->getParams(); // init data $payment = $this->getStepData(self::STEP_PAYMENT); $license = $this->createLicenseEntity(); try { Qs_Db::getInstance()->beginTransaction(); $modelOptions = ['db' => Qs_Db::getInstance(), 'transactionEnabled' => false]; if ($this->_doc->getAuthData('id')) { $user = $this->_doc->getAuthData(); $vendor = $this->getVendor(); } else { $user = $this->createUserEntity(); //Add Vendor $vendorModel = new VendorModel($modelOptions); $vendor = $this->createVendorEntity(); $user['vendorId'] = $vendorModel->insert($vendor); // Add User $userModel = new UserModel($modelOptions); // save and restore password since it changes to hash inside insert method $password = $user['password']; $userModel->insert($user); $user['password'] = $password; } $license['userId'] = $user['id']; $license['vendorId'] = $user['vendorId']; // Save License $model = new Model($modelOptions); if (self::ACTION_RENEW == $this->getSessionOption('action')) { $params['data']['id'] = $license['id'] = $licenseId = $this->getSessionOption('id'); $model->update($license, $licenseId); } else { $params['data']['id'] = $license['id'] = $licenseId = $model->insert($license); } // Process Payment $payment['total'] = $this->getPaymentSummary()['total']; $transactionId = $this->processPayment('Lic. #' . $licenseId, $payment, $user, $vendor); $this->_getDataObj()->setTransactionId($transactionId, $licenseId); Qs_Db::getInstance()->commit(); // Finalize $this->notify($licenseId); if (!$this->_doc->getAuth()->isLoggedIn()) { $this->autologin($user); } $this->clearStepData([ self::STEP_USER, self::STEP_VENDOR, self::STEP_QUESTIONNAIRE, self::STEP_NAICS, self::STEP_PAYMENT, ]); $this->clearSessionOptions(); return; } catch (UserModelException $e) { $this->_setBackUrl(self::getStepUrl(self::STEP_USER)); } catch (IntegrityPaymentException $e) { $this->_setBackUrl(self::getStepUrl(self::STEP_PAYMENT)); $this->_setBackError($e->getMessage()); } catch (SpsException $e) { $this->_setBackUrl(self::getStepUrl(self::STEP_PAYMENT)); $this->_setBackError('SPS Error: ' . $e->getMessage()); } Qs_Db::getInstance()->rollBack(); $this->_doBack(); } private function createLicenseEntity() { $license = [ 'naicsCodes' => $this->getStepData(self::STEP_NAICS, 'naicsCodes'), 'ip' => Qs_Request::getClientIP(), ]; $stepData = Qs_Array::excludeKey($this->getStepData(self::STEP_PAYMENT), 'confirmAccountNumber'); $license = array_merge($license, $stepData, $this->getPaymentSummary()); $this->maskPaymentData($license); $licenseStartTime = time(); if (self::ACTION_RENEW == $this->getSessionOption('action') && ($licenseId = $this->getSessionOption('id'))) { if (!($expiredOn = $this->_getDataObj()->get($licenseId, 'expiredOn'))) { throw new Exception('Expiration Date is not defined'); } $licenseStartTime = strtotime($expiredOn); $license['activeExpiredOn'] = $expiredOn; } $license['status'] = Entity::STATUS_ACTIVE; $license['expiredOn'] = date( 'Y-m-d', strtotime('+' . SettingsObj::get('licenseDuration') . ' months', $licenseStartTime)); $tribeIds = array_keys(TribeObj::getPairs()); foreach ($tribeIds as $tribeId) { $license['tribes'][$tribeId] = [ 'tribeId' => $tribeId, 'status' => Entity::TRIBE_STATUS_PENDING, ]; } return $license; } private function createUserEntity() { $user = $this->getStepData(self::STEP_USER); unset($user['captcha']); $user['bought'] = 'y'; $user['status'] = UserEntity::STATUS_ACTIVE; return $user; } private function createVendorEntity() { $vendor = $this->getStepData(self::STEP_VENDOR); $vendor['questionnaire'] = $this->getStepData(self::STEP_QUESTIONNAIRE, 'questionnaire'); return $vendor; } /** * @param Event $event * @return void */ public function onInitLicenseStepPlaceholders(Event $event) { $params = $event->getParams(); $licenseId = $this->getStepData(self::STEP_VERIFICATION, 'id'); $license = $this->_getDataObj()->setPrimaryKey($licenseId)->getData(); $params['placeholders']['paidByCheck'] = $license['paymentMethod'] == Entity::PAYMENT_METHOD_CHECK; $params['placeholders']['expiredOn'] = date('m/d/Y', strtotime($license['expiredOn'])); } private function notify($licenseId) { if (self::ACTION_RENEW == $this->getSessionOption('action')) { Mail::sendLicenseRenewedToAdmin($licenseId); Mail::sendLicenseRenewedToUser($licenseId); } else { Mail::sendLicenseSubmittedToAdmin($licenseId); Mail::sendLicenseSubmittedToBackgroundScreeningCompany($licenseId); Mail::sendLicenseSubmittedToUser($licenseId); LibraryMail::sendLibraryUpdatedToUser(LibraryObj::RECORD_TYPE_LICENSE, $licenseId); } return $this; } /** * @param array $user * @return void * @throws \Qs_Doc_Exception */ private function autologin(array $user) { $userAuth = $this->_doc->getAuth(); $authAdapter = new UserAuthAdapter(); $authAdapter->setIdentity($user['email'])->setCredential($user['password']); $userAuth->authenticate($authAdapter); UserIpObj::saveUserIP($this->_doc->getAuthData('id'), $_SERVER['REMOTE_ADDR']); } public function setSessionOptions(array $options) { $session = $this->getSession(); $session->options = $options; return $this; } public function clearSessionOptions() { $session = $this->getSession(); unset($session->options); return $this; } public function getSessionOption($field, $default = null) { $session = $this->getSession(); if (!isset($session->options)) { return $default; } if (!isset($session->options[$field])) { return $default; } return $session->options[$field]; } }