array ( 'friendlyName' => 'Username', 'validators' => array( 'required' => 'required', ) ), 'password' =>array ( 'friendlyName' => 'User password', 'type'=> 'password', ), 'hash' =>array ( 'friendlyName' => 'Access key', 'type'=> 'textarea', ), 'hostname' =>array ( 'friendlyName' => 'Hostname/IP', 'validators' => array( 'required' => 'required', ) ), 'ssl' =>array ( 'friendlyName' => 'Enable SSL', 'type'=> 'yesno', ), 'default_ip' =>array ( 'friendlyName' => 'Default IP', 'validators' => array( 'required' => 'required', 'pattern' => Patterns::IP4_OR_IP6, ) ), 'allow_create' =>array ( 'friendlyName' => 'In cPanel Zones', 'type' => 'yesno', 'help' => 'Allow to create zones when already in CPanel as account', ), 'template' =>array ( 'friendlyName' => 'Template', ), ); public $availableTypes = array('A', 'AAAA', 'NS', 'MX', 'CNAME', 'DNAME', 'LOC', 'TXT', 'SRV', 'PTR', 'AFSDB', 'NAPTR', 'RP'); public function testConnection() { try { $this->get('listaccts'); return true; } catch (exceptions\DNSSubmoduleException $e) { $this->get('listzones', array(), true); return true; } } public function getRecords($recordType = false) { $out = $this->get('dumpzone', array( 'domain' => $this->domain )); $return = array(); if(isset($out->result->record)){ foreach($out->result->record as $r) { if(in_array((string)$r->type, $recordType!==false ? array(strtoupper($recordType)) : $this->getAvailableRecordTypes())) { $return[] = dns\record\Record::tryToCreateFromArray((array)$r); } } } else { throw new exceptions\DNSSubmoduleException('Unable to fetch records from server', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } return $return; } public function addRecord(dns\record\Record $record) { $input = $record->toMergedArray(false); $input['domain'] = $this->domain; $input['name'] = $record->nameToAbsolute($this->domain); $this->get('addzonerecord', $input); return true; } public function editRecord(dns\record\Record $record) { $records = $this->getRecords(); if(empty($records)) return false; $lines = array(); foreach($records as $r) { $lines[$r['line']] = $r; } if(!isset($lines[$record['line']]) || !$record->isEqualTo($lines[$record['line']])) { $input = $record->toMergedArray(false); $input['domain'] = $this->domain; $input['name'] = $record->nameToAbsolute($this->domain); $this->get('editzonerecord', $input); } } public function deleteRecord(dns\record\Record $record) { $this->get('removezonerecord', array( 'zone' => $this->domain, 'line' => $record['line'] )); } public function zoneExists() { try { $out = $this->get('listzones', array() , true); } catch (exceptions\DNSSubmoduleException $e) { if($e->getCode() == dns\SubmoduleExceptionCodes::COMMAND_ERROR) { return false; } throw $e; } if(isset($out->zone)) { $k=0; while($out->zone[$k]) { if((string)$out->zone[$k]->domain == $this->domain) return true; $k++; } } return false; } public function activateZone() { if($this->ip != '') { if(!filter_var($this->ip, FILTER_VALIDATE_IP)) { throw new exceptions\DNSSubmoduleException('IP is not valid!', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS); } } else { $this->ip = $this->config['default_ip']; } $params = array( 'domain' => $this->domain, 'ip' => $this->ip ); if($this->config['template'] != "") $params['template'] = $this->config['template']; $this->get('adddns', $params); } public function terminateZone() { $this->get('killdns', array( 'domain' => $this->domain )); } public function getZones() { $out = array(); $res = $this->get('listzones', array(), true); foreach ($res->zone as $zone) { $out[(string)$zone->domain] = ''; } try { $res = $this->get('listaccts', array('want' => 'domain,ip'), true); foreach ($res->acct as $zone) { $out[(string)$zone->domain] = (string)$zone->ip; } } catch (exceptions\DNSSubmoduleException $e) { } return $out; } private function get($function, $params=array(), $nothing = false) { $url = ($this->config['ssl']? 'https://'.$this->config['hostname'].':2087' : 'http://'.$this->config['hostname'].':2086').'/xml-api/'.$function; $ch = curl_init(); if(is_array($params)) { $url .= '?'; foreach($params as $key=>$value) { $value = urlencode($value); $url .= "{$key}={$value}&"; } } $url = trim($url, '&'); $this->log($url); $chOptions = array ( CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_TIMEOUT => 50 ); if($this->config['hash'] != ''){ $header[0] = 'Authorization: WHM '.$this->config['username'].':'.str_replace(array("\r", "\n"),"", $this->config['hash']); $chOptions[CURLOPT_HTTPHEADER] = $header; }elseif($this->config['password'] != ''){ $chOptions[CURLOPT_USERPWD] = $this->config['username'].':'.$this->config['password']; }else{ throw new exceptions\DNSSubmoduleException('Password or Access key is required', dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } curl_setopt_array($ch, $chOptions); $out = curl_exec($ch); //cpanel sometimes appends the following text to the ned of response XML: if(($tagPos = strpos($out, '