| 1 |
<?php |
| 2 |
|
| 3 |
namespace Dudlewebs\WPMCS\s3\Aws\Arn; |
| 4 |
|
| 5 |
use Dudlewebs\WPMCS\s3\Aws\Arn\Exception\InvalidArnException; |
| 6 |
/** |
| 7 |
* Amazon Resource Names (ARNs) uniquely identify AWS resources. The Arn class |
| 8 |
* parses and stores a generic ARN object representation that can apply to any |
| 9 |
* service resource. |
| 10 |
* |
| 11 |
* @internal |
| 12 |
*/ |
| 13 |
class Arn implements ArnInterface |
| 14 |
{ |
| 15 |
protected $data; |
| 16 |
protected $string; |
| 17 |
public static function parse($string) |
| 18 |
{ |
| 19 |
$data = ['arn' => null, 'partition' => null, 'service' => null, 'region' => null, 'account_id' => null, 'resource' => null]; |
| 20 |
$length = \strlen($string); |
| 21 |
$lastDelim = 0; |
| 22 |
$numComponents = 0; |
| 23 |
for ($i = 0; $i < $length; $i++) { |
| 24 |
if ($numComponents < 5 && $string[$i] === ':') { |
| 25 |
// Split components between delimiters |
| 26 |
$data[\key($data)] = \substr($string, $lastDelim, $i - $lastDelim); |
| 27 |
// Do not include delimiter character itself |
| 28 |
$lastDelim = $i + 1; |
| 29 |
\next($data); |
| 30 |
$numComponents++; |
| 31 |
} |
| 32 |
if ($i === $length - 1) { |
| 33 |
// Put the remainder in the last component. |
| 34 |
if (\in_array($numComponents, [5])) { |
| 35 |
$data['resource'] = \substr($string, $lastDelim); |
| 36 |
} else { |
| 37 |
// If there are < 5 components, put remainder in current |
| 38 |
// component. |
| 39 |
$data[\key($data)] = \substr($string, $lastDelim); |
| 40 |
} |
| 41 |
} |
| 42 |
} |
| 43 |
return $data; |
| 44 |
} |
| 45 |
public function __construct($data) |
| 46 |
{ |
| 47 |
if (\is_array($data)) { |
| 48 |
$this->data = $data; |
| 49 |
} elseif (\is_string($data)) { |
| 50 |
$this->data = static::parse($data); |
| 51 |
} else { |
| 52 |
throw new InvalidArnException('Constructor accepts a string or an' . ' array as an argument.'); |
| 53 |
} |
| 54 |
static::validate($this->data); |
| 55 |
} |
| 56 |
public function __toString() |
| 57 |
{ |
| 58 |
if (!isset($this->string)) { |
| 59 |
$components = [$this->getPrefix(), $this->getPartition(), $this->getService(), $this->getRegion(), $this->getAccountId(), $this->getResource()]; |
| 60 |
$this->string = \implode(':', $components); |
| 61 |
} |
| 62 |
return $this->string; |
| 63 |
} |
| 64 |
public function getPrefix() |
| 65 |
{ |
| 66 |
return $this->data['arn']; |
| 67 |
} |
| 68 |
public function getPartition() |
| 69 |
{ |
| 70 |
return $this->data['partition']; |
| 71 |
} |
| 72 |
public function getService() |
| 73 |
{ |
| 74 |
return $this->data['service']; |
| 75 |
} |
| 76 |
public function getRegion() |
| 77 |
{ |
| 78 |
return $this->data['region']; |
| 79 |
} |
| 80 |
public function getAccountId() |
| 81 |
{ |
| 82 |
return $this->data['account_id']; |
| 83 |
} |
| 84 |
public function getResource() |
| 85 |
{ |
| 86 |
return $this->data['resource']; |
| 87 |
} |
| 88 |
public function toArray() |
| 89 |
{ |
| 90 |
return $this->data; |
| 91 |
} |
| 92 |
/** |
| 93 |
* Minimally restrictive generic ARN validation |
| 94 |
* |
| 95 |
* @param array $data |
| 96 |
*/ |
| 97 |
protected static function validate(array $data) |
| 98 |
{ |
| 99 |
if ($data['arn'] !== 'arn') { |
| 100 |
throw new InvalidArnException("The 1st component of an ARN must be" . " 'arn'."); |
| 101 |
} |
| 102 |
if (empty($data['partition'])) { |
| 103 |
throw new InvalidArnException("The 2nd component of an ARN" . " represents the partition and must not be empty."); |
| 104 |
} |
| 105 |
if (empty($data['service'])) { |
| 106 |
throw new InvalidArnException("The 3rd component of an ARN" . " represents the service and must not be empty."); |
| 107 |
} |
| 108 |
if (empty($data['resource'])) { |
| 109 |
throw new InvalidArnException("The 6th component of an ARN" . " represents the resource information and must not be empty." . " Individual service ARNs may include additional delimiters" . " to further qualify resources."); |
| 110 |
} |
| 111 |
} |
| 112 |
protected static function validateAccountId($data, $arnName) |
| 113 |
{ |
| 114 |
if (!self::isValidHostLabel($data['account_id'])) { |
| 115 |
throw new InvalidArnException("The 5th component of a {$arnName}" . " is required, represents the account ID, and" . " must be a valid host label."); |
| 116 |
} |
| 117 |
} |
| 118 |
protected static function validateRegion($data, $arnName) |
| 119 |
{ |
| 120 |
if (empty($data['region'])) { |
| 121 |
throw new InvalidArnException("The 4th component of a {$arnName}" . " represents the region and must not be empty."); |
| 122 |
} |
| 123 |
} |
| 124 |
/** |
| 125 |
* Validates whether a string component is a valid host label |
| 126 |
* |
| 127 |
* @param $string |
| 128 |
* @return bool |
| 129 |
*/ |
| 130 |
protected static function isValidHostLabel($string) |
| 131 |
{ |
| 132 |
if (empty($string) || \strlen($string) > 63) { |
| 133 |
return \false; |
| 134 |
} |
| 135 |
if ($value = \preg_match("/^[a-zA-Z0-9-]+\$/", $string)) { |
| 136 |
return \true; |
| 137 |
} |
| 138 |
return \false; |
| 139 |
} |
| 140 |
} |
| 141 |
|