-
Notifications
You must be signed in to change notification settings - Fork 83
/
Copy pathDateRangeBehavior.php
174 lines (155 loc) · 5.25 KB
/
DateRangeBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<?php
/**
* @copyright Copyright © Kartik Visweswaran, Krajee.com, 2015 - 2018
* @package yii2-date-range
* @version 1.6.9
*/
namespace kartik\daterange;
use yii\base\Model;
use yii\base\Behavior;
use yii\base\InvalidParamException;
use yii\base\InvalidConfigException;
/**
* DateRangeBehavior automatically fills the specified attributes with the parsed date range values.
*
* @author Cosmo <[email protected]>
*/
class DateRangeBehavior extends Behavior
{
/**
* @var Model the owner model of this behavior.
*/
public $owner;
/**
* @var string the attribute that containing date range value.
*/
public $attribute = 'date_range';
/**
* @var string the attribute that will receive date value formatted by [[dateFormat]]. Required when [[singleDate]]
* is set to `true`.
*/
public $dateAttribute;
/**
* @var string the attribute that will receive range start value formatted by [[dateStartFormat]]. Required when
* [[singleDate]] is set to `false`.
*/
public $dateStartAttribute;
/**
* @var string the attribute that will receive range end value formatted by [[dateEndFormat]]. Required when
* [[singleDate]] is set to `false`.
*/
public $dateEndAttribute;
/**
* @var string|null|false the PHP date format string. It will be used to format the date value.
* - If set to `null`, this will auto convert the date value into a Unix timestamp.
* - If set to `false`, there is no formatting action on the date value.
* @see [[dateAttribute]]
*/
public $dateFormat;
/**
* @var string|null|false the PHP date format string. It will be used to format the range start value.
* - If set to `null`, this will auto convert the range start value into a Unix timestamp.
* - If set to `false`, there is no formatting action on the range start value.
* @see [[dateStartAttribute]]
*/
public $dateStartFormat;
/**
* @var string|null|false the PHP date format string. It will be used to format the range end value.
* - If set to `null`, this will auto convert the range end value into a Unix timestamp.
* - If set to `false`, there is no formatting action on the range end value.
* @see [[dateEndAttribute]]
*/
public $dateEndFormat;
/**
* @var boolean whether the attribute is a single date.
*/
public $singleDate = false;
/**
* @var string the date range separator.
*/
public $separator;
/**
* Parses the given date into a Unix timestamp.
*
* @param string $date a date string
*
* @return integer|false a Unix timestamp. False on failure.
*/
protected static function dateToTime($date)
{
return strtotime($date);
}
/**
* @inheritdoc
*/
public function init()
{
parent::init();
if ($this->singleDate) {
if (!isset($this->dateAttribute)) {
throw new InvalidConfigException('The "dateAttribute" property must be specified.');
}
} else {
if (!isset($this->dateStartAttribute) || !isset($this->dateEndAttribute)) {
throw new InvalidConfigException(
'The "dateStartAttribute" and "dateEndAttribute" properties must be specified.'
);
}
}
}
/**
* @inheritdoc
*/
public function events()
{
return [
Model::EVENT_AFTER_VALIDATE => 'afterValidate',
];
}
/**
* Handles owner 'afterValidate' event.
*
* @param \yii\base\Event $event event instance.
*/
public function afterValidate($event)
{
if ($this->owner->hasErrors() || $event->name != Model::EVENT_AFTER_VALIDATE) {
return;
}
$dateRangeValue = $this->owner->{$this->attribute};
if (empty($dateRangeValue)) {
return;
}
if ($this->singleDate) {
$this->setOwnerAttribute($this->dateAttribute, $this->dateFormat, $dateRangeValue);
} else {
$separator = empty($this->separator) ? ' - ' : $this->separator;
$dates = explode($separator, $dateRangeValue, 2);
if (count($dates) !== 2) {
throw new InvalidParamException("Invalid date range: '{$dateRangeValue}'.");
}
$this->setOwnerAttribute($this->dateStartAttribute, $this->dateStartFormat, $dates[0]);
$this->setOwnerAttribute($this->dateEndAttribute, $this->dateEndFormat, $dates[1]);
}
}
/**
* Evaluates the attribute value and assigns it to the given attribute.
*
* @param string $attribute the owner attribute name
* @param string $dateFormat the PHP date format string
* @param string $date a date string
*/
protected function setOwnerAttribute($attribute, $dateFormat, $date)
{
if ($dateFormat === false) {
$this->owner->$attribute = $date;
} else {
$timestamp = static::dateToTime($date);
if ($dateFormat === null) {
$this->owner->$attribute = $timestamp;
} else {
$this->owner->$attribute = $timestamp !== false ? date($dateFormat, $timestamp) : false;
}
}
}
}