GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-gv-template-view-table.php
Go to the documentation of this file.
1 <?php
2 namespace GV;
3 
4 /** If this file is called directly, abort. */
5 if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6  die();
7 }
8 
9 /**
10  * The View Table Template class .
11  *
12  * Renders a \GV\View and a \GV\Entry_Collection via a \GV\View_Renderer.
13  */
15  /**
16  * @var string The template slug to be loaded (like "table", "list")
17  */
18  public static $slug = 'table';
19 
20 
21  /**
22  * Constructor. Add filters to modify output.
23  *
24  * @since 2.0.4
25  *
26  * @param View $view
27  * @param Entry_Collection $entries
28  * @param Request $request
29  */
30  public function __construct( View $view, Entry_Collection $entries, Request $request ) {
31 
32  add_filter( 'gravityview/template/field/label', array( __CLASS__, 'add_columns_sort_links' ), 100, 2 );
33 
34  parent::__construct( $view, $entries, $request );
35  }
36 
37  /**
38  * Add sorting links to HTML columns that support sorting
39  *
40  * @since 2.0.4
41  * @since 2.0.5 Made static
42  *
43  * @static
44  *
45  * @param string $column_label Label for the table column
46  * @param \GV\Template_Context $context
47  *
48  * @return string
49  */
50  static public function add_columns_sort_links( $column_label, $context = null ) {
51 
52  $sort_columns = $context->view->settings->get( 'sort_columns' );
53 
54  if ( empty( $sort_columns ) ) {
55  return $column_label;
56  }
57 
58  if ( ! \GravityView_frontend::getInstance()->is_field_sortable( $context->field->ID, $context->view->form->form ) ) {
59  return $column_label;
60  }
61 
62  $sorting = array();
63 
64  $directions = $context->view->settings->get( 'sort_direction' );
65 
66  $sorts = Utils::_GET( 'sort' );
67 
68  if ( $sorts ) {
69  if ( is_array( $sorts ) ) {
70  foreach ( (array)$sorts as $key => $direction ) {
71  if ( $key == $context->field->ID ) {
72  $sorting['key'] = $context->field->ID;
73  $sorting['direction'] = strtolower( $direction );
74  break;
75  }
76  }
77  } else {
78  if ( $sorts == $context->field->ID ) {
79  $sorting['key'] = $context->field->ID;
80  $sorting['direction'] = strtolower( Utils::_GET( 'dir', '' ) );
81  }
82  }
83  } else {
84  foreach ( (array)$context->view->settings->get( 'sort_field', array() ) as $i => $sort_field ) {
85  if ( $sort_field == $context->field->ID ) {
86  $sorting['key'] = $sort_field;
87  $sorting['direction'] = strtolower( Utils::get( $directions, $i, '' ) );
88  break; // Only get the first sort
89  }
90  }
91  }
92 
93  $class = 'gv-sort';
94 
95  $sort_field_id = \GravityView_frontend::_override_sorting_id_by_field_type( $context->field->ID, $context->view->form->ID );
96 
97  $sort_args = array(
98  sprintf( 'sort[%s]', $context->field->ID ),
99  'asc'
100  );
101 
102  // If we are already sorting by the current field...
103  if ( ! empty( $sorting['key'] ) && (string) $sort_field_id === (string) $sorting['key'] ) {
104 
105  switch( $sorting['direction'] ) {
106  // No sort
107  case '':
108  $sort_args[1] = 'asc';
109  $class .= ' gv-icon-caret-up-down';
110  break;
111  case 'desc':
112  $sort_args[1] = '';
113  $class .= ' gv-icon-sort-asc';
114  break;
115  case 'asc':
116  default:
117  $sort_args[1] = 'desc';
118  $class .= ' gv-icon-sort-desc';
119  break;
120  }
121 
122  } else {
123  $class .= ' gv-icon-caret-up-down';
124  }
125 
126  $url = remove_query_arg( array( 'pagenum' ) );
127  $url = remove_query_arg( 'sort', $url );
128  $multisort_url = self::_get_multisort_url( $url, $sort_args, $context->field->ID );
129 
130  $url = add_query_arg( $sort_args[0], $sort_args[1], $url );
131 
132  $return = '<a href="'. esc_url_raw( $url ) .'"';
133 
134  if ( ! empty( $multisort_url ) ) {
135  $return .= ' data-multisort-href="'. esc_url_raw( $multisort_url ) . '"';
136  }
137 
138  $return .= ' class="'. $class .'" ></a>&nbsp;'. $column_label;
139 
140  return $return;
141  }
142 
143  /**
144  * Get the multi-sort URL used in the sorting links
145  *
146  * @todo Consider moving to Utils?
147  *
148  * @since 2.3
149  *
150  * @see add_columns_sort_links
151  * @param string $url Single-sort URL
152  * @param array $sort_args Single sorting for rules, in [ field_id, dir ] format
153  * @param string|int $field_id ID of the current field being displayed
154  *
155  * @return string Multisort URL, if there are multiple sorts. Otherwise, existing $url
156  */
157  static public function _get_multisort_url( $url, $sort_args, $field_id ) {
158 
159  $sorts = Utils::_GET( 'sort' );
160 
161  if ( ! is_array( $sorts ) ) {
162  return $url;
163  }
164 
165  $multisort_url = $url;
166 
167  // If the field has already been sorted by, add the field to the URL
168  if ( ! in_array( $field_id, $keys = array_keys( $sorts ) ) ) {
169  if ( count( $keys ) ) {
170  $multisort_url = add_query_arg( sprintf( 'sort[%s]', end( $keys ) ), $sorts[ end( $keys ) ], $multisort_url );
171  $multisort_url = add_query_arg( $sort_args[0], $sort_args[1], $multisort_url );
172  } else {
173  $multisort_url = add_query_arg( $sort_args[0], $sort_args[1], $multisort_url );
174  }
175  }
176  // Otherwise, we are just updating the sort order
177  else {
178 
179  // Pass empty value to unset
180  if( '' === $sort_args[1] ) {
181  unset( $sorts[ $field_id ] );
182  } else {
183  $sorts[ $field_id ] = $sort_args[1];
184  }
185 
186  $multisort_url = add_query_arg( array( 'sort' => $sorts ), $multisort_url );
187  }
188 
189  return $multisort_url;
190  }
191 
192  /**
193  * Output the table column names.
194  *
195  * @return void
196  */
197  public function the_columns() {
198  $fields = $this->view->fields->by_position( 'directory_table-columns' );
199 
200  foreach ( $fields->by_visible( $this->view )->all() as $field ) {
201  $context = Template_Context::from_template( $this, compact( 'field' ) );
202 
203  $args = array(
204  'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
205  'hide_empty' => false,
206  'zone_id' => 'directory_table-columns',
207  'markup' => '<th id="{{ field_id }}" class="{{ class }}" style="{{width:style}}" data-label="{{label_value:data-label}}">{{label}}</th>',
208  'label_markup' => '<span class="gv-field-label">{{ label }}</span>',
209  'label' => self::get_field_column_label( $field, $context ),
210  );
211 
213  }
214  }
215 
216  /**
217  * Returns the label for a column, with support for all deprecated filters
218  *
219  * @since 2.1
220  *
221  * @param \GV\Field $field
222  * @param \GV\Template_Context $context
223  */
224  protected static function get_field_column_label( $field, $context = null ) {
225 
226  $form = $field->form_id ? GF_Form::by_id( $field->form_id ) : $context->view->form;
227 
228  /**
229  * @deprecated Here for back-compatibility.
230  */
231  $column_label = apply_filters( 'gravityview_render_after_label', $field->get_label( $context->view, $form ), $field->as_configuration() );
232  $column_label = apply_filters( 'gravityview/template/field_label', $column_label, $field->as_configuration(), ( $form && $form->form ) ? $form->form : null, null );
233 
234  /**
235  * @filter `gravityview/template/field/label` Override the field label.
236  * @since 2.0
237  * @param string $column_label The label to override.
238  * @param \GV\Template_Context $context The context. Does not have entry set here.
239  */
240  $column_label = apply_filters( 'gravityview/template/field/label', $column_label, $context );
241 
242  return $column_label;
243  }
244 
245  /**
246  * Output the entry row.
247  *
248  * @param \GV\Entry $entry The entry to be rendered.
249  * @param array $attributes The attributes for the <tr> tag
250  *
251  * @return void
252  */
253  public function the_entry( \GV\Entry $entry, $attributes ) {
254 
255  $fields = $this->view->fields->by_position( 'directory_table-columns' )->by_visible( $this->view );
256 
257  $context = Template_Context::from_template( $this, compact( 'entry', 'fields' ) );
258 
259  /**
260  * Push legacy entry context.
261  */
263  'entry' => $entry,
264  ) );
265 
266  /**
267  * @filter `gravityview_table_cells` Modify the fields displayed in a table
268  * @param array $fields
269  * @param \GravityView_View $this
270  * @deprecated Use `gravityview/template/table/fields`
271  */
272  $fields = apply_filters( 'gravityview_table_cells', $fields->as_configuration(), \GravityView_View::getInstance() );
273  $fields = Field_Collection::from_configuration( $fields );
274 
275  /**
276  * @filter `gravityview/template/table/fields` Modify the fields displayed in this tables.
277  * @param \GV\Field_Collection $fields The fields.
278  * @param \GV\Template_Context $context The context.
279  * @since 2.0
280  */
281  $fields = apply_filters( 'gravityview/template/table/fields', $fields, $context );
282 
283  $context = Template_Context::from_template( $this, compact( 'entry', 'fields' ) );
284 
285  /**
286  * @filter `gravityview/template/table/entry/row/attributes` Filter the row attributes for the row in table view.
287  *
288  * @param array $attributes The HTML attributes.
289  * @param \GV\Template_Context The context.
290  *
291  * @since 2.0
292  */
293  $attributes = apply_filters( 'gravityview/template/table/entry/row/attributes', $attributes, $context );
294 
295  /** Glue the attributes together. */
296  foreach ( $attributes as $attribute => $value ) {
297  $attributes[ $attribute ] = sprintf( "$attribute=\"%s\"", esc_attr( $value ) );
298  }
299  $attributes = implode( ' ', $attributes );
300 
301  ?>
302  <tr<?php echo $attributes ? " $attributes" : ''; ?>>
303  <?php
304 
305  /**
306  * @action `gravityview/template/table/cells/before` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
307  * @since 2.0
308  * @param \GV\Template_Context The context.
309  */
310  do_action( 'gravityview/template/table/cells/before', $context );
311 
312  /**
313  * @action `gravityview_table_cells_before` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
314  * @since 1.0.7
315  * @param \GravityView_View $this Current GravityView_View object
316  * @deprecated Use `gravityview/template/table/cells/before`
317  */
318  do_action( 'gravityview_table_cells_before', \GravityView_View::getInstance() );
319 
320  foreach ( $fields->all() as $field ) {
321  if ( isset( $this->view->unions[ $entry['form_id'] ] ) ) {
322  if ( isset( $this->view->unions[ $entry['form_id'] ][ $field->ID ] ) ) {
323  $field = $this->view->unions[ $entry['form_id'] ][ $field->ID ];
324  } else {
325  if ( ! $field instanceof Internal_Field ) {
326  $field = Internal_Field::from_configuration( array( 'id' => 'custom' ) );
327  }
328  }
329  }
330  $this->the_field( $field, $entry );
331  }
332 
333  /**
334  * @action `gravityview/template/table/cells/after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
335  * @since 2.0
336  * @param \GV\Template_Context The context.
337  */
338  do_action( 'gravityview/template/table/cells/after', $context );
339 
340  /**
341  * @action `gravityview_table_cells_after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
342  * @since 1.0.7
343  * @param \GravityView_View $this Current GravityView_View object
344  * @deprecated Use `gravityview/template/table/cells/after`
345  */
346  do_action( 'gravityview_table_cells_after', \GravityView_View::getInstance() );
347 
348  ?>
349  </tr>
350  <?php
351  }
352 
353  /**
354  * Output a field cell.
355  *
356  * @param \GV\Field $field The field to be ouput.
357  * @param \GV\Field $entry The entry this field is for.
358  *
359  * @return void
360  */
361  public function the_field( \GV\Field $field, \GV\Entry $entry ) {
362  $form = $this->view->form;
363  $single_entry = $entry;
364 
365  /**
366  * Push legacy entry context.
367  */
369  'field' => $field,
370  ) );
371 
372  if ( $entry->is_multi() ) {
373  if ( ! $single_entry = $entry->from_field( $field ) ) {
374  echo '<td></td>';
375  return;
376  }
377  $form = GF_Form::by_id( $field->form_id );
378  }
379 
380  $renderer = new Field_Renderer();
381  $source = is_numeric( $field->ID ) ? $form : new Internal_Source();
382 
383  $value = $renderer->render( $field, $this->view, $source, $entry, $this->request );
384 
385  $context = Template_Context::from_template( $this, compact( 'field' ) );
386  $context->entry = $single_entry;
387 
388  $args = array(
389  'entry' => $entry->as_entry(),
390  'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
391  'value' => $value,
392  'hide_empty' => false,
393  'zone_id' => 'directory_table-columns',
394  'label' => self::get_field_column_label( $field, $context ),
395  'markup' => '<td id="{{ field_id }}" class="{{ class }}" data-label="{{label_value:data-label}}">{{ value }}</td>',
396  'form' => $form,
397  );
398 
399  /** Output. */
401  }
402 
403  /**
404  * `gravityview_table_body_before` and `gravityview/template/table/body/before` actions.
405  *
406  * Output inside the `tbody` of the table.
407  *
408  * @param $context \GV\Template_Context The 2.0 context.
409  *
410  * @return void
411  */
412  public static function body_before( $context ) {
413  /**
414  * @action `gravityview/template/table/body/before` Output inside the `tbody` of the table.
415  * @since 2.0
416  * @param \GV\Template_Context $context The template context.
417  */
418  do_action( 'gravityview/template/table/body/before', $context );
419 
420  /**
421  * @action `gravityview_table_body_before` Inside the `tbody`, before any rows are rendered. Can be used to insert additional rows.
422  * @deprecated Use `gravityview/template/table/body/before`
423  * @since 1.0.7
424  * @param \GravityView_View $gravityview_view Current GravityView_View object.
425  */
426  do_action( 'gravityview_table_body_before', \GravityView_View::getInstance() /** ugh! */ );
427  }
428 
429  /**
430  * `gravityview_table_body_after` and `gravityview/template/table/body/after` actions.
431  *
432  * Output inside the `tbody` of the table.
433  *
434  * @param $context \GV\Template_Context The 2.0 context.
435  *
436  * @return void
437  */
438  public static function body_after( $context ) {
439  /**
440  * @action `gravityview/template/table/body/after` Output inside the `tbody` of the table at the end.
441  * @since 2.0
442  * @param \GV\Template_Context $context The template context.
443  */
444  do_action( 'gravityview/template/table/body/after', $context );
445 
446  /**
447  * @action `gravityview_table_body_after` Inside the `tbody`, after any rows are rendered. Can be used to insert additional rows.
448  * @deprecated Use `gravityview/template/table/body/after`
449  * @since 1.0.7
450  * @param \GravityView_View $gravityview_view Current GravityView_View object.
451  */
452  do_action( 'gravityview_table_body_after', \GravityView_View::getInstance() /** ugh! */ );
453  }
454 
455  /**
456  * `gravityview_table_tr_before` and `gravityview/template/table/tr/after` actions.
457  *
458  * Output inside the `tr` of the table.
459  *
460  * @param $context \GV\Template_Context The 2.0 context.
461  *
462  * @return void
463  */
464  public static function tr_before( $context ) {
465  /**
466  * @action `gravityview/template/table/tr/before` Output inside the `tr` of the table when there are no results.
467  * @since 2.0
468  * @param \GV\Template_Context $context The template context.
469  */
470  do_action( 'gravityview/template/table/tr/before', $context );
471 
472  /**
473  * @action `gravityview_table_tr_before` Before the `tr` while rendering each entry in the loop. Can be used to insert additional table rows.
474  * @since 1.0.7
475  * @deprecated USe `gravityview/template/table/tr/before`
476  * @param \GravityView_View $gravityview_view Current GraivtyView_View object.
477  */
478  do_action( 'gravityview_table_tr_before', \GravityView_View::getInstance() /** ugh! */ );
479  }
480 
481  /**
482  * `gravityview_table_tr_after` and `gravityview/template/table/tr/after` actions.
483  *
484  * Output inside the `tr` of the table.
485  *
486  * @param $context \GV\Template_Context The 2.0 context.
487  *
488  * @return void
489  */
490  public static function tr_after( $context ) {
491  /**
492  * @action `gravityview/template/table/tr/after` Output inside the `tr` of the table when there are no results.
493  * @since 2.0
494  * @param \GV\Template_Context $context The template context.
495  */
496  do_action( 'gravityview/template/table/tr/after', $context );
497 
498  /**
499  * @action `gravityview_table_tr_after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
500  * @since 1.0.7
501  * @deprecated USe `gravityview/template/table/tr/after`
502  * @param \GravityView_View $gravityview_view Current GravityView_View object.
503  */
504  do_action( 'gravityview_table_tr_after', \GravityView_View::getInstance() /** ugh! */ );
505  }
506 
507  /**
508  * `gravityview_entry_class` and `gravityview/template/table/entry/class` filters.
509  *
510  * Modify of the class of a row.
511  *
512  * @param string $class The class.
513  * @param \GV\Entry $entry The entry.
514  * @param \GV\Template_Context The context.
515  *
516  * @return string The classes.
517  */
518  public static function entry_class( $class, $entry, $context ) {
519  /**
520  * @filter `gravityview_entry_class` Modify the class applied to the entry row.
521  * @param string $class Existing class.
522  * @param array $entry Current entry being displayed
523  * @param \GravityView_View $this Current GravityView_View object
524  * @deprecated Use `gravityview/template/table/entry/class`
525  * @return string The modified class.
526  */
527  $class = apply_filters( 'gravityview_entry_class', $class, $entry->as_entry(), \GravityView_View::getInstance() );
528 
529  /**
530  * @filter `gravityview/template/table/entry/class` Modify the class aplied to the entry row.
531  * @param string $class The existing class.
532  * @param \GV\Template_Context The context.
533  * @return string The modified class.
534  */
535  return apply_filters( 'gravityview/template/table/entry/class', $class, Template_Context::from_template( $context->template, compact( 'entry' ) ) );
536  }
537 }
If this file is called directly, abort.
$url
Definition: post_image.php:25
If this file is called directly, abort.
static body_before( $context)
gravityview_table_body_before and gravityview/template/table/body/before actions. ...
static getInstance( $passed_post=NULL)
static _override_sorting_id_by_field_type( $sort_field_id, $form_id)
Override sorting per field.
__construct(View $view, Entry_Collection $entries, Request $request)
Constructor.
static add_columns_sort_links( $column_label, $context=null)
Add sorting links to HTML columns that support sorting.
If this file is called directly, abort.
$class
the_entry(\GV\Entry $entry, $attributes)
Output the entry row.
$entries
the_field(\GV\Field $field, \GV\Entry $entry)
Output a field cell.
static entry_class( $class, $entry, $context)
gravityview_entry_class and gravityview/template/table/entry/class filters.
if(gravityview() ->plugin->is_GF_25()) $form
static _get_multisort_url( $url, $sort_args, $field_id)
Get the multi-sort URL used in the sorting links.
static load( $configuration)
Hydrates the legacy context globals as needed.
Definition: _mocks.php:552
If this file is called directly, abort.
static get_field_column_label( $field, $context=null)
Returns the label for a column, with support for all deprecated filters.
static tr_before( $context)
gravityview_table_tr_before and gravityview/template/table/tr/after actions.
If this file is called directly, abort.
If this file is called directly, abort.
static tr_after( $context)
gravityview_table_tr_after and gravityview/template/table/tr/after actions.
static body_after( $context)
gravityview_table_body_after and gravityview/template/table/body/after actions.
If this file is called directly, abort.
If this file is called directly, abort.
If this file is called directly, abort.
If this file is called directly, abort.
the_columns()
Output the table column names.
gravityview_field_output( $passed_args, $context=null)
Output field based on a certain html markup.
Definition: class-api.php:1452
$entry
Definition: notes.php:27
if(false !==strpos( $value, '00:00')) $field_id
string $field_id ID of the field being displayed
Definition: time.php:22
static getInstance()
Get the one true instantiated self.