Completed
Push — develop ( d53d64...92f117 )
by Zack
18:11 queued 14:25
created

View_Table_Template::entry_class()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 0
loc 19
ccs 0
cts 4
cp 0
crap 2
rs 9.6333
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 14 and the first side effect is on line 6.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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
 */
14
class View_Table_Template extends View_Template {
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 ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
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 ) {
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
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 ) {
0 ignored issues
show
introduced by
No space after closing casting parenthesis is prohibited
Loading history...
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'
0 ignored issues
show
introduced by
Comma required after last value in array declaration
Loading history...
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 ) .'" data-multisort-href="'. esc_url_raw( $multisort_url ) . '" class="'. $class .'" ></a>&nbsp;'. $column_label;
133
	}
134
135
	/**
136
     * Get the multi-sort URL used in the sorting links
137
     *
138
     * @todo Consider moving to Utils?
139
     *
140
     * @since 2.3
141
     *
142
     * @see add_columns_sort_links
143
	 * @param string $url Single-sort URL
144
	 * @param array $sort_args Single sorting for rules, in [ field_id, dir ] format
145
     * @param string|int $field_id ID of the current field being displayed
146
     *
147
     * @return string Multisort URL, if there are multiple sorts. Otherwise, existing $url
148
	 */
149
	static public function _get_multisort_url( $url, $sort_args, $field_id ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
150
151
		$sorts = Utils::_GET( 'sort' );
152
153
		if ( ! is_array( $sorts ) ) {
154
            return $url;
155
		}
156
157
        $multisort_url = $url;
158
159
		// If the field has already been sorted by, add the field to the URL
160
        if ( ! in_array( $field_id, $keys = array_keys( $sorts ) ) ) {
161
            if ( count( $keys ) ) {
162
                $multisort_url = add_query_arg( sprintf( 'sort[%s]', end( $keys ) ), $sorts[ end( $keys ) ], $multisort_url );
163
                $multisort_url = add_query_arg( $sort_args[0], $sort_args[1], $multisort_url );
164
            } else {
165
                $multisort_url = add_query_arg( $sort_args[0], $sort_args[1], $multisort_url );
166
            }
167
        }
168
        // Otherwise, we are just updating the sort order
169
        else {
170
171
            // Pass empty value to unset
172
            if( '' === $sort_args[1] ) {
173
	            unset( $sorts[ $field_id ] );
174
            } else {
175
	            $sorts[ $field_id ] = $sort_args[1];
176
            }
177
178
            $multisort_url = add_query_arg( array( 'sort' => $sorts ), $multisort_url );
179
        }
180
181
		return $multisort_url;
182
	}
183
184
	/**
185
	 * Output the table column names.
186
	 *
187
	 * @return void
188
	 */
189
	public function the_columns() {
190
		$fields = $this->view->fields->by_position( 'directory_table-columns' );
191
192
		foreach ( $fields->by_visible()->all() as $field ) {
193
			$context = Template_Context::from_template( $this, compact( 'field' ) );
194
195
			$args = array(
196
				'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
197
				'hide_empty' => false,
198
				'zone_id' => 'directory_table-columns',
199
				'markup' => '<th id="{{ field_id }}" class="{{ class }}" style="{{width:style}}" data-label="{{label_value:data-label}}">{{label}}</th>',
200
				'label_markup' => '<span class="gv-field-label">{{ label }}</span>',
201
				'label' => self::get_field_column_label( $field, $context ),
202
			);
203
204
			echo \gravityview_field_output( $args, $context );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '\'
Loading history...
205
		}
206
	}
207
208
	/**
209
     * Returns the label for a column, with support for all deprecated filters
210
     *
211
     * @since 2.1
212
     *
213
	 * @param \GV\Field $field
214
	 * @param \GV\Template_Context $context
215
	 */
