feat(Deployment): Integrate Ansible deployment via PHP deployment pipeline
- Create AnsibleDeployStage using framework's Process module for secure command execution - Integrate AnsibleDeployStage into DeploymentPipelineCommands for production deployments - Add force_deploy flag support in Ansible playbook to override stale locks - Use PHP deployment module as orchestrator (php console.php deploy:production) - Fix ErrorAggregationInitializer to use Environment class instead of $_ENV superglobal Architecture: - BuildStage → AnsibleDeployStage → HealthCheckStage for production - Process module provides timeout, error handling, and output capture - Ansible playbook supports rollback via rollback-git-based.yml - Zero-downtime deployments with health checks
This commit is contained in:
117
src/Framework/Core/ValueObjects/PhoneNumber.php
Normal file
117
src/Framework/Core/ValueObjects/PhoneNumber.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Core\ValueObjects;
|
||||
|
||||
/**
|
||||
* Phone number value object
|
||||
*
|
||||
* Validates and formats phone numbers in E.164 format
|
||||
* E.164: +[country code][subscriber number]
|
||||
* Example: +4917612345678
|
||||
*/
|
||||
final readonly class PhoneNumber
|
||||
{
|
||||
public function __construct(
|
||||
public string $value
|
||||
) {
|
||||
if (!$this->isValid($value)) {
|
||||
throw new \InvalidArgumentException("Invalid phone number format: {$value}. Must be in E.164 format (+country code + number)");
|
||||
}
|
||||
}
|
||||
|
||||
public static function fromString(string $value): self
|
||||
{
|
||||
return new self($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create from international format (+country code + number)
|
||||
*/
|
||||
public static function fromInternational(string $countryCode, string $number): self
|
||||
{
|
||||
$cleaned = preg_replace('/[^0-9]/', '', $number);
|
||||
|
||||
if (empty($cleaned)) {
|
||||
throw new \InvalidArgumentException('Phone number cannot be empty');
|
||||
}
|
||||
|
||||
return new self("+{$countryCode}{$cleaned}");
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate E.164 format
|
||||
* - Must start with +
|
||||
* - Followed by 7-15 digits
|
||||
* - No spaces or special characters
|
||||
*/
|
||||
private function isValid(string $value): bool
|
||||
{
|
||||
// E.164 format: +[country code][number]
|
||||
// Max 15 digits total
|
||||
if (!str_starts_with($value, '+')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$numbers = substr($value, 1);
|
||||
|
||||
if (!ctype_digit($numbers)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$length = strlen($numbers);
|
||||
|
||||
return $length >= 7 && $length <= 15;
|
||||
}
|
||||
|
||||
public function equals(self $other): bool
|
||||
{
|
||||
return $this->value === $other->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get country code from phone number
|
||||
* Note: This is a simple extraction, not validation against actual country codes
|
||||
*/
|
||||
public function getCountryCode(): string
|
||||
{
|
||||
// Extract 1-3 digits after +
|
||||
preg_match('/^\+(\d{1,3})/', $this->value, $matches);
|
||||
return $matches[1] ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get subscriber number (without country code)
|
||||
*/
|
||||
public function getSubscriberNumber(): string
|
||||
{
|
||||
$countryCode = $this->getCountryCode();
|
||||
return substr($this->value, strlen($countryCode) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format for display (e.g., +49 176 12345678)
|
||||
*/
|
||||
public function toDisplayFormat(): string
|
||||
{
|
||||
$countryCode = $this->getCountryCode();
|
||||
$subscriber = $this->getSubscriberNumber();
|
||||
|
||||
// Format subscriber number in groups
|
||||
$formatted = '+' . $countryCode . ' ';
|
||||
$formatted .= chunk_split($subscriber, 3, ' ');
|
||||
|
||||
return rtrim($formatted);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user