[ 'friendlyName' => 'API Key', 'validators' => [ 'required' => 'required', ] ], 'api_secret' => [ 'friendlyName' => 'API Secret', 'type' => 'password', 'validators' => [ 'required' => 'required', ] ], 'test' => [ 'friendlyName' => 'Test Mode', 'type' => 'yesno', ], ]; public $availableTypes = ['A', 'AAAA', 'ANAME', 'NS', 'MX', 'CNAME', 'SPF', 'SRV', 'TXT', 'PTR','HTTPRED']; private $domain_id; const API_BASE_URL = 'http://api.dnsmadeeasy.com/V2.0/'; const API_BASE_URL_TEST = 'http://api.sandbox.dnsmadeeasy.com/V2.0/'; public function testConnection() { $info = $this->_get('dns/managed/'); if( !isset($info['data']) ) { throw new exceptions\DNSSubmoduleException('Unknown Error', dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } } public function zoneExists() { if( $this->domain_id() > 0 ) { $result = $this->_get('dns/managed/' . $this->domain_id()); if( $result['id'] > 0 ) { return true; } } return false; } public function getRecords( $recordType = false ) { $result = $this->_get('dns/managed/' . $this->domain_id() . '/records'); $out = []; foreach( $result['data'] as $data ) { if( in_array((string)$data['type'], $recordType ? [strtoupper($recordType)] : $this->getAvailableRecordTypes(), true) ) { $record = new dns\record\Record(); $record->line = (string)$data['id']; $record->name = (string)$data['name']; $record->type = (string)$data['type']; $record->ttl = (string)$data['ttl']; $record->createRDATAObject(); switch( (string)$data['type'] ) { case 'MX': $record->rdata->preference = (string)$data['mxLevel']; $record->rdata->exchange = (string)$data['value']; break; case 'HTTPRED': $record->rdata->link = $data['value']; $record->rdata->title = $data['title']; $record->rdata->keywords = $data['keywords']; $record->rdata->redirecttype = $data['redirectType']; $record->rdata->hardlink = (int)$data['hardLink']; break; case 'SRV': $record->rdata->setDataFromArray($data); $record->rdata->target = (string)$data['value']; default: $record->rdata->setFirstProperty((string)$data['value']); break; } $out[] = $record; } } return $out; } private function recordToParamsArray( dns\record\Record $record ) { $params = [ 'name' => str_replace('@', '', $record->nameToRelative($this->domain)), 'ttl' => $record->ttl, 'type' => $record->type ]; switch( $record->type ) { case 'PTR': $params['value'] = trim($record->rdata->ptrdname, '.') . '.'; break; case 'MX': $params['mxLevel'] = $record->rdata->preference; $params['value'] = $this->makeAbsolute($record->rdata->exchange); break; case 'HTTPRED': $params['title'] = $record->rdata->title; $params['keywords'] = $record->rdata->keywords; $params['redirectType'] = $record->rdata->redirecttype; $params['hardLink'] = (bool)$record->rdata->hardlink; $params['value'] = $record->rdata->link; break; case 'SRV': $params = array_merge($record->rdata->toArray()); $params['value'] = $record->rdata->target; $params['ttl'] = $record->ttl; $params['type'] = $record->type; break; case 'NS': $params['value'] = $this->makeAbsolute($record->rdata->nsdname); break; case 'ANAME': $params['value'] = $this->makeAbsolute($record->rdata->aname); break; case 'CNAME': $params['value'] = $this->makeAbsolute($record->rdata->cname); break; default: $params['value'] = $record->rdata->toString(); break; } return $params; } public function addRecord( dns\record\Record $record ) { $params = $this->recordToParamsArray($record); $this->_post('dns/managed/' . $this->domain_id() . '/records/ ', $params); } public function editRecord( dns\record\Record $record ) { $params = $this->recordToParamsArray($record); $params['gtdLocation'] = "DEFAULT"; $params['id'] = $record->line; $this->_put('dns/managed/' . $this->domain_id() . '/records/' . $record->line . '/', $params); } public function deleteRecord( dns\record\Record $record ) { $this->_delete('dns/managed/' . $this->domain_id() . '/records/' . $record->line); } public function activateZone() { $input = [ 'names' => [$this->domain], ]; $this->_post('dns/managed', $input); } public function terminateZone() { $this->_delete('dns/managed', [$this->domain_id()]); } private function _get( $operation ) { return $this->_curl($operation, 'GET'); } private function _delete( $operation, $data = [] ) { return $this->_curl($operation, 'DELETE', $data); } private function _put( $operation, $data = [] ) { return $this->_curl($operation, 'PUT', $data); } private function _post( $operation, $data = [] ) { return $this->_curl($operation, 'POST', $data); } private function _curl( $operation, $method, $postData = null ) { $url = ($this->config['test'] == 'on' ? self::API_BASE_URL_TEST : self::API_BASE_URL) . $operation; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //curl_setopt($ch, CURLOPT_HEADERFUNCTION, array($this, '_headerCallback')); curl_setopt($ch, CURLOPT_HTTPHEADER, $this->_requestHeaders()); if( $method === 'POST' || $method === 'DELETE' ) { foreach( $postData as $key => $value ) { if( in_array($key, ['PRIORITY', 'WEIGHT', 'PORT', 'TARGET'], true) ) { if( $key === 'TARGET' ) { unset($postData['TARGET']); } else { $postData[strtolower($key)] = $value; } unset($postData[$key]); } } curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); } elseif( $method === 'PUT' ) { curl_setopt($ch, CURLOPT_HTTPHEADER, // Ask the remote end to PUT, curl won't PUT a raw body array_merge(['X-HTTP-Method-Override: PUT'], $this->_requestHeaders())); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); } curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // reset the header values $this->_headers = []; $apiResponse = curl_exec($ch); if( curl_errno($ch) ) { throw new exceptions\DNSSubmoduleException("cURL Error: " . curl_errno($ch) . " - " . curl_error($ch), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } if( empty($apiResponse) ) { $apiResponse = '[]'; } $apiResponse = preg_replace('/([{,]+)(\s*)([^"]+?)\s*:/', '$1"$3":', $apiResponse); //key => "key" $result = json_decode($apiResponse, true); if( !is_array($result) ) { throw new exceptions\DNSSubmoduleException('Unable to parse response (' . $apiResponse . ')', dns\SubmoduleExceptionCodes::INVALID_RESPONSE); } $ci = curl_getinfo($ch); if( !empty($result['error']) || strpos($ci['http_code'], '2') !== 0 ) { throw new exceptions\DNSSubmoduleException($result['error'][0] ? : 'Unknown Error', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } return $result; } private function _requestHeaders() { $requestDate = gmdate('r'); return [ "x-dnsme-apiKey: {$this->config['apikey']}", "x-dnsme-requestDate: $requestDate", "x-dnsme-hmac: " . $this->_hash($requestDate), 'content-type:application/json', 'accept:application/json', ]; } private function _hash( $requestDate ) { return hash_hmac('sha1', $requestDate, $this->config['api_secret']); } private function domain_id() { if( isset($this->domain_id) ) { return $this->domain_id; } $info = $this->_get('dns/managed/'); foreach( $info['data'] as $value ) { if( $value['name'] === $this->domain ) { $this->domain_id = $value['id']; return $value['id']; } } } public function getZones() { $out = []; $info = $this->_get('dns/managed/'); foreach( $info['data'] as $value ) { $out[$value['name']] = ''; } return $out; } /** * @param $name * * @return string */ private function makeAbsolute( $name ) { return rtrim($name, '. ') . '.'; } }