Skip to content

Commit 41997e6

Browse files
committed
common collection/document constructor and assign methods
1 parent 394ccd4 commit 41997e6

File tree

9 files changed

+253
-22
lines changed

9 files changed

+253
-22
lines changed

src/Mvc/Collection.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,6 @@ final protected function possibleGetter(string $property)
14961496
* @param null $dataColumnMap
14971497
* @param null $whiteList
14981498
* @return $this|CollectionInterface
1499-
* @throws ReflectionException
15001499
*/
15011500
public function assign(array $data, $dataColumnMap = null, $whiteList = null): CollectionInterface
15021501
{
@@ -1517,11 +1516,21 @@ public function assign(array $data, $dataColumnMap = null, $whiteList = null): C
15171516
}
15181517

15191518
// Use reflection to list uninitialized properties
1520-
$reflection = new ReflectionClass($this);
1519+
try {
1520+
$reflection = new ReflectionClass($this);
1521+
$reflectionProperties = $reflection->getProperties();
1522+
} catch (ReflectionException $e) {
1523+
$reflectionProperties = [];
1524+
}
1525+
$reserved = $this->getReservedAttributes();
15211526

1522-
foreach ($reflection->getProperties() as $reflectionMethod) {
1527+
foreach ($reflectionProperties as $reflectionMethod) {
15231528
$key = $reflectionMethod->getName();
15241529

1530+
if (isset($reserved[$key])) {
1531+
continue;
1532+
}
1533+
15251534
if (isset($dataMapped[$key])) {
15261535
if (is_array($whiteList) && !in_array($key, $whiteList, true)) {
15271536
continue;

src/Mvc/Collection/Document.php

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<?php
22

3-
/** @noinspection PhpUndefinedClassInspection */
4-
53
/**
64
* This file is part of the Phalcon Framework.
75
*
@@ -20,7 +18,10 @@
2018
use MongoDB\BSON\Serializable;
2119
use MongoDB\BSON\Unserializable;
2220
use Phalcon\Helper\Str;
21+
use Phalcon\Incubator\MongoDB\Mvc\CollectionInterface;
2322
use Phalcon\Mvc\EntityInterface;
23+
use ReflectionClass;
24+
use ReflectionException;
2425

2526
/**
2627
* Class Document
@@ -42,19 +43,68 @@ class Document implements
4243
*
4344
* @param array $data
4445
*/
45-
final public function __construct(array $data = [])
46+
final public function __construct($data = null)
4647
{
47-
foreach ($data as $key => $value) {
48-
$this->offsetSet($key, $value);
49-
}
50-
5148
/**
5249
* This allows the developer to execute initialization stuff every time
5350
* an instance is created
5451
*/
5552
if (method_exists($this, 'onConstruct')) {
56-
$this->onConstruct();
53+
$this->onConstruct($data);
54+
}
55+
56+
if (is_array($data)) {
57+
$this->assign($data);
58+
}
59+
}
60+
61+
/**
62+
* @param array $data
63+
* @param null $dataColumnMap
64+
* @param null $whiteList
65+
* @return $this|CollectionInterface
66+
*/
67+
public function assign(array $data, $dataColumnMap = null, $whiteList = null): self
68+
{
69+
if (is_array($dataColumnMap)) {
70+
$dataMapped = [];
71+
72+
foreach ($data as $key => $value) {
73+
if (isset($dataColumnMap[$key])) {
74+
$dataMapped[$dataColumnMap[$key]] = $value;
75+
}
76+
}
77+
} else {
78+
$dataMapped = $data;
79+
}
80+
81+
if (count($dataMapped) === 0) {
82+
return $this;
83+
}
84+
85+
// Use reflection to list uninitialized properties
86+
try {
87+
$reflection = new ReflectionClass($this);
88+
$reflectionProperties = $reflection->getProperties();
89+
} catch (ReflectionException $e) {
90+
$reflectionProperties = [];
91+
}
92+
93+
foreach ($reflectionProperties as $reflectionMethod) {
94+
$key = $reflectionMethod->getName();
95+
96+
if (isset($dataMapped[$key])) {
97+
if (is_array($whiteList) && !in_array($key, $whiteList, true)) {
98+
continue;
99+
}
100+
101+
if (!$this->possibleSetter($key, $dataMapped[$key])) {
102+
$this->$key = $dataMapped[$key];
103+
}
104+
}
57105
}
106+
107+
return $this;
58108
}
59109

60110
/**
@@ -146,7 +196,7 @@ public function toArray(): array
146196
*
147197
* @return array
148198
*/
149-
public function jsonSerialize()
199+
public function jsonSerialize(): array
150200
{
151201
$data = [];
152202

@@ -157,9 +207,13 @@ public function jsonSerialize()
157207
return $data;
158208
}
159209

210+
/**
211+
* @param string $property
212+
* @return mixed
213+
*/
160214
final protected function possibleGetter(string $property)
161215
{
162-
$possibleGetter = "get" . Str::camelize($property);
216+
$possibleGetter = "get" . ucfirst(Str::camelize($property));
163217

164218
if (!method_exists($this, $possibleGetter)) {
165219
return $this->$property;
@@ -171,15 +225,33 @@ final protected function possibleGetter(string $property)
171225
/**
172226
* @return array
173227
*/
174-
public function bsonSerialize()
228+
public function bsonSerialize(): array
175229
{
176230
return $this->toArray();
177231
}
178232

233+
/**
234+
* @param string $property
235+
* @param $value
236+
* @return bool
237+
*/
238+
final protected function possibleSetter(string $property, $value): bool
239+
{
240+
$possibleSetter = "set" . ucfirst(Str::camelize($property));
241+
242+
if (!method_exists($this, $possibleSetter)) {
243+
return false;
244+
}
245+
246+
$this->$possibleSetter($value);
247+
248+
return true;
249+
}
250+
179251
/**
180252
* @param array $data
181253
*/
182-
public function bsonUnserialize(array $data)
254+
public function bsonUnserialize(array $data): void
183255
{
184256
foreach ($data as $key => $value) {
185257
$this->offsetSet($key, $value);

tests/_data/fixtures/Mvc/Collections/Documents/RobotPart.php

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,15 @@
1515

1616
use DateTime;
1717
use DateTimeInterface;
18+
use MongoDB\BSON\ObjectId;
1819
use MongoDB\BSON\UTCDateTime;
20+
use Phalcon\Incubator\MongoDB\Helper\Mongo;
1921
use Phalcon\Incubator\MongoDB\Mvc\Collection\Document;
22+
use function GuzzleHttp\Psr7\str;
2023

2124
class RobotPart extends Document
2225
{
23-
public $id;
26+
protected $id;
2427

2528
public $common_name;
2629

@@ -44,8 +47,40 @@ public function setDate(DateTimeInterface $date)
4447
*/
4548
public function getDate()
4649
{
47-
return $this->date
48-
->toDateTime()
49-
->format(DateTime::ISO8601);
50+
if (null !== $this->date) {
51+
return $this->date
52+
->toDateTime()
53+
->format(DateTime::ATOM);
54+
}
55+
56+
return null;
57+
}
58+
59+
/**
60+
* @param string $type
61+
* @return mixed
62+
*/
63+
public function getId($type = 'string')
64+
{
65+
switch ($type) {
66+
case 'string':
67+
return (string) $this->id;
68+
69+
case 'object':
70+
return $this->id;
71+
72+
default:
73+
return null;
74+
}
75+
}
76+
77+
/**
78+
* @param mixed $id
79+
*/
80+
public function setId($id): void
81+
{
82+
$this->id = Mongo::isValidObjectId($id)
83+
? new ObjectId((string)$id)
84+
: null;
5085
}
5186
}

tests/integration/Collection/ConstructCest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace Phalcon\Incubator\MongoDB\Mvc\Test\Integration\Collection;
1515

1616
use IntegrationTester;
17+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Mvc\Collections\Documents\RobotPart;
1718
use Phalcon\Incubator\MongoDB\Test\Fixtures\Mvc\Collections\Robots;
1819
use Phalcon\Incubator\MongoDB\Test\Fixtures\Traits\DiTrait;
1920

@@ -43,7 +44,10 @@ public function mvcCollectionConstruct(IntegrationTester $I)
4344
$I->wantToTest('Mvc\Collection - __construct()');
4445

4546
$robot = new Robots();
47+
$robot->rbpart = new RobotPart();
48+
4649
$I->assertInstanceOf(Robots::class, $robot);
50+
$I->assertInstanceOf(RobotPart::class, $robot->rbpart);
4751
$I->assertEquals(Robots::DIRTY_STATE_TRANSIENT, $robot->getDirtyState());
4852
}
4953
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Phalcon Framework.
5+
*
6+
* (c) Phalcon Team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE.txt
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Phalcon\Incubator\MongoDB\Mvc\Test\Integration\Collection\Document;
15+
16+
use IntegrationTester;
17+
use MongoDB\BSON\ObjectId;
18+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Mvc\Collections\Documents\RobotPart;
19+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Traits\DiTrait;
20+
21+
/**
22+
* Class AssignCest
23+
*/
24+
class AssignCest
25+
{
26+
use DiTrait;
27+
28+
public function _before()
29+
{
30+
$this->setNewFactoryDefault();
31+
$this->setDiCollectionManager();
32+
$this->setDiMongo();
33+
}
34+
35+
/**
36+
* Tests Phalcon\Mvc\Collection\Document :: assign()
37+
*
38+
* @param IntegrationTester $I
39+
*/
40+
public function mvcCollectionDocumentConstruct(IntegrationTester $I)
41+
{
42+
$I->wantToTest('Mvc\Collection\Document - assign()');
43+
44+
$robotPart = new RobotPart();
45+
$robotPart->assign([
46+
'id' => new ObjectId()
47+
]);
48+
49+
$I->assertInstanceOf(ObjectId::class, $robotPart->getId('object'));
50+
}
51+
}

tests/integration/Collection/Document/ConstructCest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public function _before()
4040
*/
4141
public function mvcCollectionDocumentConstruct(IntegrationTester $I)
4242
{
43-
$I->wantToTest('Mvc\Collection\Document - offsetExists()');
43+
$I->wantToTest('Mvc\Collection\Document - __construct()');
4444

4545
$robotPart = new RobotPart();
4646
$I->assertInstanceOf(RobotPart::class, $robotPart);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the Phalcon Framework.
5+
*
6+
* (c) Phalcon Team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE.txt
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Phalcon\Incubator\MongoDB\Mvc\Test\Integration\Collection\Document;
15+
16+
use IntegrationTester;
17+
use MongoDB\BSON\ObjectId;
18+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Mvc\Collections\Documents\RobotPart;
19+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Mvc\Collections\Robots;
20+
use Phalcon\Incubator\MongoDB\Test\Fixtures\Traits\DiTrait;
21+
22+
/**
23+
* Class JsonSerializeCest
24+
*/
25+
class JsonSerializeCest
26+
{
27+
use DiTrait;
28+
29+
public function _before()
30+
{
31+
$this->setNewFactoryDefault();
32+
$this->setDiCollectionManager();
33+
$this->setDiMongo();
34+
}
35+
36+
/**
37+
* Tests Phalcon\Mvc\Collection\Document :: jsonSerialize()
38+
*
39+
* @param IntegrationTester $I
40+
*/
41+
public function mvcCollectionDocumentJsonSerializeCest(IntegrationTester $I)
42+
{
43+
$I->wantToTest('Mvc\Collection\Document - jsonSerialize()');
44+
45+
$parts = [
46+
'id' => new ObjectId(),
47+
'date' => null,
48+
'common_name' => 'Henry'
49+
];
50+
51+
$robotPart = new RobotPart($parts);
52+
$data = $robotPart->toArray();
53+
$data['id'] = (string)$data['id'];
54+
55+
$dataCompare = json_decode(json_encode($data), true);
56+
$robotCompare = json_decode(json_encode($robotPart), true);
57+
58+
$I->assertEquals($dataCompare, $robotCompare);
59+
}
60+
}

tests/integration/Collection/Document/ReadWriteAttributeCest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function mvcCollectionDocumentReadWriteAttribute(IntegrationTester $I)
5656
$robotPart = new RobotPart(['common_name' => $common_name]);
5757

5858
$robotPart->writeAttribute('id', $robot->getId());
59-
$I->assertEquals($robotPart->id, $robot->getId());
59+
$I->assertEquals($robotPart->getId('object'), $robot->getId());
6060

6161
$partName = $robotPart->readAttribute('common_name');
6262
$I->assertEquals($common_name, $partName);

0 commit comments

Comments
 (0)