Skip to content

Commit 77480b5

Browse files
Merge pull request #159 from ischenko/nodockblocks
Removed usage of docblocks, fixed several parsing issues
2 parents a6e2fd2 + 4df7a57 commit 77480b5

File tree

30 files changed

+384
-83
lines changed

30 files changed

+384
-83
lines changed

src/BlockStorage/v2/Models/Snapshot.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\BlockStorage\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\OperatorResource;
67
use OpenStack\Common\Resource\Creatable;
78
use OpenStack\Common\Resource\Deletable;
@@ -49,10 +50,19 @@ class Snapshot extends OperatorResource implements Listable, Creatable, Updateab
4950
protected $markerKey = 'id';
5051

5152
protected $aliases = [
52-
'created_at' => 'createdAt',
5353
'volume_id' => 'volumeId',
5454
];
5555

56+
/**
57+
* @inheritdoc
58+
*/
59+
protected function getAliases(): array
60+
{
61+
return parent::getAliases() + [
62+
'created_at' => new Alias('createdAt', \DateTimeImmutable::class)
63+
];
64+
}
65+
5666
public function populateFromResponse(ResponseInterface $response): self
5767
{
5868
parent::populateFromResponse($response);

src/BlockStorage/v2/Models/Volume.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php declare(strict_types=1);
22
namespace OpenStack\BlockStorage\v2\Models;
33

4+
use OpenStack\Common\Resource\Alias;
45
use OpenStack\Common\Resource\OperatorResource;
56
use OpenStack\Common\Resource\Creatable;
67
use OpenStack\Common\Resource\Deletable;
@@ -69,12 +70,21 @@ class Volume extends OperatorResource implements Creatable, Listable, Updateable
6970
'availability_zone' => 'availabilityZone',
7071
'source_volid' => 'sourceVolumeId',
7172
'snapshot_id' => 'snapshotId',
72-
'created_at' => 'createdAt',
7373
'volume_type' => 'volumeTypeName',
7474
'os-vol-tenant-attr:tenant_id' => 'tenantId',
7575
'os-vol-host-attr:host' => 'host'
7676
];
7777