216
	protected static function get_field_column_label( $field, $context = null ) {
217
218
		$form = $field->form_id ? GF_Form::by_id( $field->form_id ) : $context->view->form;
0 ignored issues
show
Documentation introduced by
The property form_id does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
219
220
		/**
221
		 * @deprecated Here for back-compatibility.
222
		 */
223
		$column_label = apply_filters( 'gravityview_render_after_label', $field->get_label( $context->view, $form ), $field->as_configuration() );
224
		$column_label = apply_filters( 'gravityview/template/field_label', $column_label, $field->as_configuration(), ( $form && $form->form ) ? $form->form : null, null );
225
226
		/**
227
		 * @filter `gravityview/template/field/label` Override the field label.
228
		 * @since 2.0
229
		 * @param[in,out] string $column_label The label to override.
230
		 * @param \GV\Template_Context $context The context. Does not have entry set here.
231
		 */
232
		$column_label = apply_filters( 'gravityview/template/field/label', $column_label, $context );
233
234
		return $column_label;
235
    }
236
237
	/**
238
	 * Output the entry row.
239
	 *
240
	 * @param \GV\Entry $entry The entry to be rendered.
241
	 * @param array $attributes The attributes for the <tr> tag
242
	 *
243
	 * @return void
244
	 */
245
	public function the_entry( \GV\Entry $entry, $attributes ) {
246
247
		$fields = $this->view->fields->by_position( 'directory_table-columns' )->by_visible();
248
249
		$context = Template_Context::from_template( $this, compact( 'entry', 'fields' ) );
250
251
		/**
252
		 * Push legacy entry context.
253
		 */
254
		\GV\Mocks\Legacy_Context::load( array(
255
			'entry' => $entry,
256
		) );
257
258
		/**
259
		 * @filter `gravityview_table_cells` Modify the fields displayed in a table
260
		 * @param array $fields
261
		 * @param \GravityView_View $this
262
		 * @deprecated Use `gravityview/template/table/fields`
263
		 */
264
		$fields = apply_filters( 'gravityview_table_cells', $fields->as_configuration(), \GravityView_View::getInstance() );
265
		$fields = Field_Collection::from_configuration( $fields );
266
267
		/**
268
		 * @filter `gravityview/template/table/fields` Modify the fields displayed in this tables.
269
		 * @param \GV\Field_Collection $fields The fields.
270
		 * @param \GV\Template_Context $context The context.
271
		 * @since 2.0
272
		 */
273
		$fields = apply_filters( 'gravityview/template/table/fields', $fields, $context );
274
275
		$context = Template_Context::from_template( $this, compact( 'entry', 'fields' ) );
276
277
		/**
278
		 * @filter `gravityview/template/table/entry/row/attributes` Filter the row attributes for the row in table view.
279
		 *
280
		 * @param array $attributes The HTML attributes.
281
		 * @param \GV\Template_Context The context.
282
		 *
283
		 * @since 2.0
284
		 */
285
		$attributes = apply_filters( 'gravityview/template/table/entry/row/attributes', $attributes, $context );
286
287
		/** Glue the attributes together. */
288
		foreach ( $attributes as $attribute => $value ) {
289
			$attributes[ $attribute ] = sprintf( "$attribute=\"%s\"", esc_attr( $value ) );
290
		}
291
		$attributes = implode( ' ', $attributes );
292
293
		?>
294
			<tr<?php echo $attributes ? " $attributes" : ''; ?>>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$attributes'
Loading history...
295
                <?php
296
297
				/**
298
				 * @action `gravityview/template/table/cells/before` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
299
				 * @since 2.0
300
				 * @param \GV\Template_Context The context.
301
				 */
302
				do_action( 'gravityview/template/table/cells/before', $context );
303
304
                /**
305
                 * @action `gravityview_table_cells_before` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
306
                 * @since 1.0.7
307
				 * @param \GravityView_View $this Current GravityView_View object
308
				 * @deprecated Use `gravityview/template/table/cells/before`
309
                 */
310
                do_action( 'gravityview_table_cells_before', \GravityView_View::getInstance() );
311
312
                foreach ( $fields->all() as $field ) {
313
					if ( isset( $this->view->unions[ $entry['form_id'] ] ) ) {
314
						if ( isset( $this->view->unions[ $entry['form_id'] ][ $field->ID ] ) ) {
315
							$field = $this->view->unions[ $entry['form_id'] ][ $field->ID ];
316
						} else {
317
							if ( ! $field instanceof Internal_Field ) {
318
								$field = Internal_Field::from_configuration( array( 'id' => 'custom' ) );
319
							}
320
						}
321
					}
322
					$this->the_field( $field, $entry );
323
				}
324
325
				/**
326
				 * @action `gravityview/template/table/cells/after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
327
				 * @since 2.0
328
				 * @param \GV\Template_Context The context.
329
				 */
330
				do_action( 'gravityview/template/table/cells/after', $context );
331
332
                /**
333
                 * @action `gravityview_table_cells_after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
334
                 * @since 1.0.7
335
				 * @param \GravityView_View $this Current GravityView_View object
336
				 * @deprecated Use `gravityview/template/table/cells/after`
337
                 */
338
                do_action( 'gravityview_table_cells_after', \GravityView_View::getInstance() );
339
340
				?>
341
			</tr>
342
		<?php
343
	}
