Currently in Event Espresso core, we store datetime information for fields in our model entities that are described by
DateTime objects. This makes working with
DateTime objects easier. You can read more about when we started using
DateTime objects internally in this post.
Recently, we uncovered a potential flaw with this implementation in that this internally stored
DateTime object was exposed via the
EE_Base_Class::get_DateTime_object method and thus directly mutable by client code. We don’t want this to be mutable because it can lead to unpredictable and unexpected behaviour for any other code working with that entity in the same request.
Our intention has always been that the internal
DateTime object stored in the
EE_Base_Class entity would be immutable externally and any mutation would have to occur through the exposed setters. Besides the exposure of the instance via
get_DateTime_object we also missed the fact that if a
EE_Base_Class child instance (eg.
EE_Datetime) was cloned, the clone would receive the original instances of any cached objects on properties. Thus in the case of cached
DateTime objects, when client code did something like this:
$datetime = EE_Datetime::new_instance();
$cloned = clone $datetime;
The change on the clone start date would also affect the date on the original
$datetime instance because it’s mutating the same
So beginning with version
4.9.59.p of Event Espresso core, the internal
DateTime objects become immutable outside of the
EE_Base_Class entities and are only mutated through setters. We’ve changed things so that:
EE_Base_Class::get_DateTime_objectreturns a clone of the
DateTimeobject. You can mutate that clone and it will not affect the original in the entity.
- Utilizing the
__clonemagic PHP method, we’ve ensured that anytime a
EE_Base_Classchild instance is cloned, that any internal
DateTimeobjects are also cloned. Thus with our example above, the
$cloneinstance can have its date and time information modified and it will only affect the clone, not the original.
In all of Event Espresso core and our add-ons we only had a couple places where the
DateTime object was being mutated directly outside of a
EE_Base_Class and we modified those places so it would work with the changes. Although we believe its unlikely it’s happening, the purpose of this blog post is to alert any developers expecting to be able to directly mutate these
DateTime objects to make sure you understand this is will no longer be possible. All mutations must be done through the exposed interface.