mirror of
https://github.com/maelgangloff/domain-watchdog.git
synced 2025-12-29 16:15:04 +00:00
feat: add differential tracking of domain EPP status codes
This commit is contained in:
39
migrations/Version20241212214741.php
Normal file
39
migrations/Version20241212214741.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\Migrations\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Auto-generated Migration: Please modify to your needs!
|
||||
*/
|
||||
final class Version20241212214741 extends AbstractMigration
|
||||
{
|
||||
public function getDescription(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function up(Schema $schema): void
|
||||
{
|
||||
// this up() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('CREATE SEQUENCE domain_status_id_seq INCREMENT BY 1 MINVALUE 1 START 1');
|
||||
$this->addSql('CREATE TABLE domain_status (id INT NOT NULL, domain_id VARCHAR(255) NOT NULL, date TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, add_status TEXT NOT NULL, delete_status TEXT NOT NULL, PRIMARY KEY(id))');
|
||||
$this->addSql('CREATE INDEX IDX_146369D5115F0EE5 ON domain_status (domain_id)');
|
||||
$this->addSql('COMMENT ON COLUMN domain_status.date IS \'(DC2Type:datetime_immutable)\'');
|
||||
$this->addSql('COMMENT ON COLUMN domain_status.add_status IS \'(DC2Type:simple_array)\'');
|
||||
$this->addSql('COMMENT ON COLUMN domain_status.delete_status IS \'(DC2Type:simple_array)\'');
|
||||
$this->addSql('ALTER TABLE domain_status ADD CONSTRAINT FK_146369D5115F0EE5 FOREIGN KEY (domain_id) REFERENCES domain (ldh_name) NOT DEFERRABLE INITIALLY IMMEDIATE');
|
||||
}
|
||||
|
||||
public function down(Schema $schema): void
|
||||
{
|
||||
// this down() migration is auto-generated, please modify it to your needs
|
||||
$this->addSql('DROP SEQUENCE domain_status_id_seq CASCADE');
|
||||
$this->addSql('ALTER TABLE domain_status DROP CONSTRAINT FK_146369D5115F0EE5');
|
||||
$this->addSql('DROP TABLE domain_status');
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,12 @@ class Domain
|
||||
#[Groups(['domain:item', 'domain:list'])]
|
||||
private ?bool $deleted;
|
||||
|
||||
/**
|
||||
* @var Collection<int, DomainStatus>
|
||||
*/
|
||||
#[ORM\OneToMany(targetEntity: DomainStatus::class, mappedBy: 'domain', orphanRemoval: true)]
|
||||
private Collection $domainStatuses;
|
||||
|
||||
private const IMPORTANT_EVENTS = [EventAction::Deletion->value, EventAction::Expiration->value];
|
||||
private const IMPORTANT_STATUS = [
|
||||
'redemption period',
|
||||
@@ -128,8 +134,8 @@ class Domain
|
||||
$this->nameservers = new ArrayCollection();
|
||||
$this->createdAt = new \DateTimeImmutable('now');
|
||||
$this->updatedAt = new \DateTimeImmutable('now');
|
||||
|
||||
$this->deleted = false;
|
||||
$this->domainStatuses = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getLdhName(): ?string
|
||||
@@ -376,4 +382,34 @@ class Domain
|
||||
|| (count(array_intersect($this->getStatus(), ['auto renew period', 'client hold', 'server hold'])) > 0
|
||||
&& $this->getUpdatedAt()->diff(new \DateTimeImmutable())->days >= 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, DomainStatus>
|
||||
*/
|
||||
public function getDomainStatuses(): Collection
|
||||
{
|
||||
return $this->domainStatuses;
|
||||
}
|
||||
|
||||
public function addDomainStatus(DomainStatus $domainStatus): static
|
||||
{
|
||||
if (!$this->domainStatuses->contains($domainStatus)) {
|
||||
$this->domainStatuses->add($domainStatus);
|
||||
$domainStatus->setDomain($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeDomainStatus(DomainStatus $domainStatus): static
|
||||
{
|
||||
if ($this->domainStatuses->removeElement($domainStatus)) {
|
||||
// set the owning side to null (unless already changed)
|
||||
if ($domainStatus->getDomain() === $this) {
|
||||
$domainStatus->setDomain(null);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
87
src/Entity/DomainStatus.php
Normal file
87
src/Entity/DomainStatus.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\DomainStatusRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity(repositoryClass: DomainStatusRepository::class)]
|
||||
class DomainStatus
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column]
|
||||
private ?int $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'domainStatuses')]
|
||||
#[ORM\JoinColumn(referencedColumnName: 'ldh_name', nullable: false)]
|
||||
private ?Domain $domain = null;
|
||||
|
||||
#[ORM\Column]
|
||||
private ?\DateTimeImmutable $date = null;
|
||||
|
||||
#[ORM\Column(type: Types::SIMPLE_ARRAY)]
|
||||
private array $addStatus = [];
|
||||
|
||||
#[ORM\Column(type: Types::SIMPLE_ARRAY)]
|
||||
private array $deleteStatus = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->date = new \DateTimeImmutable('now');
|
||||
}
|
||||
|
||||
public function getId(): ?int
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getDomain(): ?Domain
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
public function setDomain(?Domain $domain): static
|
||||
{
|
||||
$this->domain = $domain;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDate(): ?\DateTimeImmutable
|
||||
{
|
||||
return $this->date;
|
||||
}
|
||||
|
||||
public function setDate(\DateTimeImmutable $date): static
|
||||
{
|
||||
$this->date = $date;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAddStatus(): array
|
||||
{
|
||||
return $this->addStatus;
|
||||
}
|
||||
|
||||
public function setAddStatus(array $addStatus): static
|
||||
{
|
||||
$this->addStatus = $addStatus;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDeleteStatus(): array
|
||||
{
|
||||
return $this->deleteStatus;
|
||||
}
|
||||
|
||||
public function setDeleteStatus(array $deleteStatus): static
|
||||
{
|
||||
$this->deleteStatus = $deleteStatus;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
43
src/Repository/DomainStatusRepository.php
Normal file
43
src/Repository/DomainStatusRepository.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\DomainStatus;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<DomainStatus>
|
||||
*/
|
||||
class DomainStatusRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, DomainStatus::class);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return DomainStatus[] Returns an array of DomainStatus objects
|
||||
// */
|
||||
// public function findByExampleField($value): array
|
||||
// {
|
||||
// return $this->createQueryBuilder('d')
|
||||
// ->andWhere('d.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->orderBy('d.id', 'ASC')
|
||||
// ->setMaxResults(10)
|
||||
// ->getQuery()
|
||||
// ->getResult()
|
||||
// ;
|
||||
// }
|
||||
|
||||
// public function findOneBySomeField($value): ?DomainStatus
|
||||
// {
|
||||
// return $this->createQueryBuilder('d')
|
||||
// ->andWhere('d.exampleField = :val')
|
||||
// ->setParameter('val', $value)
|
||||
// ->getQuery()
|
||||
// ->getOneOrNullResult()
|
||||
// ;
|
||||
// }
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use App\Config\TldType;
|
||||
use App\Entity\Domain;
|
||||
use App\Entity\DomainEntity;
|
||||
use App\Entity\DomainEvent;
|
||||
use App\Entity\DomainStatus;
|
||||
use App\Entity\Entity;
|
||||
use App\Entity\EntityEvent;
|
||||
use App\Entity\Nameserver;
|
||||
@@ -182,7 +183,22 @@ readonly class RDAPService
|
||||
$domain->setTld($tld)->setLdhName($idnDomain)->setDeleted(false);
|
||||
|
||||
if (array_key_exists('status', $res)) {
|
||||
$addedStatus = array_diff($res['status'], $domain->getStatus());
|
||||
$deletedStatus = array_diff($domain->getStatus(), $res['status']);
|
||||
$domain->setStatus($res['status']);
|
||||
|
||||
if (count($addedStatus) > 0 || count($deletedStatus) > 0) {
|
||||
$this->em->persist($domain);
|
||||
$this->em->flush();
|
||||
|
||||
$domainStatus = (new DomainStatus())
|
||||
->setDomain($domain)
|
||||
->setDate($domain->getUpdatedAt())
|
||||
->setAddStatus($addedStatus)
|
||||
->setDeleteStatus($deletedStatus);
|
||||
|
||||
$this->em->persist($domainStatus);
|
||||
}
|
||||
} else {
|
||||
$this->logger->warning('The domain name {idnDomain} has no WHOIS status.', [
|
||||
'idnDomain' => $idnDomain,
|
||||
|
||||
Reference in New Issue
Block a user