1: <?php
2:
3: App::uses('ModelBehavior', 'Model');
4:
5: class TimeZoneBehavior extends ModelBehavior {
6:
7: const UTC_TIMEZONE = 'GMT';
8:
9: 10: 11: 12:
13: private $config;
14:
15: public function setup(\Model $model, $config = array()) {
16: parent::setup($model, $config);
17: $this->config[$model->name] = $config;
18: foreach ($this->config[$model->name] as $field) {
19: $model->validate[$this->_timeZoneField($field)]['timezoneFormat'] = array(
20: 'rule' => 'isValidTimeZone',
21: 'message' => __d('date_time','It is not a valid Timezone format'),
22: 'allowEmpty' => true,
23: 'required' => false,
24: );
25: }
26: }
27:
28: public function beforeSave(\Model $model, $options = array()) {
29: if (parent::beforeSave($model, $options) === false) {
30: return false;
31: }
32: $this->_toDatabase($model, $model->data);
33: return true;
34: }
35:
36: public function afterSave(\Model $model, $created, $options = array()) {
37: if (parent::afterSave($model, $created, $options) === False) {
38: return false;
39: }
40: $this->_fromDatabase($model, $model->data);
41: return true;
42: }
43:
44: public function afterFind(\Model $model, $results, $primary = false) {
45: if (is_array($results)) {
46: foreach (array_keys($results) as $k) {
47: $this->_fromDatabase($model, $results[$k]);
48: }
49: }
50: return $results;
51: }
52:
53: public function isValidTimeZone(\Model $model, $check) {
54: foreach ($check as $value) {
55: if (!in_array($value, timezone_identifiers_list())) {
56: return false;
57: }
58: }
59: return true;
60: }
61:
62: 63: 64: 65: 66: 67:
68: private function _toDatabase(\Model $model, &$row) {
69: foreach ($this->config[$model->name] as $field) {
70: $this->_assertTimeZoneField($model, $row, $field);
71: $this->_convertDateFieldToUtc($model, $row, $field);
72: }
73: if (empty($row[$model->alias][$this->_timeZoneField($field)])) {
74: throw new Exception("{$this->_timeZoneField($field)} field is empty");
75: }
76: }
77:
78: 79: 80: 81: 82:
83: private function _fromDatabase(\Model $model, &$row) {
84: foreach ($this->config[$model->name] as $field) {
85: if (!empty($row[$model->alias][$field])) {
86: $row[$model->alias][$field] = $this->_fromUtc(
87: $row[$model->alias][$field]
88: , $row[$model->alias][$this->_timeZoneField($field)]
89: );
90: }
91: }
92: }
93:
94: private function _assertTimeZoneField(\Model $model, &$row, $field) {
95: if (empty($row[$model->alias][$this->_timeZoneField($field)])) {
96: $row[$model->alias][$this->_timeZoneField($field)] = date_default_timezone_get();
97: }
98: }
99:
100: private function _convertDateFieldToUtc(\Model $model, &$row, $field) {
101: if (!empty($row[$model->alias][$field])) {
102: $row[$model->alias][$field] = $this->_toUtc(
103: $row[$model->alias][$field]
104: , $row[$model->alias][$this->_timeZoneField($field)]
105: );
106: }
107: }
108:
109: 110: 111: 112: 113: 114:
115: private function _toUtc($date, $timeZone) {
116: return $this->_convertDateToZone(
117: $date
118: , $timeZone
119: , self::UTC_TIMEZONE);
120: }
121:
122: 123: 124: 125: 126: 127:
128: private function _fromUtc($date, $timeZone) {
129: return $this->_convertDateToZone(
130: $date
131: , self::UTC_TIMEZONE
132: , $timeZone);
133: }
134:
135: 136: 137: 138: 139: 140: 141:
142: private function _convertDateToZone($date, $from, $to) {
143: $date = new DateTime($date, new DateTimeZone($from));
144: $date->setTimezone(new DateTimeZone($to));
145: return $date->format('Y-m-d H:i:s');
146: }
147:
148: 149: 150: 151: 152:
153: private function _timeZoneField($field) {
154: return $field . '_timezone';
155: }
156:
157: }
158: