Completed
Branch BUG-10274-DbSafeDateTime (26ef84)
by
unknown
24:47 queued 12:27
created

DbSafeDateTime::__wakeup()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 2
Metric Value
cc 2
eloc 17
c 4
b 0
f 2
nc 2
nop 0
dl 0
loc 29
rs 8.8571
1
<?php
2
namespace EventEspresso\core\domain\entities;
3
4
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
5
	exit( 'No direct script access allowed' );
6
}
7
8
9
10
/**
11
 * Class DbSafeDateTime
12
 * Some versions of PHP do bad things when you try to serialize a DateTime object for storage.
13
 * This DateTime class extension can be safely serialized and unserialized,
14
 * because the only data it stores is a string containing all o fits relevant details
15
 *
16
 * @package       Event Espresso
17
 * @author        Brent Christensen
18
 * @since         $VID:$
19
 */
20
class DbSafeDateTime extends \DateTime {
21
22
	/**
23
	 * @type string db_safe_timestamp_format
24
	 */
25
	const db_safe_timestamp_format = 'Y-m-d H:i:s O e';
26
27
	/**
28
	 * DateTime object converted to a string that includes the date, time, UTC offset, and timezone identifier
29
	 *
30
	 * @type string $_datetime_string
31
	 */
32
	protected $_datetime_string = '';
33
34
	/**
35
     * where to write the error log to
36
     *
37
     * @type string $_error_log_dir
38
	 */
39
	protected $_error_log_dir = '';
40
41
42
43
    /**
44
     * @param string $error_log_dir
45
     */
46
    public function setErrorLogDir($error_log_dir)
47
    {
48
        // if the folder path is writable, then except the path + filename, else keep empty
49
        $this->_error_log_dir = is_writable(str_replace(basename($error_log_dir), '', $error_log_dir))
50
            ?  $error_log_dir
51
            : '';
52
    }
53
54
55
56
	public function __toString() {
57
		return $this->format( DbSafeDateTime::db_safe_timestamp_format );
58
	}
59
60
61
62
	public function __sleep() {
63
		$this->_datetime_string = $this->format( DbSafeDateTime::db_safe_timestamp_format );
64
        $date = \DateTime::createFromFormat(DbSafeDateTime::db_safe_timestamp_format, $this->_datetime_string);
65
        if ( ! $date instanceof \DateTime) {
66
            try {
67
                // we want a stack trace to determine where the malformed date came from, so...
68
                throw new \DomainException();
69
            } catch (\DomainException $e) {
70
                $stack_trace = $e->getTraceAsString();
71
            }
72
            $this->writeToErrorLog(
73
                sprintf(
74
                    __(
75
                        'A valid DateTime could not be generated from "%1$s" because the following errors occurred: %2$s %3$s %2$s PHP version: %4$s %2$s Stack Trace: %5$s',
76
                        'event_espresso'
77
                    ),
78
                    $this->_datetime_string,
79
                    '<br />',
80
                    print_r(\DateTime::getLastErrors(), true),
81
                    PHP_VERSION,
82
                    $stack_trace
83
                )
84
            );
85
        }
86
        return array( '_datetime_string' );
87
	}
88
89
90
91
	public function __wakeup() {
92
	    // if an empty or null value got saved to the db for a datetime,
93
        // then some servers and/or PHP itself will incorrectly convert that date string
94
        // resulting in "-0001-11-30" for the year-month-day.
95
        // We'll replace those with "0000-00-00" which will allow a valid DateTime object to be created,
96
        // but still result in the internal date for that object being set to "-0001-11-30 10:00:00.000000".
97
        // so we're no better off, but at least things won't go fatal on us.
98
        $this->_datetime_string = str_replace('-0001-11-30', '0000-00-00', $this->_datetime_string);
99
		$date = \DateTime::createFromFormat( DbSafeDateTime::db_safe_timestamp_format, $this->_datetime_string );
100
		if ( ! $date instanceof \DateTime) {
101
            $this->writeToErrorLog(
102
                sprintf(
103
                    __(
104
                        'A valid DateTime could not be recreated from "%1$s" because the following errors occurred: %2$s %3$s %2$s PHP version: %4$s',
105
                        'event_espresso'
106
                    ),
107
                    $this->_datetime_string,
108
                    '<br />',
109
                    print_r(\DateTime::getLastErrors(), true),
110
                    PHP_VERSION
111
                )
112
            );
113
        } else {
114
            $this->__construct(
115
                $date->format(\EE_Datetime_Field::mysql_timestamp_format),
116
                new \DateTimeZone($date->format('e'))
117
            );
118
        }
119
	}
120
121
122
123
    private function writeToErrorLog($message)
124
    {
125
        if ( ! empty($this->_error_log_dir)) {
126
            error_log($message, 3, $this->_error_log_dir);
127
        } else {
128
            error_log($message);
129
        }
130
    }
131
132
133
}
134
// End of file DbSafeDateTime.php
135
// Location: EventEspresso\core\domain\entities/DbSafeDateTime.php