Skip to content

Commit 891ff0d

Browse files
committed
Merge pull request #541 from Rican7/bugfix/datetime-cloning
Bugfix - DateTime cloning and model attribute dirty flagging
2 parents f088c2d + 2da9dcf commit 891ff0d

File tree

2 files changed

+53
-4
lines changed

2 files changed

+53
-4
lines changed

lib/DateTime.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,20 @@ public function __toString()
133133
return $this->format();
134134
}
135135

136+
/**
137+
* Handle PHP object `clone`.
138+
*
139+
* This makes sure that the object doesn't still flag an attached model as
140+
* dirty after cloning the DateTime object and making modifications to it.
141+
*
142+
* @return void
143+
*/
144+
public function __clone()
145+
{
146+
$this->model = null;
147+
$this->attribute_name = null;
148+
}
149+
136150
private function flag_dirty()
137151
{
138152
if ($this->model)

test/DateTimeTest.php

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
2-
use ActiveRecord\DateTime as DateTime;
32
use ActiveRecord\DatabaseException;
3+
use ActiveRecord\DateTime as DateTime;
44

55
class DateTimeTest extends SnakeCase_PHPUnit_Framework_TestCase
66
{
@@ -15,13 +15,20 @@ public function tear_down()
1515
DateTime::$DEFAULT_FORMAT = $this->original_format;
1616
}
1717

18-
private function assert_dirtifies($method /*, method params, ...*/)
18+
private function get_model()
1919
{
2020
try {
2121
$model = new Author();
2222
} catch (DatabaseException $e) {
2323
$this->mark_test_skipped('failed to connect. '.$e->getMessage());
2424
}
25+
26+
return $model;
27+
}
28+
29+
private function assert_dirtifies($method /*, method params, ...*/)
30+
{
31+
$model = $this->get_model();
2532
$datetime = new DateTime();
2633
$datetime->attribute_of($model,'some_date');
2734

@@ -153,7 +160,7 @@ public function test_create_from_format_with_tz()
153160
public function test_native_date_time_attribute_copies_exact_tz()
154161
{
155162
$dt = new \DateTime(null, new \DateTimeZone('America/New_York'));
156-
$model = new Author();
163+
$model = $this->get_model();
157164

158165
// Test that the data transforms without modification
159166
$model->assign_attribute('updated_at', $dt);
@@ -167,7 +174,7 @@ public function test_native_date_time_attribute_copies_exact_tz()
167174
public function test_ar_date_time_attribute_copies_exact_tz()
168175
{
169176
$dt = new DateTime(null, new \DateTimeZone('America/New_York'));
170-
$model = new Author();
177+
$model = $this->get_model();
171178

172179
// Test that the data transforms without modification
173180
$model->assign_attribute('updated_at', $dt);
@@ -177,5 +184,33 @@ public function test_ar_date_time_attribute_copies_exact_tz()
177184
$this->assert_equals($dt->getTimeZone(), $dt2->getTimeZone());
178185
$this->assert_equals($dt->getTimeZone()->getName(), $dt2->getTimeZone()->getName());
179186
}
187+
188+
public function test_clone()
189+
{
190+
$model = $this->get_model();
191+
$model_attribute = 'some_date';
192+
193+
$datetime = new DateTime();
194+
$datetime->attribute_of($model, $model_attribute);
195+
196+
$cloned_datetime = clone $datetime;
197+
198+
// Assert initial state
199+
$this->assert_false($model->attribute_is_dirty($model_attribute));
200+
201+
$cloned_datetime->add(new DateInterval('PT1S'));
202+
203+
// Assert that modifying the cloned object didn't flag the model
204+
$this->assert_false($model->attribute_is_dirty($model_attribute));
205+
206+
$datetime->add(new DateInterval('PT1S'));
207+
208+
// Assert that modifying the model-attached object did flag the model
209+
$this->assert_true($model->attribute_is_dirty($model_attribute));
210+
211+
// Assert that the dates are equal but not the same instance
212+
$this->assert_equals($datetime, $cloned_datetime);
213+
$this->assert_not_same($datetime, $cloned_datetime);
214+
}
180215
}
181216
?>

0 commit comments

Comments
 (0)