1 <?php
2
3 /**
4 * A Javascript date-picker which submits dates as unix timestamps.
5 *
6 * @package Fieldmanager_Field
7 */
8 class Fieldmanager_Datepicker extends Fieldmanager_Field {
9
10 /**
11 * @var boolean
12 * Collect time info or just date info? Defaults to just date info.
13 */
14 public $use_time = False;
15
16 /**
17 * @var boolean
18 * If true, and $use_time == true, and $date_element = 'dropdown', will render an 'AM' and 'PM' dropdown
19 */
20 public $use_am_pm = True;
21
22 /**
23 * @var string
24 * PHP date format, only used for rendering already-saved dates. Use js_opts['dateFormat'] for the
25 * date shown when a user selects an option. This option renders to '21 Apr 2013', and is fairly
26 * friendly to international users.
27 */
28 public $date_format = 'j M Y';
29
30 /**
31 * @var boolean
32 * By default in WordPress, strtotime() assumes GMT. If $store_local_time is true, FM will use the
33 * site's timezone setting when generating the timestamp. Note that `date()` will return GMT times
34 * for the stamp no matter what, so if you store the local time, `date( 'H:i', $time )` will return
35 * the offset time. Use this option if the exact timestamp is important, e.g. to schedule a wp-cron
36 * event.
37 */
38 public $store_local_time = false;
39
40 /**
41 * @var array
42 * Options to pass to the jQueryUI Datepicker. If you change dateFormat, be sure that it returns
43 * a valid unix timestamp. Also, it's best to change js_opts['dateFormat'] and date_format together
44 * for a consistent user experience.
45 *
46 * Default:
47 * <code>
48 * array(
49 * 'showButtonPanel' => True,
50 * 'showOtherMonths' => True,
51 * 'selectOtherMonths' => True,
52 * 'dateFormat' => 'd M yy',
53 * );
54 * </code>
55 * @see http://api.jqueryui.com/datepicker/
56 */
57 public $js_opts = array();
58
59 /**
60 * Construct default attributes and enqueue javascript
61 * @param array $options
62 */
63 public function __construct( $label = '', $options = array() ) {
64 wp_enqueue_script( 'jquery-ui-datepicker' );
65 fm_add_style( 'fm-jquery-ui', 'css/jquery-ui/jquery-ui-1.10.2.custom.min.css' );
66 fm_add_script( 'fm_datepicker', 'js/fieldmanager-datepicker.js', array( 'fieldmanager_script' ) );
67 parent::__construct( $label, $options );
68
69 if ( empty( $this->js_opts ) ) {
70 $this->js_opts = array(
71 'showButtonPanel' => True,
72 'showOtherMonths' => True,
73 'selectOtherMonths' => True,
74 'dateFormat' => 'd M yy',
75 );
76 }
77 }
78
79 /**
80 * Generate HTML for the form element itself. Generally should be just one tag, no wrappers.
81 *
82 * @param mixed string[]|string the value of the element.
83 * @return string HTML for the element.
84 */
85 public function form_element( $value ) {
86 $value = absint( $value );
87 $old_value = $value;
88 // If we're storing the local time, in order to make the form work as expected, we have
89 // to alter the timestamp. This isn't ideal, but there currently isn't a good way around
90 // it in WordPress.
91 if ( $this->store_local_time ) {
92 $value += get_option( 'gmt_offset' ) * HOUR_IN_SECONDS;
93 }
94 ob_start();
95 include fieldmanager_get_template( 'datepicker' );
96
97 // Reset the timestamp
98 $value = $old_value;
99 return ob_get_clean();
100 }
101
102 /**
103 * Convert date to timestamp
104 * @param $value
105 * @param $current_value
106 * @return int unix timestamp
107 */
108 public function presave( $value, $current_value = array() ) {
109 $time_to_parse = sanitize_text_field( $value['date'] );
110 if ( isset( $value['hour'] ) && is_numeric( $value['hour'] ) && $this->use_time ) {
111 $hour = intval( $value['hour'] );
112 $minute = ( isset( $value['minute'] ) && is_numeric( $value['minute'] ) ) ? intval( $value['minute'] ) : 0;
113 if ( $hour == 0 && $this->use_am_pm ) $hour = 12;
114 $time_to_parse .= ' ' . $hour;
115 $time_to_parse .= ':' . str_pad( $minute, 2, '0', STR_PAD_LEFT );
116 $time_to_parse .= ' ' . sanitize_text_field( $value['ampm'] );
117 }
118 if ( $this->store_local_time ) {
119 return get_gmt_from_date( $time_to_parse, 'U' );
120 } else {
121 return intval( strtotime( $time_to_parse ) );
122 }
123 }
124
125 /**
126 * Get hour for rendering in field
127 * @param int $value unix timestamp
128 * @return string value of hour
129 */
130 public function get_hour( $value ) {
131 return !empty( $value ) ? date( $this->use_am_pm ? 'g' : 'G', $value ) : '';
132 }
133
134 /**
135 * Get minute for rendering in field
136 * @param int $value unix timestamp
137 * @return string value of hour
138 */
139 public function get_minute( $value ) {
140 return !empty( $value ) ? date( 'i', $value ) : '';
141 }
142
143 /**
144 * Get am or pm for rendering in field
145 * @param int $value unix timestamp
146 * @return string 'am', 'pm', or ''
147 */
148 public function get_am_pm( $value ) {
149 return ! empty( $value ) ? date( 'a', $value ) : '';
150 }
151
152 }
153