Completed
Push — develop ( 87b48c...882b48 )
by Gennady
23:47 queued 03:49
created

View_Table_Template::the_entry()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 99

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 7.1782

Importance

Changes 0
Metric Value
cc 7
nc 10
nop 2
dl 0
loc 99
ccs 22
cts 26
cp 0.8462
crap 7.1782
rs 7.0884
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
 */
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 19
	public function __construct( View $view, Entry_Collection $entries, Request $request ) {
31
32 19
	    add_filter( 'gravityview/template/field/label', array( __CLASS__, 'add_columns_sort_links' ), 100, 2 );
33
34 19
		parent::__construct( $view, $entries, $request );
35 19
	}
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 29
	static public function add_columns_sort_links( $column_label, $context = null ) {
51
52 29
		$sort_columns = $context->view->settings->get( 'sort_columns' );
53
54 29
		if ( empty( $sort_columns ) ) {
55 28
            return $column_label;
56
		}
57
58 1
		if ( ! \GravityView_frontend::getInstance()->is_field_sortable( $context->field->ID, $context->view->form->form ) ) {
59
			return $column_label;
60
		}
61
62 1
		$sorting = array();
63
64 1
		$directions = $context->view->settings->get( 'sort_direction' );
65
66 1
		$sorts = Utils::_GET( 'sort' );
67
68 1
		if ( $sorts ) {
69 1
			if ( is_array( $sorts ) ) {
70 1
				foreach ( (array)$sorts as $key => $direction ) {
71 1
					if ( $key == $context->field->ID ) {
72 1
						$sorting['key'] = $context->field->ID;
73 1
						$sorting['direction'] = strtolower( $direction );
74 1
						break;
75
					}
76
				}
77
			} else {
78
				if ( $sorts == $context->field->ID ) {
79
					$sorting['key'] = $context->field->ID;
80 1
					$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 1
		$class = 'gv-sort';
94
95 1
		$sort_field_id = \GravityView_frontend::_override_sorting_id_by_field_type( $context->field->ID, $context->view->form->ID );
96
97
		$sort_args = array(
98 1
			sprintf( 'sort[%s]', $context->field->ID ),
99 1
			'asc'
100
		);
101
102
		// If we are already sorting by the current field...
103 1
		if ( ! empty( $sorting['key'] ) && (string) $sort_field_id === (string) $sorting['key'] ) {
104
105 1
		    switch( $sorting['direction'] ) {
106
		        // No sort
107 1
                case '':
108 1
	                $sort_args[1] = 'asc';
109 1
	                $class .= ' gv-icon-caret-up-down';
110 1
                    break;
111 1
                case 'desc':
112 1
	                $sort_args[1] = '';
113 1
	                $class .= ' gv-icon-sort-asc';
114 1
	                break;
115 1
                case 'asc':
116
                default:
117 1
                    $sort_args[1] = 'desc';
118 1
                    $class .= ' gv-icon-sort-desc';
119 1
                    break;
120
            }
121
122
		} else {
123
			$class .= ' gv-icon-caret-up-down';
124
		}
125
126 1
		$url = remove_query_arg( array( 'pagenum' ) );
127 1
		$url = remove_query_arg( 'sort', $url );
128 1
		$multisort_url = self::_get_multisort_url( $url, $sort_args, $context->field->ID );
129
130 1
    	$url = add_query_arg( $sort_args[0], $sort_args[1], $url );
131
132 1
		$return = '<a href="'. esc_url_raw( $url ) .'"';
133
134 1
		if ( ! empty( $multisort_url ) ) {
135 1
			$return .= ' data-multisort-href="'. esc_url_raw( $multisort_url ) . '"';
136
		}
137
138 1
		$return .= ' class="'. $class .'" ></a>&nbsp;'. $column_label;
139
140 1
		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 2
	static public function _get_multisort_url( $url, $sort_args, $field_id ) {
158
159 2
		$sorts = Utils::_GET( 'sort' );
160
161 2
		if ( ! is_array( $sorts ) ) {
162 1
            return $url;
163
		}
164
165 2
        $multisort_url = $url;
166
167
		// If the field has already been sorted by, add the field to the URL
168 2
        if ( ! in_array( $field_id, $keys = array_keys( $sorts ) ) ) {
169 1
            if ( count( $keys ) ) {
170 1
                $multisort_url = add_query_arg( sprintf( 'sort[%s]', end( $keys ) ), $sorts[ end( $keys ) ], $multisort_url );
171 1
                $multisort_url = add_query_arg( $sort_args[0], $sort_args[1], $multisort_url );
172
            } else {
173 1
                $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 2
            if( '' === $sort_args[1] ) {
181 1
	            unset( $sorts[ $field_id ] );
182
            } else {
183 2
	            $sorts[ $field_id ] = $sort_args[1];
184
            }
185
186 2
            $multisort_url = add_query_arg( array( 'sort' => $sorts ), $multisort_url );
187
        }
188
189 2
		return $multisort_url;
190
	}
191
192
	/**
193
	 * Output the table column names.
194
	 *
195
	 * @return void
196
	 */
197 20
	public function the_columns() {
198 20
		$fields = $this->view->fields->by_position( 'directory_table-columns' );
199
200 20
		foreach ( $fields->by_visible( $this->view )->all() as $field ) {
201 20
			$context = Template_Context::from_template( $this, compact( 'field' ) );
202
203
			$args = array(
204 20
				'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
205
				'hide_empty' => false,
206 20
				'zone_id' => 'directory_table-columns',
207 20
				'markup' => '<th id="{{ field_id }}" class="{{ class }}" style="{{width:style}}" data-label="{{label_value:data-label}}">{{label}}</th>',
208 20
				'label_markup' => '<span class="gv-field-label">{{ label }}</span>',
209 20
				'label' => self::get_field_column_label( $field, $context ),
210
			);
211
212 20
			echo \gravityview_field_output( $args, $context );
213
		}
214 20
	}
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 19
	protected static function get_field_column_label( $field, $context = null ) {
225
226 19
		$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...
227
228
		/**
229
		 * @deprecated Here for back-compatibility.
230
		 */
231 19
		$column_label = apply_filters( 'gravityview_render_after_label', $field->get_label( $context->view, $form ), $field->as_configuration() );
232 19
		$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[in,out] string $column_label The label to override.
238
		 * @param \GV\Template_Context $context The context. Does not have entry set here.
239
		 */
240 19
		$column_label = apply_filters( 'gravityview/template/field/label', $column_label, $context );
241
242 19
		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 17
	public function the_entry( \GV\Entry $entry, $attributes ) {
254
255 17
		$fields = $this->view->fields->by_position( 'directory_table-columns' )->by_visible( $this->view );
256
257 17
		$context = Template_Context::from_template( $this, compact( 'entry', 'fields' ) );
258
259
		/**
260
		 * Push legacy entry context.
261
		 */
262 17
		\GV\Mocks\Legacy_Context::load( array(
263 17
			'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 17
		$fields = apply_filters( 'gravityview_table_cells', $fields->as_configuration(), \GravityView_View::getInstance() );
273 17
		$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 17
		$fields = apply_filters( 'gravityview/template/table/fields', $fields, $context );
282
283 17
		$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 17
		$attributes = apply_filters( 'gravityview/template/table/entry/row/attributes', $attributes, $context );
294
295
		/** Glue the attributes together. */
296 17
		foreach ( $attributes as $attribute => $value ) {
297 17
			$attributes[ $attribute ] = sprintf( "$attribute=\"%s\"", esc_attr( $value ) );
298
		}
299 17
		$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 17
				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 17
                do_action( 'gravityview_table_cells_before', \GravityView_View::getInstance() );
319
320 17
                foreach ( $fields->all() as $field ) {
321 17
					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 17
					$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 17
				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 17
                do_action( 'gravityview_table_cells_after', \GravityView_View::getInstance() );
347
348
				?>
349 17
			</tr>
350
		<?php
351 17
	}
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 16
	public function the_field( \GV\Field $field, \GV\Entry $entry ) {
362 16
		$form = $this->view->form;
363 16
		$single_entry = $entry;
364
365
		/**
366
		 * Push legacy entry context.
367
		 */
368 16
		\GV\Mocks\Legacy_Context::load( array(
369 16
			'field' => $field,
370
		) );
371
372 16
		if ( $entry->is_multi() ) {
373 3
			if ( ! $single_entry = $entry->from_field( $field ) ) {
374
				echo '<td></td>';
375
				return;
376
			}
377 3
			$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...
378
		}
379
380 16
		$renderer = new Field_Renderer();
381 16
		$source = is_numeric( $field->ID ) ? $form : new Internal_Source();
382
383 16
		$value = $renderer->render( $field, $this->view, $source, $entry, $this->request );
384
385 16
		$context = Template_Context::from_template( $this, compact( 'field' ) );
386 16
		$context->entry = $single_entry;
387
388
		$args = array(
389 16
			'entry' => $entry->as_entry(),
390 16
			'field' => is_numeric( $field->ID ) ? $field->as_configuration() : null,
391 16
			'value' => $value,
392
			'hide_empty' => false,
393 16
			'zone_id' => 'directory_table-columns',
394 16
            'label' => self::get_field_column_label( $field, $context ),
395 16
			'markup' => '<td id="{{ field_id }}" class="{{ class }}" data-label="{{label_value:data-label}}">{{ value }}</td>',
396 16
            'form' => $form,
397
		);
398
399
		/** Output. */
400 16
		echo \gravityview_field_output( $args, $context );
401 16
	}
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 19
	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 19
		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 19
		do_action( 'gravityview_table_body_before', \GravityView_View::getInstance() /** ugh! */ );
427 19
	}
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 19
	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 19
		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 19
		do_action( 'gravityview_table_body_after', \GravityView_View::getInstance() /** ugh! */ );
453 19
	}
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 6
	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 6
		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 6
		do_action( 'gravityview_table_tr_before', \GravityView_View::getInstance() /** ugh! */ );
479 6
	}
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 6
	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 6
		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 6
		do_action( 'gravityview_table_tr_after', \GravityView_View::getInstance() /** ugh! */ );
505 6
	}
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 16
	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 16
		$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 16
		return apply_filters( 'gravityview/template/table/entry/class', $class, Template_Context::from_template( $context->template, compact( 'entry' ) ) );
536
	}
537
}
538