344
345
	/**
346
	 * Output a field cell.
347
	 *
348
	 * @param \GV\Field $field The field to be ouput.
349
	 * @param \GV\Field $entry The entry this field is for.
350
	 *
351
	 * @return void
352
	 */
353
	public function the_field( \GV\Field $field, \GV\Entry $entry ) {
354
		$form = $this->view->form;
355
		$single_entry = $entry;
356
357
		if ( $entry->is_multi() ) {
358
			if ( ! $single_entry = $entry->from_field( $field ) ) {
359
				echo '<td></td>';
360
				return;
361
			}
362
			$form = GF_Form::by_id( $field->form_id );
0 ignored issues
show
Documentation introduced by
The property form_id does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
363
		}
364
365
		$renderer = new Field_Renderer();
366
		$source = is_numeric( $field->ID ) ? $form : new Internal_Source();
367
368
		$value = $renderer->render( $field, $this->view, $source, $entry, $this->request );
369
370
		$context = Template_Context::from_template( $this, compact( 'field' ) );
371
		$context->entry = $single_entry;
372
373
		$args = array(
374
			'entry' => $entry->as_entry(),
375
			'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
376
			'value' => $value,
377
			'hide_empty' => false,
378
			'zone_id' => 'directory_table-columns',
379
            'label' => self::get_field_column_label( $field, $context ),
380
			'markup' => '<td id="{{ field_id }}" class="{{ class }}" data-label="{{label_value:data-label}}">{{ value }}</td>',
381
            'form' => $form,
382
		);
383
384
		/** Output. */
385
		echo \gravityview_field_output( $args, $context );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '\'
Loading history...
386
	}
387
388
	/**
389
	 * `gravityview_table_body_before` and `gravityview/template/table/body/before` actions.
390
	 *
391
	 * Output inside the `tbody` of the table.
392
	 *
393
	 * @param $context \GV\Template_Context The 2.0 context.
394
	 *
395
	 * @return void
396
	 */
397
	public static function body_before( $context ) {
398
		/**
399
		 * @action `gravityview/template/table/body/before` Output inside the `tbody` of the table.
400
		 * @since 2.0
401
		 * @param \GV\Template_Context $context The template context.
402
		 */
403
		do_action( 'gravityview/template/table/body/before', $context );
404
405
		/**
406
		* @action `gravityview_table_body_before` Inside the `tbody`, before any rows are rendered. Can be used to insert additional rows.
407
		* @deprecated Use `gravityview/template/table/body/before`
408
		* @since 1.0.7
409
		* @param \GravityView_View $gravityview_view Current GravityView_View object.
410
		*/
411
		do_action( 'gravityview_table_body_before', \GravityView_View::getInstance() /** ugh! */ );
412
	}
413
414
	/**
415
	 * `gravityview_table_body_after` and `gravityview/template/table/body/after` actions.
416
	 *
417
	 * Output inside the `tbody` of the table.
418
	 *
419
	 * @param $context \GV\Template_Context The 2.0 context.
420
	 *
421
	 * @return void
422
	 */
