<?php
namespace App\Entity\ExternalPartner\ExternalJobPostingCrawler;
use App\Entity\ExternalPartner\IntegratedExternalPartnerCustomer;
use App\Entity\RecurrentJob;
use App\Entity\User;
use App\Service\ExternalPartner\ExternalJobPostingCrawlerService;
use App\Utility\DateTimeUtility;
use App\Utility\ReflectionHelper;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Exception;
use InvalidArgumentException;
/**
* @ORM\Entity
*
* @ORM\Table(
* name="external_job_posting_crawler_content_parser_tasks"
* )
*/
class ContentParserTask
{
public const STATUS_NEW = 0;
public const STATUS_URL_INVALID = 1;
public const STATUS_READY_TO_BE_SUBMITTED = 2;
public const STATUS_SUBMITTED = 3;
public const STATUS_COULD_NOT_BE_SUBMITTED = 4;
public const STATUS_RESULT_RECEIVED = 5;
public const STATUS_RESULT_HANDLING_SUCCEEDED = 6;
public const STATUS_RESULT_HANDLING_FAILED = 7;
public const STATUS_PARSER_HAS_RECEIVED = 8;
public const STATUS_PARSER_STARTING_FETCH = 9;
public const STATUS_PARSER_FINISHED_FETCH_WITH_SUCCESS = 10;
public const STATUS_PARSER_FINISHED_FETCH_WITH_ERROR = 11;
public const STATUS_PARSER_STARTING_PARSE = 12;
public const STATUS_PARSER_FINISHED_PARSE_WITH_SUCCESS = 13;
public const STATUS_PARSER_FINISHED_PARSE_WITH_ERROR = 14;
public const STATUS_PARSER_STARTING_RESULT_REPORT = 15;
public const STATUS_PARSER_FINISHED_RESULT_REPORT_WITH_SUCCESS = 16;
public const STATUS_PARSER_FINISHED_RESULT_REPORT_WITH_ERROR = 17;
public const STATUS_PARSER_OTHER_ERROR = 18;
/**
* @throws Exception
*/
public function __construct(
int $parserId,
string $urlToParse,
string $resultReportUrl,
IntegratedExternalPartnerCustomer $integratedExternalPartnerCustomer,
?User $createdByUser,
?string $zipcode = null,
?string $recurrentJobsIdForUpdateCheck = null
) {
if (!ReflectionHelper::hasConstWithValue(
ExternalJobPostingCrawlerService::class,
'CONTENT_PARSER_ID_',
$parserId
)) {
throw new InvalidArgumentException("Unknown parser id $parserId.");
}
if (!(mb_substr($urlToParse, 0, 8) === 'https://')) {
throw new InvalidArgumentException("urlToParse does not start with 'https://'.");
}
$this->status = self::STATUS_NEW;
$this->parserId = $parserId;
$this->urlToParse = $urlToParse;
$this->resultReportUrl = $resultReportUrl;
$this->user = $createdByUser;
$this->integratedExternalPartnerCustomer = $integratedExternalPartnerCustomer;
$this->createdAt = DateTimeUtility::createDateTimeUtc();
$this->zipcode = $zipcode;
$this->recurrentJobsIdForUpdateCheck = $recurrentJobsIdForUpdateCheck;
}
/**
* @ORM\GeneratedValue(strategy="CUSTOM")
*
* @ORM\CustomIdGenerator(class="App\Utility\DatabaseIdGenerator")
*
* @ORM\Column(name="id", type="guid")
*
* @ORM\Id
*/
protected ?string $id;
public function getId(): string
{
return $this->id;
}
/**
* @ORM\Column(name="parser_id", type="smallint", nullable=false)
*/
private int $parserId;
public function getParserId(): int
{
return $this->parserId;
}
/**
* @ORM\Column(name="url_to_parse", type="text", length="4096", nullable=false)
*/
private string $urlToParse;
public function getUrlToParse(): string
{
return $this->urlToParse;
}
/**
* @ORM\Column(name="result_report_url", type="text", length="4096", nullable=false)
*/
private string $resultReportUrl;
public function getResultReportUrl(): string
{
return $this->resultReportUrl;
}
/**
* @ORM\Column(name="created_at", type="datetime", nullable=false)
*/
private DateTime $createdAt;
public function getCreatedAt(): DateTime
{
return $this->createdAt;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\User")
*
* @ORM\JoinColumn(name="users_id", nullable=true, onDelete="SET NULL")
*/
private ?User $user;
public function getUser(): ?User
{
return $this->user;
}
/**
* @ORM\Column(name="status", type="smallint", nullable=false)
*/
private int $status;
public function setStatus(int $status): void
{
if (!ReflectionHelper::hasConstWithValue(
self::class,
'STATUS_',
$status
)) {
throw new InvalidArgumentException("Unknown status $status.");
}
// Because of asynchronity, we might get a STATUS_PARSER_FINISHED_RESULT_REPORT_WITH_SUCCESS
// via the info channel from the parser, but don't want to update this if handling already
// failed.
if ($this->status === self::STATUS_RESULT_HANDLING_FAILED) {
return;
}
$this->status = $status;
}
public function getStatus(): int
{
return $this->status;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\ExternalPartner\IntegratedExternalPartnerCustomer")
*
* @ORM\JoinColumn(name="integrated_external_partner_customers_id", referencedColumnName="id", onDelete="CASCADE")
*/
private IntegratedExternalPartnerCustomer $integratedExternalPartnerCustomer;
public function getIntegratedExternalPartnerCustomer(): IntegratedExternalPartnerCustomer
{
return $this->integratedExternalPartnerCustomer;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\RecurrentJob")
*
* @ORM\JoinColumn(name="related_recurrent_jobs_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
*/
private ?RecurrentJob $relatedRecurrentJob;
/** @throws Exception */
public function setRelatedRecurrentJob(?RecurrentJob $relatedRecurrentJob): void
{
if ($this->status !== self::STATUS_RESULT_RECEIVED) {
throw new Exception('Can only set related recurrent job if status is RESULT_RECEIVED.');
}
$this->relatedRecurrentJob = $relatedRecurrentJob;
}
public function getRelatedRecurrentJob(): ?RecurrentJob
{
return $this->relatedRecurrentJob;
}
/**
* @ORM\Column(name="zipcode", type="string", length=128, nullable=true)
*/
protected ?string $zipcode;
public function getZipcode(): ?string
{
return $this->zipcode;
}
/**
* @ORM\ManyToOne(targetEntity="App\Entity\RecurrentJob", cascade={"persist"})
*
* @ORM\JoinColumn(name="recurrent_jobs_id_for_update_check", referencedColumnName="id", nullable=true, onDelete="CASCADE")
*/
protected ?string $recurrentJobsIdForUpdateCheck;
public function getRecurrentJobsIdForUpdateCheck(): ?string
{
return $this->recurrentJobsIdForUpdateCheck;
}
}