GravityView  1.19.4
The best, easiest way to display Gravity Forms entries on your website.
class-gravityview-field-time.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @file class-gravityview-field-time.php
4  * @package GravityView
5  * @subpackage includes\fields
6  */
7 
8 /**
9  * Add custom options for date fields
10  */
12 
13  var $name = 'time';
14 
15  var $search_operators = array( 'is', 'isnot', 'greater_than', 'less_than' );
16 
17  var $_gf_field_class_name = 'GF_Field_Time';
18 
19  var $group = 'advanced';
20 
21  /**
22  * @internal Do not define. This is overridden by the class using a filter.
23  * @todo Fix using variable for time field
24  */
26 
27  /**
28  * @var string The part of the Gravity Forms query that's modified to enable sorting by time. `value` gets replaced.
29  * @since 1.14
30  */
31  const GF_SORTING_SQL = 'SELECT 0 as query, lead_id as id, value';
32 
33  /**
34  * @var string Used to implode and explode the custom sort key for query modification.
35  * @since 1.14
36  */
37  private $_sort_divider = '|:time:|';
38 
39  /**
40  * @var string Used to store the time format for the field ("12" or "24") so it can be used in the query filter
41  * @since 1.14
42  */
43  private $_time_format = null;
44 
45  /**
46  * @var string Used to store the date format for the field, based on the input being displayed, so it can be used in the query filter
47  * @since 1.14
48  */
49  private $_date_format = null;
50 
51  /**
52  * GravityView_Field_Time constructor.
53  */
54  public function __construct() {
55 
56  $this->label = esc_html__( 'Time', 'gravityview' );
57 
58  parent::__construct();
59 
60  add_filter( 'gravityview/sorting/time', array( $this, 'modify_sort_id' ), 10, 2 );
61 
62  add_filter('gravityview_search_criteria', array( $this, '_maybe_filter_gravity_forms_query' ), 10, 4 );
63  }
64 
65  /**
66  * Modify the sort key for the time field so it can be parsed by the query filter
67  *
68  * @see _modify_query_sort_by_time_hack
69  *
70  * @since 1.14
71  * @param string $sort_field_id Existing sort field ID (like "5")
72  * @param int $form_id Gravity Forms Form ID being sorted
73  *
74  * @return string Modified sort key imploded with $_sort_divider, like `5|:time:|12|:time:|h:i A`
75  */
76  public function modify_sort_id( $sort_field_id, $form_id ) {
77 
78  $time_format = self::_get_time_format_for_field( $sort_field_id, $form_id );
79 
80  $date_format = self::date_format( $time_format, $sort_field_id );
81 
82  // Should look something like `5|:time:|12|:time:|h:i A`
83  $new_sort_field_id = implode( $this->_sort_divider, array( $sort_field_id, $time_format, $date_format ) );
84 
85  return $new_sort_field_id;
86  }
87 
88  /**
89  * If the sorting key matches the key set in modify_sort_id(), then modify the Gravity Forms query SQL
90  *
91  * @since 1.14
92  * @see modify_sort_id()
93  *
94  * @param array $criteria Search criteria used by GravityView
95  * @param array $form_ids Forms to search
96  * @param int $view_id ID of the view being used to search
97  *
98  * @return $criteria If a match, the sorting will be updated to set `is_numeric` to true and make sure the field ID is an int
99  */
100  public function _maybe_filter_gravity_forms_query( $criteria, $form_ids, $view_id ) {
101 
102  // If the search is being sorted
103  if( ! empty( $criteria['sorting']['key'] ) ) {
104 
105  $pieces = explode( $this->_sort_divider, $criteria['sorting']['key'] );
106 
107  /**
108  * And the sort key matches the key set in modify_sort_id(), then modify the Gravity Forms query SQL
109  * @see modify_sort_id()
110  */
111  if( ! empty( $pieces[1] ) ) {
112 
113  // Pass these to the _modify_query_sort_by_time_hack() method
114  $this->_time_format = $pieces[1];
115  $this->_date_format = $pieces[2];
116 
117  // Remove fake input IDs (5.1 doesn't exist. Use 5)
118  $criteria['sorting']['key'] = floor( $pieces[0] );
119 
120  /**
121  * Make sure sorting is numeric (# of seconds). IMPORTANT.
122  * @see GVCommon::is_field_numeric() is_numeric should also be set here
123  */
124  $criteria['sorting']['is_numeric'] = true;
125 
126  // Modify the Gravity Forms WP Query
127  add_filter('query', array( $this, '_modify_query_sort_by_time_hack' ) );
128  }
129  }
130 
131  return $criteria;
132  }
133 
134  /**
135  * Modify Gravity Forms query SQL to convert times to numbers
136  * Gravity Forms couldn't sort by time...until NOW
137  *
138  * @since 1.14
139  * @param string $query MySQL query
140  *
141  * @return string Modified query, if the query matches the expected Gravity Forms SQL string used for sorting time fields. Otherwise, original query.
142  */
143  function _modify_query_sort_by_time_hack( $query ) {
144 
145  /**
146  * If this is a Gravity Forms entry selection sorting query, generated by sort_by_field_query(),
147  * then we want to modify the query.
148  * @see GFFormsModel::sort_by_field_query()
149  */
150  if( strpos( $query, self::GF_SORTING_SQL ) > 0 ) {
151 
152  if( $this->_time_format === '24' ) {
153  $sql_str_to_date = "STR_TO_DATE( `value`, '%H:%i' )";
154  } else {
155  $sql_str_to_date = "STR_TO_DATE( `value`, '%h:%i %p' )";
156  }
157 
158  switch ( $this->_date_format ) {
159  case 'h':
160  case 'H':
161  $modification = "TIME_FORMAT( {$sql_str_to_date}, '%H' )";
162  break;
163  case 'i':
164  $modification = "TIME_FORMAT( {$sql_str_to_date}, '%i' )";
165  break;
166  case 'H:i':
167  case 'h:i A':
168  default:
169  $modification = "TIME_TO_SEC( {$sql_str_to_date} )";
170  }
171 
172  /**
173  * Convert the time (12:30 pm) to the MySQL `TIME_TO_SEC()` value for that time (45000)
174  * This way, Gravity Forms is able to sort numerically.
175  */
176  $replacement_query = str_replace( 'value', "{$modification} as value", self::GF_SORTING_SQL );
177 
178  /**
179  * Replace it in the main query
180  */
181  $query = str_replace( self::GF_SORTING_SQL, $replacement_query, $query );
182 
183  /**
184  * REMOVE the Gravity Forms WP Query modifications!
185  */
186  remove_filter( 'query', array( $this, '_modify_query_sort_by_time_hack' ) );
187  }
188 
189  return $query;
190  }
191 
192 
193  function field_options( $field_options, $template_id = '', $field_id = '', $context = '', $input_type = '' ) {
194 
195  // Set variables
196  parent::field_options( $field_options, $template_id, $field_id, $context, $input_type );
197 
198  if( 'edit' === $context ) {
199  return $field_options;
200  }
201 
202  /**
203  * Set default date format based on field ID and Form ID
204  */
205  add_filter('gravityview_date_format', array( $this, '_filter_date_display_date_format' ) );
206 
207  $this->add_field_support('date_display', $field_options );
208 
209  remove_filter('gravityview_date_format', array( $this, '_filter_date_display_date_format' ) );
210 
211  return $field_options;
212  }
213 
214  /**
215  * Return the field's time format by fetching the form ID and checking the field settings
216  *
217  * @since 1.14
218  *
219  * @return string Either "12" or "24". "12" is default.
220  */
221  private function _get_time_format() {
222  global $post;
223 
224  $current_form = isset( $_POST['form_id'] ) ? intval( $_POST['form_id'] ) : gravityview_get_form_id( $post->ID );
225 
226  return self::_get_time_format_for_field( $this->_field_id, $current_form );
227  }
228 
229  /**
230  * Return the field's time format by fetching the form ID and checking the field settings
231  *
232  * @since 1.14
233  *
234  * @param string $field_id ID for Gravity Forms time field
235  * @param int $form_id ID for Gravity Forms form
236  * @return string Either "12" or "24". "12" is default.
237  */
238  static public function _get_time_format_for_field( $field_id, $form_id = 0 ) {
239 
240  // GF defaults to 12, so should we.
241  $time_format = '12';
242 
243  if( $form_id ) {
244  $form = GFAPI::get_form( $form_id );
245 
246  if ( $form ) {
247  $field = GFFormsModel::get_field( $form, floor( $field_id ) );
248  if ( $field && $field instanceof GF_Field_Time ) {
249  $field->sanitize_settings(); // Make sure time is set
250  $time_format = $field->timeFormat;
251  }
252  }
253  }
254 
255  return $time_format;
256  }
257 
258  /**
259  * Modify the default PHP date formats used by the time field based on the field IDs and the field settings
260  *
261  * @since 1.14
262  *
263  * @return string PHP date() format text to to display the correctly formatted time value for the newly created field
264  */
266 
267  $time_format = $this->_get_time_format();
269 
270  return self::date_format( $time_format, $field_id );
271  }
272 
273  /**
274  * Get the default date format for a field based on the field ID and the time format setting
275  *
276  * @since 1.14
277 
278  * @param string $time_format The time format ("12" or "24"). Default: "12" {@since 1.14}
279  * @param int $field_id The ID of the field. Used to figure out full time/hours/minutes/am/pm {@since 1.14}
280  *
281  * @return string PHP date format for the time
282  */
283  static public function date_format( $time_format = '12', $field_id = 0 ) {
284 
285  $field_input_id = gravityview_get_input_id_from_id( $field_id );
286 
287  $default = 'h:i A';
288 
289  // This doesn't take into account 24-hour
290  switch( $field_input_id ) {
291  // Hours
292  case 1:
293  return ( $time_format === '12' ) ? 'h' : 'H';
294  break;
295  // Minutes
296  case 2:
297  return 'i';
298  break;
299  // AM/PM
300  case 3:
301  return 'A';
302  break;
303  // Full time field
304  case 0:
305  return ( $time_format === '12' ) ? $default : 'H:i';
306  break;
307  }
308 
309  return $default;
310  }
311 
312 }
313 
static date_format($time_format= '12', $field_id=0)
Get the default date format for a field based on the field ID and the time format setting...
Modify field settings by extending this class.
gravityview_get_input_id_from_id($field_id= '')
Very commonly needed: get the # of the input based on a full field ID.
modify_sort_id($sort_field_id, $form_id)
Modify the sort key for the time field so it can be parsed by the query filter.
static _get_time_format_for_field($field_id, $form_id=0)
Return the field&#39;s time format by fetching the form ID and checking the field settings.
$criteria['paging']
Modify the search parameters before the entries are fetched.
_filter_date_display_date_format()
Modify the default PHP date formats used by the time field based on the field IDs and the field setti...
add_field_support($key= '', &$field_options)
_modify_query_sort_by_time_hack($query)
Modify Gravity Forms query SQL to convert times to numbers Gravity Forms couldn&#39;t sort by time...
field_options($field_options, $template_id= '', $field_id= '', $context= '', $input_type= '')
$field_id
Definition: time.php:17
_maybe_filter_gravity_forms_query($criteria, $form_ids, $view_id)
If the sorting key matches the key set in modify_sort_id(), then modify the Gravity Forms query SQL...
if(empty($created_by)) $form_id
__construct()
GravityView_Field_Time constructor.
global $post
Add custom options for date fields.
gravityview_get_form_id($view_id)
Get the connected form ID from a View ID.
_get_time_format()
Return the field&#39;s time format by fetching the form ID and checking the field settings.
$current_form
Definition: data-source.php:14
$field
Definition: gquiz_grade.php:11