423
	public static function body_after( $context ) {
424
		/**
425
		 * @action `gravityview/template/table/body/after` Output inside the `tbody` of the table at the end.
426
		 * @since 2.0
427
		 * @param \GV\Template_Context $context The template context.
428
		 */
429
		do_action( 'gravityview/template/table/body/after', $context );
430
431
		/**
432
		* @action `gravityview_table_body_after` Inside the `tbody`, after any rows are rendered. Can be used to insert additional rows.
433
		* @deprecated Use `gravityview/template/table/body/after`
434
		* @since 1.0.7
435
		* @param \GravityView_View $gravityview_view Current GravityView_View object.
436
		*/
437
		do_action( 'gravityview_table_body_after', \GravityView_View::getInstance() /** ugh! */ );
438
	}
439
440
	/**
441
	 * `gravityview_table_tr_before` and `gravityview/template/table/tr/after` actions.
442
	 *
443
	 * Output inside the `tr` of the table.
444
	 *
445
	 * @param $context \GV\Template_Context The 2.0 context.
446
	 *
447
	 * @return void
448
	 */
449
	public static function tr_before( $context ) {
450
		/**
451
		 * @action `gravityview/template/table/tr/before` Output inside the `tr` of the table when there are no results.
452
		 * @since 2.0
453
		 * @param \GV\Template_Context $context The template context.
454
		 */
455
		do_action( 'gravityview/template/table/tr/before', $context );
456
457
		/**
458
		 * @action `gravityview_table_tr_before` Before the `tr` while rendering each entry in the loop. Can be used to insert additional table rows.
459
		 * @since 1.0.7
460
		 * @deprecated USe `gravityview/template/table/tr/before`
461
		 * @param \GravityView_View $gravityview_view Current GraivtyView_View object.
462
		 */
463
		do_action( 'gravityview_table_tr_before', \GravityView_View::getInstance() /** ugh! */ );
464
	}
465
466
	/**
467
	 * `gravityview_table_tr_after` and `gravityview/template/table/tr/after` actions.
468
	 *
469
	 * Output inside the `tr` of the table.
470
	 *
471
	 * @param $context \GV\Template_Context The 2.0 context.
472
	 *
473
	 * @return void
474
	 */
475
	public static function tr_after( $context ) {
476
		/**
477
		 * @action `gravityview/template/table/tr/after` Output inside the `tr` of the table when there are no results.
478
		 * @since 2.0
479
		 * @param \GV\Template_Context $context The template context.
480
		 */
481
		do_action( 'gravityview/template/table/tr/after', $context );
482
483
		/**
484
		 * @action `gravityview_table_tr_after` Inside the `tr` while rendering each entry in the loop. Can be used to insert additional table cells.
485
		 * @since 1.0.7
486
		 * @deprecated USe `gravityview/template/table/tr/after`
487
		 * @param \GravityView_View $gravityview_view Current GravityView_View object.
488
		 */
489
		do_action( 'gravityview_table_tr_after', \GravityView_View::getInstance() /** ugh! */ );
490
	}
491
492
	/**
493
	 * `gravityview_entry_class` and `gravityview/template/table/entry/class` filters.
494
	 *
495
	 * Modify of the class of a row.
496
	 *
497
	 * @param string $class The class.
498
	 * @param \GV\Entry $entry The entry.
499
	 * @param \GV\Template_Context The context.
500
	 *
501
	 * @return string The classes.
502
	 */
503
	public static function entry_class( $class, $entry, $context ) {
504
		/**
505
		 * @filter `gravityview_entry_class` Modify the class applied to the entry row.
506
		 * @param string $class Existing class.
507
		 * @param array $entry Current entry being displayed
508
		 * @param \GravityView_View $this Current GravityView_View object
509
		 * @deprecated Use `gravityview/template/table/entry/class`
510
		 * @return string The modified class.
511
		 */
512
		$class = apply_filters( 'gravityview_entry_class', $class, $entry->as_entry(), \GravityView_View::getInstance() );
513
514
		/**
515
		 * @filter `gravityview/template/table/entry/class` Modify the class aplied to the entry row.
516
		 * @param string $class The existing class.
517
		 * @param \GV\Template_Context The context.
518
		 * @return string The modified class.
519
		 */
520
		return apply_filters( 'gravityview/template/table/entry/class', $class, Template_Context::from_template( $context->template, compact( 'entry' ) ) );
521
	}
522
}
523