78+
/**
79+
* @inheritdoc
80+
*/
81+
protected function getAliases(): array
82+
{
83+
return parent::getAliases() + [
84+
'created_at' => new Alias('createdAt', \DateTimeImmutable::class)
85+
];
86+
}
87+
7888
public function populateFromResponse(ResponseInterface $response): self
7989
{
8090
parent::populateFromResponse($response);

src/Common/JsonSchema/Schema.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public function normalizeObject($subject, array $aliases): \stdClass
3434
$out = new \stdClass;
3535

3636
foreach ($this->body->properties as $propertyName => $property) {
37-
$name = isset($aliases[$propertyName]) ? $aliases[$propertyName] : $propertyName;
37+
$name = ((array)($aliases[$propertyName] ?? $propertyName))[0];
38+
3839
if (isset($property->readOnly) && $property->readOnly === true) {
3940
continue;
4041
} elseif (property_exists($subject, $name)) {

src/Common/Resource/AbstractResource.php

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -63,71 +63,38 @@ public function populateFromResponse(ResponseInterface $response): self
6363
*/
6464
public function populateFromArray(array $array): self
6565
{
66-
$reflClass = new \ReflectionClass($this);
66+
$aliases = $this->getAliases();
6767

6868
foreach ($array as $key => $val) {
69-
$propertyName = (string) (isset($this->aliases[$key]) ? $this->aliases[$key] : $key);
69+
$alias = $aliases[$key] ?? false;
7070

71-
if (property_exists($this, $propertyName)) {
72-
if ($type = $this->extractTypeFromDocBlock($reflClass, $propertyName)) {
73-
$val = $this->parseDocBlockValue($type, $val);
74-
}
75-
76-
$this->$propertyName = $val;
71+
if ($alias instanceof Alias) {
72+
$key = $alias->propertyName;
73+
$val = $alias->getValue($this, $val);
7774
}
78-
}
79-
80-
return $this;
81-
}
8275

83-
private function parseDocBlockValue(string $type, $val)
84-
{
85-
if (is_null($val)) {
86-
return $val;
87-
} elseif (strpos($type, '[]') === 0 && is_array($val)) {
88-
$array = [];
89-
foreach ($val as $subVal) {
90-
$array[] = $this->model($this->normalizeModelClass(substr($type, 2)), $subVal);
76+
if (property_exists($this, $key)) {
77+
$this->{$key} = $val;
9178
}
92-
$val = $array;
93-
} elseif (strcasecmp($type, '\datetimeimmutable') === 0) {
94-
$val = new \DateTimeImmutable($val);
95-
} elseif ($this->isNotNativeType($type)) {
96-
$val = $this->model($this->normalizeModelClass($type), $val);
9779
}
9880

99-
return $val;
100-
}
101-
102-
private function isNotNativeType(string $type): bool
103-
{
104-
return !in_array($type, [
105-
'string', 'bool', 'boolean', 'double', 'null', 'array', 'object', 'int', 'integer', 'float', 'numeric',
106-
'mixed'
107-
]);
108-
}
109-
110-
private function normalizeModelClass(string $class): string
111-
{
112-
if (strpos($class, '\\') === false) {
113-
$currentNamespace = (new \ReflectionClass($this))->getNamespaceName();
114-
$class = sprintf("%s\\%s", $currentNamespace, $class);
115-
}
116-
117-
return $class;
81+
return $this;
11882
}
11983

120-
private function extractTypeFromDocBlock(\ReflectionClass $reflClass, string $propertyName)
84+
/**
85+
* Constructs alias objects
86+
*
87+
* @return Alias[]
88+
*/
89+
protected function getAliases(): array
12190
{
122-
$docComment = $reflClass->getProperty($propertyName)->getDocComment();
91+
$aliases = [];
12392

124-
if (!$docComment) {
125-
return false;
93+
foreach ((array)$this->aliases as $alias => $property) {
94+
$aliases[$alias] = new Alias($property);
12695
}
12796

128-
$matches = [];
129-
preg_match('#@var ((\[\])?[\w|\\\]+)#', $docComment, $matches);
130-
return isset($matches[1]) ? $matches[1] : null;
97+
return $aliases;
13198
}
13299

133100
/**

src/Common/Resource/Alias.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace OpenStack\Common\Resource;
4+
5+
/**
6+
* @package OpenStack\Common\Resource
7+
*/
8+
class Alias
9+
{
10+
/**
11+
* @var string
12+
*/
13+
public $propertyName;
14+
15+
/**
16+
* @var bool
17+
*/
18+
private $isList;
19+
20+
/**
21+
* @var string
22+
*/
23+
private $className;
24+
25+
/**
26+
* @param string $propertyName A name of the property in target resource class
27+
* @param string|null $className A class name for the property value
28+
* @param bool $list Whether value of the property should be treated as a list or not
29+
*/
30+
public function __construct(string $propertyName, string $className = null, bool $list = false)
31+
{
32+
$this->isList = $list;
33+
$this->propertyName = $propertyName;
34+
$this->className = $className && class_exists($className) ? $className : null;
35+
}
36+
37+
/**
38+
* @param ResourceInterface $resource
39+
* @param mixed $value
40+
*
41+
* @return mixed
42+
*/
43+
public function getValue(ResourceInterface $resource, $value)
44+
{
45+
if ($value === null || !$this->className) {
46+
return $value;
47+
} elseif ($this->isList && is_array($value)) {
48+
$array = [];
49+
foreach ($value as $subVal) {
50+
$array[] = $resource->model($this->className, $subVal);
51+
}
52+
return $array;
53+
} elseif ($this->className === \DateTimeImmutable::class) {
54+
return new \DateTimeImmutable($value);
55+
}
56+
57+
return $resource->model($this->className, $value);
58+
}
59+
}

src/Compute/v2/Models/Image.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\Compute\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\OperatorResource;
67
use OpenStack\Common\Resource\Deletable;
78
use OpenStack\Common\Resource\HasMetadata;
@@ -50,6 +51,17 @@ class Image extends OperatorResource implements Listable, Retrievable, Deletable
5051
protected $resourceKey = 'image';
5152
protected $resourcesKey = 'images';
5253

54+
/**
55+
* @inheritdoc
56+
*/
57+
protected function getAliases(): array
58+
{
59+
return parent::getAliases() + [
60+
'created' => new Alias('created', \DateTimeImmutable::class),
61+
'updated' => new Alias('updated', \DateTimeImmutable::class)
62+
];
63+
}
64+
5365
/**
5466
* {@inheritDoc}
5567
*/

src/Compute/v2/Models/Keypair.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\Compute\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\Creatable;
67
use OpenStack\Common\Resource\OperatorResource;
78
use OpenStack\Common\Resource\Deletable;
@@ -44,12 +45,21 @@ class Keypair extends OperatorResource implements Listable, Retrievable, Deletab
4445
'public_key' => 'publicKey',
4546
'private_key' => 'privateKey',
4647
'user_id' => 'userId',
47-
'created_at' => 'createdAt',
4848
];
4949

5050
protected $resourceKey = 'keypair';
5151
protected $resourcesKey = 'keypairs';
5252

53+
/**
54+
* @inheritdoc
55+
*/
56+
protected function getAliases(): array
57+
{
58+
return parent::getAliases() + [
59+
'created_at' => new Alias('createdAt', \DateTimeImmutable::class)
60+
];
61+
}
62+
5363
/**
5464
* {@inheritDoc}
5565
*/

src/Compute/v2/Models/Server.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\Compute\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\HasWaiterTrait;
67
use OpenStack\Common\Resource\Creatable;
78
use OpenStack\Common\Resource\Deletable;
@@ -111,6 +112,19 @@ class Server extends OperatorResource implements
111112
'OS-EXT-SRV-ATTR:hypervisor_hostname' => 'hypervisorHostname',
112113
];
113114

115+
/**
116+
* @inheritdoc
117+
*/
118+
protected function getAliases(): array
119+
{
120+
return parent::getAliases() + [
121+
'image' => new Alias('image', Image::class),
122+
'flavor' => new Alias('flavor', Flavor::class),
123+
'created' => new Alias('created', \DateTimeImmutable::class),
124+
'updated' => new Alias('updated', \DateTimeImmutable::class)
125+
];
126+
}
127+
114128
/**
115129
* {@inheritDoc}
116130
*

src/Identity/v2/Models/Catalog.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\Identity\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\OperatorResource;
67
use OpenStack\Common\Transport\Utils;
78
use Psr\Http\Message\ResponseInterface;
@@ -22,6 +23,16 @@ class Catalog extends OperatorResource implements \OpenStack\Common\Auth\Catalog
2223
*/
2324
public $entries = [];
2425

26+
/**
27+
* @inheritdoc
28+
*/
29+
protected function getAliases(): array
30+
{
31+
return parent::getAliases() + [
32+
'entries' => new Alias('entries', Entry::class, true)
33+
];
34+
}
35+
2536
/**
2637
* {@inheritDoc}
2738
*/

src/Identity/v2/Models/Entry.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace OpenStack\Identity\v2\Models;
44

5+
use OpenStack\Common\Resource\Alias;
56
use OpenStack\Common\Resource\OperatorResource;
67

78
/**
@@ -20,6 +21,16 @@ class Entry extends OperatorResource
2021
/** @var []Endpoint */
2122
public $endpoints = [];
2223

24+
/**
25+
* @inheritdoc
26+
*/
27+
protected function getAliases(): array
28+
{
29+
return parent::getAliases() + [
30+
'endpoints' => new Alias('endpoints', Endpoint::class, true)
31+
];
32+
}
33+
2334
/**
2435
* Indicates whether this catalog entry matches a certain name and type.
2536
*

0 commit comments

Comments
 (0)