mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
NEW: Allow DateTime to be immutable (#10125)
* BUG: Datetime modify() returns a new field instance. * PR fixes. * PR fixes.
This commit is contained in:
parent
c6ee8c0b34
commit
3db1435df7
@ -47,6 +47,46 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
const ISO_DATETIME_NORMALISED = 'y-MM-dd\'T\'HH:mm:ss';
|
const ISO_DATETIME_NORMALISED = 'y-MM-dd\'T\'HH:mm:ss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag idicating if this field is considered immutable
|
||||||
|
* when this is enabled setting the value of this field will return a new field instance
|
||||||
|
* instead updatin the old one
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $immutable = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $immutable
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setImmutable(bool $immutable): self
|
||||||
|
{
|
||||||
|
$this->immutable = $immutable;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value, $record = null, $markChanged = true)
|
||||||
|
{
|
||||||
|
if ($this->immutable) {
|
||||||
|
// This field is set as immutable so we have to create a new field instance
|
||||||
|
// instead of just updating the value
|
||||||
|
$field = clone $this;
|
||||||
|
|
||||||
|
return $field
|
||||||
|
// This field will inherit the immutable status but we have to disable it before setting the value
|
||||||
|
// to avoid recursion
|
||||||
|
->setImmutable(false)
|
||||||
|
// Update the value so the new field contains the desired value
|
||||||
|
->setValue($value, $record, $markChanged)
|
||||||
|
// Return the immutable flag to the correct state
|
||||||
|
->setImmutable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::setValue($value, $record, $markChanged);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the standard localised date
|
* Returns the standard localised date
|
||||||
*
|
*
|
||||||
@ -170,13 +210,11 @@ class DBDatetime extends DBDate implements TemplateGlobalProvider
|
|||||||
*/
|
*/
|
||||||
public static function now()
|
public static function now()
|
||||||
{
|
{
|
||||||
|
$time = self::$mock_now ? self::$mock_now->Value : time();
|
||||||
|
|
||||||
/** @var DBDatetime $now */
|
/** @var DBDatetime $now */
|
||||||
$now = null;
|
$now = DBField::create_field('Datetime', $time);
|
||||||
if (self::$mock_now) {
|
|
||||||
$now = DBField::create_field('Datetime', self::$mock_now->Value);
|
|
||||||
} else {
|
|
||||||
$now = DBField::create_field('Datetime', time());
|
|
||||||
}
|
|
||||||
return $now;
|
return $now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,6 +499,24 @@ class DatetimeFieldTest extends SapphireTest
|
|||||||
$field->setTimezone('Pacific/Auckland');
|
$field->setTimezone('Pacific/Auckland');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testModifyReturnNewField(): void
|
||||||
|
{
|
||||||
|
$globalStateNow = '2020-01-01 00:00:00';
|
||||||
|
DBDatetime::set_mock_now($globalStateNow);
|
||||||
|
|
||||||
|
// Suppose we need to know the current time in our feature, we store it in a variable
|
||||||
|
// Make this field immutable, so future modifications don't apply to any other object references
|
||||||
|
$now = DBDatetime::now()->setImmutable(true);
|
||||||
|
|
||||||
|
// Later in the code we want to know the time value for 10 days later, we can reuse our $now variable
|
||||||
|
$later = $now->modify('+ 10 days')->Rfc2822();
|
||||||
|
|
||||||
|
// Our expectation is that this code should not apply the change to our
|
||||||
|
// $now variable declared earlier in the code
|
||||||
|
$this->assertSame('2020-01-11 00:00:00', $later, 'We expect to get a future datetime');
|
||||||
|
$this->assertSame($globalStateNow, $now->Rfc2822(), 'We expect to get the current datetime');
|
||||||
|
}
|
||||||
|
|
||||||
protected function getMockForm()
|
protected function getMockForm()
|
||||||
{
|
{
|
||||||
/** @skipUpgrade */
|
/** @skipUpgrade */
|
||||||
|
Loading…
Reference in New Issue
Block a user