/**
  * Executor
  *
  * @throws UpdateDomainContactTask_Exception
  */
 public function Run($userid = null)
 {
     try {
         $Factory = RegistryModuleFactory::GetInstance();
         $Registry = $Factory->GetRegistryByExtension($this->Domain->Extension);
         $Manifest = $Registry->GetManifest();
         if ($userid && $this->Domain->UserID != $userid) {
             throw new UpdateDomainContactAction_Exception(_("You don't have permissions for manage this domain"), UpdateDomainContactAction_Exception::DOMAIN_NOT_BELONGS_TO_USER);
         }
         $OldContact = $this->Domain->GetContact($this->contact_type);
         if ($this->NewContact && $this->NewContact->UserID != $this->Domain->UserID) {
             throw new UpdateDomainContactAction_Exception(_("You don't have permissions for using this contact"), UpdateDomainContactAction_Exception::CONTACT_NOT_BELONGS_TO_USER);
         }
         $trade = $Manifest->GetRegistryOptions()->ability->trade == '1';
         if ($this->contact_type != CONTACT_TYPE::REGISTRANT || !$trade) {
             try {
                 $Registry->UpdateDomainContact($this->Domain, $this->contact_type, $OldContact, $this->NewContact);
                 return $this->Domain->HasPendingOperation(Registry::OP_UPDATE) ? UpdateDomainContactAction_Result::PENDING : UpdateDomainContactAction_Result::OK;
             } catch (Exception $e) {
                 throw new UpdateDomainContactAction_Exception(sprintf(_("Cannot change contact. Reason: %s"), $e->getMessage()));
             }
         } else {
             // Execute trade when:
             // - Trade invoice is paid
             // - Previous trade failed
             if ($this->Domain->IncompleteOrderOperation == INCOMPLETE_OPERATION::DOMAIN_TRADE || $this->Invoice && $this->Invoice->Status == INVOICE_STATUS::PAID) {
                 $this->Domain->SetContact($this->NewContact, CONTACT_TYPE::REGISTRANT);
                 $this->Domain->IncompleteOrderOperation = null;
                 $extra["requesttype"] = "ownerChange";
                 try {
                     $trade = $Registry->ChangeDomainOwner($this->Domain, 1, $extra);
                     return $this->Domain->HasPendingOperation(Registry::OP_TRADE) ? UpdateDomainContactAction_Result::PENDING : UpdateDomainContactAction_Result::OK;
                 } catch (Exception $e) {
                     $this->Domain->IncompleteOrderOperation = INCOMPLETE_OPERATION::DOMAIN_TRADE;
                     if ($this->Invoice) {
                         $this->Invoice->ActionStatus = INVOICE_ACTION_STATUS::FAILED;
                         $this->Invoice->ActionFailReason = $e->getMessage();
                     }
                     throw new UpdateDomainContactAction_Exception(sprintf(_("Cannot change contact. Reason: %s"), $e->getMessage()));
                 }
             } else {
                 // Issue an invoice for trade operation
                 $invoiceid = $this->Db->GetOne("SELECT * FROM invoices WHERE status=? AND itemid=? AND purpose=?", array(INVOICE_STATUS::PENDING, $this->Domain->ID, INVOICE_PURPOSE::DOMAIN_TRADE));
                 if (!$invoiceid) {
                     $this->Domain->SetExtraField("NewRegistrantCLID", $this->NewContact->CLID);
                     DBDomain::GetInstance()->Save($this->Domain);
                     $Invoice = new Invoice(INVOICE_PURPOSE::DOMAIN_TRADE, $this->Domain->ID, $userid);
                     $Invoice->Description = sprintf(_("%s domain name trade"), $this->Domain->GetHostName());
                     $Invoice->Save();
                     $this->Invoice = $Invoice;
                     return UpdateDomainContactAction_Result::INVOICE_GENERATED;
                 } else {
                     throw new UpdateDomainContactAction_Exception(_("Another domain trade is already initiated"));
                 }
             }
         }
     } catch (Exception $e) {
         throw new UpdateDomainContactAction_Exception($e->getMessage());
     }
 }
 public function OnDomainRenewed(Domain $domain)
 {
     if ((int) $this->Manifest->GetRegistryOptions()->ability->auto_renewal) {
         $domain->SetExtraField('RenewalDate', strtotime("+1 year", $domain->RenewalDate));
     }
 }
 /**
  * Request domain transfer
  *
  * @param string $domain Domain required data: name, pw
  * @param array $extradata Extra fields
  * @return bool Transaction status
  */
 public function TransferRequest(Domain $domain, $extra = array())
 {
     if ($extra['registrant']) {
         $registrant_clid = $extra['registrant'];
     } else {
         $EmptyRegistrant = $this->RegistryAccessible->NewContactInstance(CONTACT_TYPE::REGISTRANT);
         $registrant_clid = $EmptyRegistrant->CLID;
         $domain->SetExtraField('x-gr-trn-registrant', $registrant_clid);
     }
     $new_pw = $this->GeneratePassword();
     $params = array('name' => "{$domain->Name}.{$this->Extension}", "pw" => $this->EscapeXML($extra["pw"]), 'new_pw' => $this->EscapeXML($new_pw), "registrant" => $registrant_clid);
     $response = $this->Request("domain-trans-request", $params);
     $status = $response->Succeed ? REGISTRY_RESPONSE_STATUS::SUCCESS : REGISTRY_RESPONSE_STATUS::FAILED;
     $domain->AuthCode = $new_pw;
     return new TransferRequestResponse($status, $response->ErrMsg, $response->Code);
 }
 /**
  * Register domain.
  * This operation supports pending status. If you return response object with Status = REGISTRY_RESPONSE_STATUS.PENDING, you must return response later during a poll.
  * See IRegistryModuleClientPollable::PollCreateDomain().
  *	 
  * @param Domain $domain
  * @param int $period Domain registration period
  * @param array $extra Extra fields
  * @return CreateDomainResponse
  */
 public function CreateDomain(Domain $domain, $period, $extra = array())
 {
     $params = array('SLD' => $this->MakeNameIDNCompatible($domain->Name), 'TLD' => $this->Extension, 'NumYears' => $period, 'DomainPassword' => $domain->AuthCode ? $domain->AuthCode : rand(100000000, 9999999999.0));
     // IDN tag
     $is_idna = $this->RegistryAccessible->IsIDNHostName($domain->Name);
     if ($is_idna) {
         $params['IDNCode'] = $domain->IDNLanguage;
     }
     // NS
     $nameservers = $domain->GetNameserverList();
     $n = 1;
     foreach ($nameservers as $ns) {
         $params['NS' . $n] = $ns->HostName;
         $n++;
     }
     // Contacts
     $contacts = $domain->GetContactList();
     foreach ($contacts as $t => $contact) {
         $params = array_merge($params, $this->PackContact($contact, $t));
     }
     // TLD specific extra fields
     $params = array_merge($params, $extra);
     // Request enom.com
     $Resp = $this->Request('Purchase', $params);
     if ($Resp->Code == 200) {
         $status = REGISTRY_RESPONSE_STATUS::SUCCESS;
     } elseif ($Resp->Code == 1300 && strtolower($Resp->Data->IsRealTimeTLD) == 'false') {
         $status = REGISTRY_RESPONSE_STATUS::PENDING;
     } else {
         $status = REGISTRY_RESPONSE_STATUS::FAILED;
     }
     $Ret = new CreateDomainResponse($status, $Resp->ErrMsg, $Resp->Code);
     if ($Resp->Succeed) {
         $domain->SetExtraField('OrderID', $Resp->Data->OrderID);
         $Ret->CreateDate = time();
         $Ret->ExpireDate = time() + 86400 * 365 * $period;
         $Ret->AuthCode = (string) $params['DomainPassword'];
     }
     return $Ret;
 }