@@ -161,7 +161,7 @@ protected function __construct($fieldValues = [], $by_db = false, $timezone = ''
161161 );
162162 }
163163 }
164- $ this ->_timezone = EEH_DTT_Helper:: get_valid_timezone_string ($ timezone );
164+ $ this ->set_timezone ($ timezone );
165165 if (! empty ($ date_formats ) && is_array ($ date_formats )) {
166166 list ($ this ->_dt_frmt , $ this ->_tm_frmt ) = $ date_formats ;
167167 } else {
@@ -411,15 +411,15 @@ private static function _get_model_classname($model_name = null)
411411 * Gets the model instance (eg instance of EEM_Attendee) given its classname (eg EE_Attendee)
412412 *
413413 * @param string $model_classname
414- * @param null $timezone
414+ * @param string $timezone
415415 * @return EEM_Base
416416 * @throws ReflectionException
417417 * @throws InvalidArgumentException
418418 * @throws InvalidInterfaceException
419419 * @throws InvalidDataTypeException
420420 * @throws EE_Error
421421 */
422- protected static function _get_model_instance_with_name ($ model_classname , $ timezone = null )
422+ protected static function _get_model_instance_with_name ($ model_classname , $ timezone = '' )
423423 {
424424 $ model_classname = str_replace ('EEM_ ' , '' , $ model_classname );
425425 $ model = EE_Registry::instance ()->load_model ($ model_classname );
@@ -445,17 +445,16 @@ protected function _clear_cached_property($property_name)
445445 /**
446446 * Gets the EEM_*_Model for this class
447447 *
448- * @access public now, as this is more convenient
449- * @param $classname
450- * @param null $timezone
448+ * @param string $classname
449+ * @param string $timezone
451450 * @return EEM_Base
452451 * @throws InvalidArgumentException
453452 * @throws InvalidInterfaceException
454453 * @throws InvalidDataTypeException
455454 * @throws EE_Error
456455 * @throws ReflectionException
457456 */
458- protected static function _get_model ($ classname , $ timezone = null )
457+ protected static function _get_model ($ classname , $ timezone = '' )
459458 {
460459 // find model for this class
461460 if (! $ classname ) {
@@ -667,7 +666,7 @@ protected static function _get_primary_key_name($classname = null)
667666 *
668667 * @param array $props_n_values incoming array of properties and their values
669668 * @param string $classname the classname of the child class
670- * @param null $timezone
669+ * @param string $timezone
671670 * @param array $date_formats incoming date_formats in an array where the first value is the
672671 * date_format and the second value is the time format
673672 * @return mixed (EE_Base_Class|bool)
@@ -679,7 +678,7 @@ protected static function _get_primary_key_name($classname = null)
679678 * @throws ReflectionException
680679 * @throws ReflectionException
681680 */
682- protected static function _check_for_object ($ props_n_values , $ classname , $ timezone = null , $ date_formats = [])
681+ protected static function _check_for_object ($ props_n_values , $ classname , $ timezone = '' , $ date_formats = [])
683682 {
684683 $ existing = null ;
685684 $ model = self ::_get_model ($ classname , $ timezone );
@@ -695,9 +694,8 @@ protected static function _check_for_object($props_n_values, $classname, $timezo
695694 }
696695 } elseif ($ model ->has_all_combined_primary_key_fields ($ props_n_values )) {
697696 // no primary key on this model, but there's still a matching item in the DB
698- $ existing = self ::_get_model ($ classname , $ timezone )->get_one_by_ID (
699- self ::_get_model ($ classname , $ timezone )
700- ->get_index_primary_key_string ($ props_n_values )
697+ $ existing = $ model ->get_one_by_ID (
698+ $ model ->get_index_primary_key_string ($ props_n_values )
701699 );
702700 }
703701 if ($ existing ) {
@@ -1187,6 +1185,7 @@ public function get_all_from_cache($relationName)
11871185 );
11881186 }
11891187 }
1188+ $ this ->updateTimezoneOnRelated ($ objects );
11901189 return $ objects ;
11911190 }
11921191
@@ -1289,7 +1288,8 @@ public function get_extra_meta($meta_key, $single = false, $default = null)
12891288 public function get_first_related ($ relationName , $ query_params = [])
12901289 {
12911290 $ model_relation = $ this ->_model ->related_settings_for ($ relationName );
1292- if ($ this ->ID ()) {// this exists in the DB, get from the cache OR the DB
1291+ if ($ this ->ID ()) {
1292+ // this exists in the DB, get from the cache OR the DB
12931293 // if they've provided some query parameters, don't bother trying to cache the result
12941294 // also make sure we're not caching the result of get_first_related
12951295 // on a relation which should have an array of objects (because the cache might have an array of objects)
@@ -1333,6 +1333,7 @@ public function get_first_related($relationName, $query_params = [])
13331333 $ related_model_object = $ this ->get_one_from_cache ($ relationName );
13341334 }
13351335 }
1336+ $ this ->updateTimezoneOnRelated ($ related_model_object );
13361337 return $ related_model_object ;
13371338 }
13381339
@@ -1388,6 +1389,7 @@ public function get_many_related($relationName, $query_params = [])
13881389 // this doesn't exist in the DB, so just get the related things from the cache
13891390 $ related_model_objects = $ this ->get_all_from_cache ($ relationName );
13901391 }
1392+ $ this ->updateTimezoneOnRelated ($ related_model_objects );
13911393 return $ related_model_objects ;
13921394 }
13931395
@@ -1405,8 +1407,9 @@ public function get_one_from_cache($relationName)
14051407 ? $ this ->_model_relations [ $ relationName ]
14061408 : null ;
14071409 if (is_array ($ cached_array_or_object )) {
1408- return array_shift ($ cached_array_or_object );
1410+ $ cached_array_or_object = array_shift ($ cached_array_or_object );
14091411 }
1412+ $ this ->updateTimezoneOnRelated ($ cached_array_or_object );
14101413 return $ cached_array_or_object ;
14111414 }
14121415
@@ -1496,6 +1499,9 @@ public function cache($relationName = '', $object_to_cache = null, $cache_id = n
14961499 */
14971500 public function get_timezone ()
14981501 {
1502+ if (empty ($ this ->_timezone )) {
1503+ $ this ->set_timezone ();
1504+ }
14991505 return $ this ->_timezone ;
15001506 }
15011507
@@ -1506,16 +1512,37 @@ public function get_timezone()
15061512 * (UTC Unix Timestamp) for the object OR when converting FROM the internal timezone (UTC Unix Timestamp). This is
15071513 * available to all child classes that may be using the EE_Datetime_Field for a field data type.
15081514 *
1509- * @access public
15101515 * @param string $timezone A valid timezone string as described by @link http://www.php.net/manual/en/timezones.php
1516+ * @param bool $only_if_not_set if true and $this->_timezone already has a value, then will not do anything
15111517 * @return void
1512- * @throws InvalidArgumentException
1513- * @throws InvalidInterfaceException
1514- * @throws InvalidDataTypeException
15151518 */
1516- public function set_timezone ($ timezone = '' )
1519+ public function set_timezone ($ timezone = '' , $ only_if_not_set = false )
15171520 {
1518- $ this ->_timezone = EEH_DTT_Helper::get_valid_timezone_string ($ timezone );
1521+ static $ set_in_progress = false ;
1522+ // don't update the timezone if it's already set ?
1523+ if (($ only_if_not_set && $ this ->_timezone !== '' ) ) {
1524+ return ;
1525+ }
1526+ $ valid_timezone = ! empty ($ timezone ) && $ this ->_timezone && $ timezone !== $ this ->_timezone
1527+ ? EEH_DTT_Helper::get_valid_timezone_string ($ timezone )
1528+ : $ this ->_timezone ;
1529+ // do NOT set the timezone if we are already in the process of setting the timezone
1530+ // OR the existing timezone is already set and the incoming value is nothing (which gets set to default TZ)
1531+ // OR the existing timezone is already set and the validated value is the same as the existing timezone
1532+ if (
1533+ $ set_in_progress
1534+ || (
1535+ ! empty ($ this ->_timezone )
1536+ && (
1537+ empty ($ timezone ) || $ valid_timezone === $ this ->_timezone
1538+ )
1539+ )
1540+ ) {
1541+ return ;
1542+ }
1543+ $ set_in_progress = true ;
1544+ $ this ->_timezone = $ valid_timezone ? $ valid_timezone : EEH_DTT_Helper::get_valid_timezone_string ();
1545+ $ TZ = new DateTimeZone ($ this ->_timezone );
15191546 // make sure we clear all cached properties because they won't be relevant now
15201547 $ this ->_clear_cached_properties ();
15211548 // make sure we update field settings and the date for all EE_Datetime_Fields
@@ -1524,10 +1551,29 @@ public function set_timezone($timezone = '')
15241551 if ($ field_obj instanceof EE_Datetime_Field) {
15251552 $ field_obj ->set_timezone ($ this ->_timezone );
15261553 if (isset ($ this ->_fields [ $ field_name ]) && $ this ->_fields [ $ field_name ] instanceof DateTime) {
1527- EEH_DTT_Helper::setTimezone ($ this ->_fields [ $ field_name ], new DateTimeZone ( $ this -> _timezone ) );
1554+ EEH_DTT_Helper::setTimezone ($ this ->_fields [ $ field_name ], $ TZ );
15281555 }
15291556 }
15301557 }
1558+ $ set_in_progress = false ;
1559+ }
1560+
1561+
1562+ /**
1563+ * @param array|EE_Base_Class $related
1564+ * @since $VID:$
1565+ */
1566+ private function updateTimezoneOnRelated ($ related )
1567+ {
1568+ if ($ related instanceof EE_Base_Class && $ related ->get_timezone () !== $ this ->_timezone ) {
1569+ $ related ->set_timezone ($ this ->_timezone );
1570+ return ;
1571+ }
1572+ if (is_array ($ related )) {
1573+ foreach ($ related as $ object ) {
1574+ $ this ->updateTimezoneOnRelated ($ object );
1575+ }
1576+ }
15311577 }
15321578
15331579
@@ -1566,7 +1612,7 @@ public function update_cache_after_object_save(
15661612 // verify that incoming object is of the correct type
15671613 $ obj_class = 'EE_ ' . $ relationName ;
15681614 if ($ newly_saved_object instanceof $ obj_class ) {
1569- /* @type EE_Base_Class $ newly_saved_object */
1615+ $ this -> updateTimezoneOnRelated ( $ newly_saved_object);
15701616 // now get the type of relation
15711617 $ relationship_to_model = $ this ->_model ->related_settings_for ($ relationName );
15721618 // if this is a 1:1 relationship
@@ -1994,7 +2040,7 @@ public function get_i18n_datetime($field_name, $format = '')
19942040 $ format ,
19952041 EEH_DTT_Helper::get_timestamp_with_offset (
19962042 $ this ->get_raw ($ field_name ),
1997- $ this ->_timezone
2043+ $ this ->get_timezone ()
19982044 )
19992045 );
20002046 }
@@ -3158,9 +3204,13 @@ public function __sleep()
31583204 * PLZ NOTE: this will reset the array to whatever fields values were present prior to serialization,
31593205 * and therefore should NOT be used to determine if state change has occurred since initial construction.
31603206 * At best, you would only be able to detect if state change has occurred during THIS request.
3207+ *
3208+ * @throws EE_Error
3209+ * @throws ReflectionException
31613210 */
31623211 public function __wakeup ()
31633212 {
3213+ $ this ->_model = $ this ->get_model ();
31643214 $ this ->_props_n_values_provided_in_constructor = $ this ->_fields ;
31653215 }
31663216
0 commit comments