enableGeoRouting, showPreview: $this->showPreview, customDomain: $this->customDomain, clickLimit: $this->clickLimit, password: $this->password ); } public function withGeoRouting(bool $enabled): self { return new self( trackClicks: $this->trackClicks, enableGeoRouting: $enabled, showPreview: $this->showPreview, customDomain: $this->customDomain, clickLimit: $this->clickLimit, password: $this->password ); } public function withClickLimit(?int $limit): self { return new self( trackClicks: $this->trackClicks, enableGeoRouting: $this->enableGeoRouting, showPreview: $this->showPreview, customDomain: $this->customDomain, clickLimit: $limit, password: $this->password ); } public function withPassword(?string $password): self { return new self( trackClicks: $this->trackClicks, enableGeoRouting: $this->enableGeoRouting, showPreview: $this->showPreview, customDomain: $this->customDomain, clickLimit: $this->clickLimit, password: $password ? password_hash($password, PASSWORD_BCRYPT) : null ); } public function isPasswordProtected(): bool { return $this->password !== null; } public function verifyPassword(string $password): bool { if (! $this->isPasswordProtected()) { return true; } return password_verify($password, $this->password); } public function hasClickLimitReached(int $currentClicks): bool { if ($this->clickLimit === null) { return false; } return $currentClicks >= $this->clickLimit; } public function toArray(): array { return [ 'track_clicks' => $this->trackClicks, 'enable_geo_routing' => $this->enableGeoRouting, 'show_preview' => $this->showPreview, 'custom_domain' => $this->customDomain, 'click_limit' => $this->clickLimit, 'has_password' => $this->isPasswordProtected(), ]; } }