Files
domain-watchdog/src/Service/Connector/NamecheapProvider.php

152 lines
5.3 KiB
PHP
Raw Normal View History

2024-08-19 21:17:57 +02:00
<?php
2024-08-20 13:56:50 +02:00
2024-08-19 21:17:57 +02:00
namespace App\Service\Connector;
use App\Dto\Connector\NamecheapProviderDto;
2024-08-19 21:17:57 +02:00
use App\Entity\Domain;
2024-09-18 13:37:07 +02:00
use Psr\Cache\CacheItemInterface;
2024-09-25 14:03:16 +02:00
use Psr\Cache\CacheItemPoolInterface;
2024-10-02 12:01:07 +02:00
use Psr\Cache\InvalidArgumentException;
2024-09-09 14:02:33 +02:00
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;
2024-10-02 12:01:07 +02:00
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
2024-08-20 13:56:50 +02:00
use Symfony\Contracts\HttpClient\HttpClientInterface;
2024-08-19 21:17:57 +02:00
2024-09-09 14:02:33 +02:00
#[Autoconfigure(public: true)]
2024-09-30 13:48:15 +02:00
class NamecheapProvider extends AbstractProvider
2024-08-19 21:17:57 +02:00
{
protected string $dtoClass = NamecheapProviderDto::class;
2024-08-19 21:17:57 +02:00
public const BASE_URL = 'https://api.namecheap.com/xml.response';
2024-10-02 12:01:07 +02:00
public const SANDBOX_BASE_URL = 'https://api.sandbox.namecheap.com/xml.response';
2024-08-19 21:17:57 +02:00
public function __construct(
CacheItemPoolInterface $cacheItemPool,
private readonly HttpClientInterface $client,
private readonly string $outgoingIp,
DenormalizerInterface&NormalizerInterface $serializer,
ValidatorInterface $validator,
) {
parent::__construct($cacheItemPool, $serializer, $validator);
2024-08-20 13:56:50 +02:00
}
2024-08-19 21:17:57 +02:00
2024-10-02 12:01:07 +02:00
/**
* @throws \Exception
* @throws TransportExceptionInterface
*/
2024-08-19 21:17:57 +02:00
public function orderDomain(Domain $domain, $dryRun): void
2024-08-20 13:56:50 +02:00
{
$addresses = $this->call('namecheap.users.address.getList', [], $dryRun)->AddressGetListResult->List;
2024-08-20 13:56:50 +02:00
if (count($addresses) < 1) {
throw new BadRequestHttpException('Namecheap account requires at least one address to purchase a domain');
2024-08-20 13:56:50 +02:00
}
2024-09-26 13:18:46 +02:00
$addressId = (string) $addresses->attributes()['AddressId'];
$address = (array) $this->call('namecheap.users.address.getinfo', ['AddressId' => $addressId], $dryRun)->GetAddressInfoResult;
2024-09-09 14:02:33 +02:00
if (empty($address['PostalCode'])) {
$address['PostalCode'] = $address['Zip'];
}
2024-08-19 21:17:57 +02:00
2024-08-20 13:56:50 +02:00
$domainAddresses = [];
self::mergePrefixKeys('Registrant', $address, $domainAddresses);
self::mergePrefixKeys('Tech', $address, $domainAddresses);
self::mergePrefixKeys('Admin', $address, $domainAddresses);
self::mergePrefixKeys('AuxBilling', $address, $domainAddresses);
$this->call('namecheap.domains.create', array_merge([
'DomainName' => $domain->getLdhName(), // Domain name to register
'Years' => 1, // Number of years to register
'AddFreeWhoisguard' => 'yes', // Adds free domain privacy for the domain
'WGEnabled' => 'yes', // Enables free domain privacy for the domain
2024-08-23 14:01:02 +02:00
], $domainAddresses), $dryRun);
2024-08-20 13:56:50 +02:00
}
2024-10-02 12:01:07 +02:00
private static function mergePrefixKeys(string $prefix, array|object $src, array &$dest): void
2024-08-20 13:56:50 +02:00
{
foreach ($src as $key => $value) {
2024-09-26 13:18:46 +02:00
$dest[$prefix.$key] = $value;
2024-08-20 13:56:50 +02:00
}
}
2024-10-02 12:01:07 +02:00
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
* @throws \Exception
*/
2024-08-23 14:01:02 +02:00
private function call(string $command, array $parameters = [], bool $dryRun = true): object
2024-08-19 21:17:57 +02:00
{
$actualParams = array_merge([
2024-08-20 13:56:50 +02:00
'Command' => $command,
2024-09-09 14:02:33 +02:00
'UserName' => $this->authData['ApiUser'],
2024-08-23 14:01:02 +02:00
'ApiUser' => $this->authData['ApiUser'],
'ApiKey' => $this->authData['ApiKey'],
'ClientIp' => $this->outgoingIp,
2024-08-19 21:17:57 +02:00
], $parameters);
2024-08-23 14:01:02 +02:00
$response = $this->client->request('POST', $dryRun ? self::SANDBOX_BASE_URL : self::BASE_URL, [
2024-08-20 13:56:50 +02:00
'query' => $actualParams,
2024-08-19 21:17:57 +02:00
]);
$data = new \SimpleXMLElement($response->getContent());
2024-09-09 14:02:33 +02:00
if ($data->Errors->Error) {
throw new BadRequestHttpException($data->Errors->Error);
2024-08-19 21:17:57 +02:00
}
return $data->CommandResponse;
}
2024-10-02 12:01:07 +02:00
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
protected function assertAuthentication(): void
2024-09-30 13:48:15 +02:00
{
$addresses = $this->call('namecheap.users.address.getList', [], false)->AddressGetListResult->List;
if (count($addresses) < 1) {
throw new BadRequestHttpException('Namecheap account requires at least one address to purchase a domain');
}
2024-09-30 13:48:15 +02:00
}
2024-10-02 12:01:07 +02:00
/**
* @throws InvalidArgumentException
*/
2024-09-18 13:37:07 +02:00
protected function getCachedTldList(): CacheItemInterface
{
2024-09-25 14:03:16 +02:00
return $this->cacheItemPool->getItem('app.provider.namecheap.supported-tld');
2024-09-18 13:37:07 +02:00
}
2024-10-02 12:01:07 +02:00
/**
* @throws TransportExceptionInterface
* @throws ServerExceptionInterface
* @throws RedirectionExceptionInterface
* @throws ClientExceptionInterface
*/
2024-09-18 13:37:07 +02:00
protected function getSupportedTldList(): array
{
2024-09-25 14:03:16 +02:00
$supported = [];
$tlds = $this->call('namecheap.domains.gettldlist', [], false)->Tlds->Tld;
for ($i = 0; $i < $tlds->count(); ++$i) {
$supported[] = (string) $tlds[$i]['Name'];
}
return $supported;
2024-09-18 13:37:07 +02:00
}
2024-08-19 21:17:57 +02:00
}