Completed
Push — develop ( 0382bd...a61784 )
by Zack
21:58 queued 06:07
created

GravityView_View::getPaging()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 9
ccs 3
cts 3
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/**
3
 * GravityView templating engine class
4
 *
5
 * @package   GravityView
6
 * @license   GPL2+
7
 * @author    Katz Web Services, Inc.
8
 * @link      http://gravityview.co
9
 * @copyright Copyright 2014, Katz Web Services, Inc.
10
 *
11
 * @since 1.0.0
12
 */
13
14
/** If this file is called directly, abort. */
15
if ( ! defined( 'ABSPATH' ) ) {
16
	die;
17
}
18
19
if( ! class_exists( '\GV\Gamajo_Template_Loader' ) ) {
20
	require( GRAVITYVIEW_DIR . 'future/lib/class-gamajo-template-loader.php' );
21
}
22
23
class GravityView_View extends \GV\Gamajo_Template_Loader {
24
25
	/**
26
	 * Prefix for filter names.
27
	 *
28
	 * @var string $filter_prefix
29
	 */
30
	protected $filter_prefix = 'gravityview';
31
32
	/**
33
	 * Directory name where custom templates for this plugin should be found in the theme.
34
	 *
35
	 * @var string $theme_template_directory
36
	 */
37
	protected $theme_template_directory = 'gravityview';
38
39
	/**
40
	 * Reference to the root directory path of this plugin.
41
	 *
42
	 * @var string $plugin_directory
43
	 */
44
	protected $plugin_directory = GRAVITYVIEW_DIR;
45
46
	/**
47
	 * Store templates locations that have already been located
48
	 *
49
	 * @var array $located_templates
50
	 */
51
	protected $located_templates = array();
52
53
	/**
54
	 * The name of the template, like "list", "table", or "datatables"
55
	 *
56
	 * @var string $template_part_slug
57
	 */
58
	protected $template_part_slug = '';
59
60
	/**
61
	 * The name of the file part, like "body" or "single"
62
	 *
63
	 * @var string $template_part_name
64
	 */
65
	protected $template_part_name = '';
66
67
	/**
68
	 * @var int $form_id Gravity Forms form ID
69
	 */
70
	protected $form_id = null;
71
72
	/**
73
	 * @var int $view_id View ID
74
	 * @todo: this needs to be public until extensions support 1.7+
75
	 */
76
	public $view_id = null;
77
78
	/**
79
	 * @var array $fields Fields for the form
80
	 */
81
	protected $fields = array();
82
83
	/**
84
	 * @var string $context Current screen. Defaults to "directory" or "single"
85
	 */
86
	protected $context = 'directory';
87
88
	/**
89
	 * @var int|null $post_id If in embedded post or page, the ID of it
90
	 */
91
	protected $post_id = null;
92
93
	/**
94
	 * @var array $form Gravity Forms form array at ID $form_id
95
	 */
96
	protected $form = null;
97
98
	/**
99
	 * @var array $atts Configuration for the View
100
	 */
101
	protected $atts = array();
102
103
	/**
104
	 * @var array $entries Entries for the current result. Single item in array for single entry View
105
	 */
106
	protected $entries = array();
107
108
	/**
109
	 * @var int $total_entries Total entries count for the current result.
110
	 */
111
	protected $total_entries = 0;
112
113
	/**
114
	 * @var string $back_link_label The label to display back links
115
	 */
116
	protected $back_link_label = '';
117
118
	/**
119
	 * @var array $paging Array with `offset` and `page_size` keys
120
	 */
121
	protected $paging = array();
122
123
	/**
124
	 * @var array $sorting Array with `sort_field` and `sort_direction` keys
125
	 */
126
	protected $sorting = array();
127
128
	/**
129
	 * @var bool $hide_until_searched Whether to hide the results until a search is performed
130
	 * @since 1.5.4
131
	 */
132
	protected $hide_until_searched = false;
133
134
	/**
135
	 * Current entry in the loop
136
	 *
137
	 * @var array $_current_entry
138
	 */
139
	protected $_current_entry = array();
140
141
	/**
142
	 * @var array $_current_field
143
	 */
144
	protected $_current_field = array();
145
146
	/**
147
	 * @var GravityView_View $instance
148
	 */
149
	static $instance = NULL;
150
151
	/**
152
	 * Construct the view object
153
	 * @param  array       $atts Associative array to set the data of
154
	 */
155 111
	function __construct( $atts = array() ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
156
157 111
		$atts = wp_parse_args( $atts, array(
158 111
			'form_id' => NULL,
159
			'view_id' => NULL,
160
			'fields'  => NULL,
161
			'context' => NULL,
162
			'post_id' => NULL,
163
			'form'    => NULL,
164
			'atts'	  => NULL,
165
		) );
166
167 111
		foreach ($atts as $key => $value) {
168 111
			if( is_null( $value ) ) {
169 111
				continue;
170
			}
171 22
			$this->{$key} = $value;
172
		}
173
174
175
		// Add granular overrides
176 111
		add_filter( $this->filter_prefix . '_get_template_part', array( $this, 'add_id_specific_templates' ), 10, 3 );
177
178
		// widget logic
179 111
		add_action( 'gravityview/template/before', array( $this, 'render_widget_hooks' ) );
180 111
		add_action( 'gravityview/template/after', array( $this, 'render_widget_hooks' ) );
181
182
		/**
183
		 * Clear the current entry after the loop is done
184
		 * @since 1.7.3
185
		 */
186 111
		add_action( 'gravityview_footer', array( $this, 'clearCurrentEntry' ), 500 );
187
188 111
		self::$instance = &$this;
189 111
	}
190
191
	/**
192
	 * @param null $passed_post
193
	 *
194
	 * @return GravityView_View
195
	 */
196 150
	static function getInstance( $passed_post = NULL ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
197
198 150
		if( empty( self::$instance ) ) {
199 111
			self::$instance = new self( $passed_post );
200
		}
201
202 150
		return self::$instance;
203
	}
204
205
	/**
206
	 * @param string|null $key The key to a specific attribute of the current field
207
	 * @return array|mixed|null If $key is set and attribute exists at $key, return that. If not set, return NULL. Otherwise, return current field array
208
	 */
209 101
	public function getCurrentField( $key = NULL ) {
210
211 101
		if( !empty( $key ) ) {
212
			if( isset( $this->_current_field[ $key ] ) ) {
213
				return $this->_current_field[ $key ];
214
			}
215
			return NULL;
216
		}
217
218 101
		return $this->_current_field;
219
	}
220
221
	public function setCurrentFieldSetting( $key, $value ) {
222
223
		if( !empty( $this->_current_field ) ) {
224
			$this->_current_field['field_settings'][ $key ] = $value;
225
		}
226
227
	}
228
229
	public function getCurrentFieldSetting( $key ) {
230
		$settings = $this->getCurrentField('field_settings');
231
232
		if( $settings && !empty( $settings[ $key ] ) ) {
233
			return $settings[ $key ];
234
		}
235
236
		return NULL;
237
	}
238
239
	/**
240
	 * @param array $passed_field
241
	 */
242 101
	public function setCurrentField( $passed_field ) {
243
244 101
		$existing_field = $this->getCurrentField();
245
246 101
		$set_field = wp_parse_args( $passed_field, $existing_field );
247
248 101
		$this->_current_field = $set_field;
249
250
		/**
251
		 * Backward compatibility
252
		 * @deprecated 1.6.2
253
		 */
254 101
		$this->field_data = $set_field;
0 ignored issues
show
Bug introduced by
The property field_data does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
255 101
	}
256
257
	/**
258
	 * @param string|null $key The key to a specific field in the fields array
259
	 * @return array|mixed|null If $key is set and field exists at $key, return that. If not set, return NULL. Otherwise, return array of fields.
260
	 */
261 60
	public function getAtts( $key = NULL ) {
262
263 60
		if( !empty( $key ) ) {
264 24
			if( isset( $this->atts[ $key ] ) ) {
265 24
				return $this->atts[ $key ];
266
			}
267
			return NULL;
268
		}
269
270 38
		return $this->atts;
271
	}
272
273
	/**
274
	 * @param array $atts
275
	 */
276 38
	public function setAtts( $atts ) {
277 38
		$this->atts = $atts;
278 38
	}
279
280
	/**
281
	 * @return array
282
	 */
283 123
	public function getForm() {
284 123
		return $this->form;
285
	}
286
287
	/**
288
	 * @param array $form
289
	 */
290 39
	public function setForm( $form ) {
291 39
		$this->form = $form;
292 39
	}
293
294
	/**
295
	 * @return int|null
296
	 */
297 40
	public function getPostId() {
298 40
		return $this->post_id;
299
	}
300
301
	/**
302
	 * @param int|null $post_id
303
	 */
304 38
	public function setPostId( $post_id ) {
305 38
		$this->post_id = $post_id;
306 38
	}
307
308
	/**
309
	 * @return string
310
	 */
311 101
	public function getContext() {
312 101
		return $this->context;
313
	}
314
315
	/**
316
	 * @param string $context
317
	 */
318 38
	public function setContext( $context ) {
319 38
		$this->context = $context;
320 38
	}
321
322
	/**
323
	 * @param string|null $key The key to a specific field in the fields array
324
	 * @return array|mixed|null If $key is set and field exists at $key, return that. If not set, return NULL. Otherwise, return array of fields.
325
	 */
326 38
	public function getFields( $key = null ) {
327
328 38
		$fields = empty( $this->fields ) ? NULL : $this->fields;
329
330 38
		if( $fields && !empty( $key ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fields of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
331 1
			$fields = isset( $fields[ $key ] ) ? $fields[ $key ] : NULL;
332
		}
333
334 38
		return $fields;
335
	}
336
337
	/**
338
     * Get the fields for a specific context
339
     *
340
     * @since 1.19.2
341
     *
342
	 * @param string $context [Optional] "directory", "single", or "edit"
343
	 *
344
	 * @return array Array of GravityView field layout configurations
345
	 */
346 2
	public function getContextFields( $context = '' ) {
347
348 2
	    if( '' === $context ) {
349 2
	        $context = $this->getContext();
350
        }
351
352 2
		$fields = $this->getFields();
353
354 2
        foreach ( (array) $fields as $key => $context_fields ) {
355
356
            // Formatted as `{context}_{template id}-{zone name}`, so we want just the $context to match against
357 2
            $matches = explode( '_', $key );
358
359 2
            if( isset( $matches[0] ) && $matches[0] === $context ) {
360 2
                return $context_fields;
361
            }
362
        }
363
364
		return array();
365
    }
366
367
	/**
368
	 * @param array $fields
369
	 */
370 37
	public function setFields( $fields ) {
371 37
		$this->fields = $fields;
372 37
	}
373
374
	/**
375
	 * @param string $key The key to a specific field in the fields array
376
	 * @return array|mixed|null If $key is set and field exists at $key, return that. If not set, return NULL. Otherwise, return array of fields.
377
	 */
378 2
	public function getField( $key ) {
379
380 2
		if( !empty( $key ) ) {
381 2
			if( isset( $this->fields[ $key ] ) ) {
382 2
				return $this->fields[ $key ];
383
			}
384
		}
385
386 1
		return NULL;
387
	}
388
389
	/**
390
	 * @param string $key The key to a specific field in the fields array
391
	 * @param mixed $value The value to set for the field
392
	 */
393
	public function setField( $key, $value ) {
394
		$this->fields[ $key ] = $value;
395
	}
396
397
	/**
398
	 * @return int
399
	 */
400 61
	public function getViewId() {
401 61
		return absint( $this->view_id );
402
	}
403
404
	/**
405
	 * @param int $view_id
406
	 */
407 38
	public function setViewId( $view_id ) {
408 38
		$this->view_id = intval( $view_id );
409 38
	}
410
411
	/**
412
	 * @return int
413
	 */
414 38
	public function getFormId() {
415 38
		return $this->form_id;
416
	}
417
418
	/**
419
	 * @param int $form_id
420
	 */
421 38
	public function setFormId( $form_id ) {
422 38
		$this->form_id = $form_id;
423 38
	}
424
425
	/**
426
	 * @return array
427
	 */
428 78
	public function getEntries() {
429 78
		return $this->entries;
430
	}
431
432
	/**
433
	 * @param array $entries
434
	 */
435 38
	public function setEntries( $entries ) {
436 38
		$this->entries = $entries;
437 38
	}
438
439
	/**
440
	 * @return int
441
	 */
442 39
	public function getTotalEntries() {
443 39
		return (int)$this->total_entries;
444
	}
445
446
	/**
447
	 * @param int $total_entries
448
	 */
449 39
	public function setTotalEntries( $total_entries ) {
450 39
		$this->total_entries = intval( $total_entries );
451 39
	}
452
453
	/**
454
	 * @return array
455
	 */
456 39
	public function getPaging() {
457
458
	    $default_params = array(
459 39
            'offset' => 0,
460
            'page_size' => 20,
461
        );
462
463 39
		return wp_parse_args( $this->paging, $default_params );
464
	}
465
466
	/**
467
	 * @param array $paging
468
	 */
469 38
	public function setPaging( $paging ) {
470 38
		$this->paging = $paging;
471 38
	}
472
473
	/**
474
	 * Get an array with pagination information
475
	 *
476
	 * @since 1.13
477
	 *
478
	 * @return array {
479
	 *  @type int $first The starting entry number (counter, not ID)
480
	 *  @type int $last The last displayed entry number (counter, not ID)
481
	 *  @type int $total The total number of entries
482
	 * }
483
	 */
484 2
	public function getPaginationCounts() {
485
486 2
		$paging = $this->getPaging();
487 2
		$offset = $paging['offset'];
488 2
		$page_size = $paging['page_size'];
489 2
		$total = $this->getTotalEntries();
490
491 2
		if ( empty( $total ) ) {
492 1
			gravityview()->log->debug( 'No entries. Returning empty array.' );
493
494 1
			return array();
495
		}
496
497 2
		$first = empty( $offset ) ? 1 : $offset + 1;
498
499
		// If the page size + starting entry is larger than total, the total is the max.
500 2
		$last = ( $offset + $page_size > $total ) ? $total : $offset + $page_size;
501
502
		/**
503
		 * @filter `gravityview_pagination_counts` Modify the displayed pagination numbers
504
		 * @since 1.13
505
		 * @param array $counts Array with $first, $last, $total numbers in that order
506
		 */
507 2
		list( $first, $last, $total ) = apply_filters( 'gravityview_pagination_counts', array( $first, $last, $total ) );
508
509 2
		return array( 'first' => (int) $first, 'last' => (int) $last, 'total' => (int) $total );
510
	}
511
512
	/**
513
	 * @return array
514
	 */
515 38
	public function getSorting() {
516
517
		$defaults_params = array(
518 38
            'sort_field' => 'date_created',
519
            'sort_direction' => 'ASC',
520
            'is_numeric' => false,
521
        );
522
523 38
		return wp_parse_args( $this->sorting, $defaults_params );
524
	}
525
526
	/**
527
	 * @param array $sorting
528
	 */
529 76
	public function setSorting( $sorting ) {
530 76
		$this->sorting = $sorting;
531 76
	}
532
533
	/**
534
	 * @param boolean $do_replace Perform merge tag and shortcode processing on the label. Default: true.
535
	 * @since 2.0
536
	 *
537
	 * @deprecated Use $template->get_back_label();
538
	 *
539
	 * @return string
540
	 */
541 39
	public function getBackLinkLabel( $do_replace = true ) {
542 39
		if ( $do_replace ) {
543 2
			$back_link_label = GravityView_API::replace_variables( $this->back_link_label, $this->getForm(), $this->getCurrentEntry() );
544 2
			return do_shortcode( $back_link_label );
545
		}
546
547 38
		return $this->back_link_label;
548
	}
549
550
	/**
551
	 * @param string $back_link_label
552
	 */
553 39
	public function setBackLinkLabel( $back_link_label ) {
554 39
		$this->back_link_label = $back_link_label;
555 39
	}
556
557
	/**
558
	 * @return boolean
559
	 */
560 38
	public function isHideUntilSearched() {
561 38
		return $this->hide_until_searched;
562
	}
563
564
	/**
565
	 * @param boolean $hide_until_searched
566
	 */
567 38
	public function setHideUntilSearched( $hide_until_searched ) {
568 38
		$this->hide_until_searched = $hide_until_searched;
569 38
	}
570
571
	/**
572
	 * @return string
573
	 */
574 2
	public function getTemplatePartSlug() {
575 2
		return $this->template_part_slug;
576
	}
577
578
	/**
579
	 * @param string $template_part_slug
580
	 */
581 6
	public function setTemplatePartSlug( $template_part_slug ) {
582 6
		$this->template_part_slug = $template_part_slug;
583 6
	}
584
585
	/**
586
	 * @return string
587
	 */
588
	public function getTemplatePartName() {
589
		return $this->template_part_name;
590
	}
591
592
	/**
593
	 * @param string $template_part_name
594
	 */
595 6
	public function setTemplatePartName( $template_part_name ) {
596 6
		$this->template_part_name = $template_part_name;
597 6
	}
598
599
	/**
600
	 * Return the current entry. If in the loop, the current entry. If single entry, the currently viewed entry.
601
	 * @return array
602
	 */
603 101
	public function getCurrentEntry() {
604
605 101
		if( in_array( $this->getContext(), array( 'edit', 'single') ) ) {
606 30
			$entries = $this->getEntries();
607 30
			$entry = $entries[0];
608
		} else {
609 82
			$entry = $this->_current_entry;
610
		}
611
612
		/** @since 1.16 Fixes DataTables empty entry issue */
613 101
		if ( empty( $entry ) && ! empty( $this->_current_field['entry'] ) ) {
614 11
			$entry = $this->_current_field['entry'];
615
		}
616
617 101
		return $entry;
618
	}
619
620
	/**
621
	 * @param array $current_entry
622
	 * @return void
623
	 */
624 39
	public function setCurrentEntry( $current_entry ) {
625 39
		$this->_current_entry = $current_entry;
626 39
	}
627
628
	/**
629
	 * Clear the current entry after all entries in the loop have been displayed.
630
	 *
631
	 * @since 1.7.3
632
	 * @return void
633
	 */
634 29
	public function clearCurrentEntry() {
635 29
		$this->_current_entry = NULL;
636 29
	}
637
638
	/**
639
	 * Render an output zone, as configured in the Admin
640
	 *
641
	 * @since 1.16.4 Added $echo parameter
642
	 *
643
	 * @param string $zone The zone name, like 'footer-left'
644
	 * @param array $atts
645
	 * @param bool $echo Whether to print the output
646
	 *
647
	 * @deprecated This will never get called in new templates.
648
	 *
649
	 * @return string|null
650
	 */
651 2
	public function renderZone( $zone = '', $atts = array(), $echo = true ) {
652
653 2
		if ( empty( $zone ) ) {
654
			gravityview()->log->error( 'No zone defined.');
655
			return NULL;
656
		}
657
658
		$defaults = array(
659 2
			'slug' => $this->getTemplatePartSlug(),
660 2
			'context' => $this->getContext(),
661 2
			'entry' => $this->getCurrentEntry(),
662 2
			'form' => $this->getForm(),
663 2
			'hide_empty' => $this->getAtts('hide_empty'),
664
		);
665
666 2
		$final_atts = wp_parse_args( $atts, $defaults );
667
668 2
		$output = '';
669
670 2
		$final_atts['zone_id'] = "{$final_atts['context']}_{$final_atts['slug']}-{$zone}";
671
672 2
		$fields = $this->getField( $final_atts['zone_id'] );
673
674
		// Backward compatibility
675 2
		if ( 'table' === $this->getTemplatePartSlug() ) {
676
			/**
677
			 * @filter `gravityview_table_cells` Modify the fields displayed in a table
678
			 * @param array $fields
679
			 * @param \GravityView_View $this
680
			 * @deprecated Use `gravityview/template/table/fields`
681
			 */
682 1
			$fields = apply_filters("gravityview_table_cells", $fields, $this );
683
		}
684
685 2
		if ( empty( $fields ) ) {
686
687 1
			gravityview()->log->error( 'Empty zone configuration for {zone_id}.', array( 'zone_id' => $final_atts['zone_id'] ) );
688
689 1
			return NULL;
690
		}
691
692 2
		$field_output = '';
693 2
		foreach ( $fields as $field ) {
694 2
			$final_atts['field'] = $field;
695
696 2
			$field_output .= gravityview_field_output( $final_atts );
697
		}
698
699
		/**
700
		 * If a zone has no field output, choose whether to show wrapper
701
		 * False by default to keep backward compatibility
702
		 * @since 1.7.6
703
		 * @param boolean $hide_empty_zone Default: false
704
		 * @since 2.0
705
		 * @param \GV\Template_Context $context The context. Null here. Since this path is deprecated.
706
		 */
707 2
		if ( empty( $field_output ) && apply_filters( 'gravityview/render/hide-empty-zone', false, null ) ) {
708
			return NULL;
709
		}
710
711 2
		if( !empty( $final_atts['wrapper_class'] ) ) {
712 1
			$output .= '<div class="'.gravityview_sanitize_html_class( $final_atts['wrapper_class'] ).'">';
713
		}
714
715 2
		$output .= $field_output;
716
717 2
		if( !empty( $final_atts['wrapper_class'] ) ) {
718 1
			$output .= '</div>';
719
		}
720
721 2
		if( $echo ) {
722 2
			echo $output;
723
		}
724
725 2
		return $output;
726
	}
727
728
	/**
729
	 * In order to improve lookup times, we store located templates in a local array.
730
	 *
731
	 * This improves performance by up to 1/2 second on a 250 entry View with 7 columns showing
732
	 *
733
	 * @inheritdoc
734
	 * @see Gamajo_Template_Loader::locate_template()
735
	 * @return null|string NULL: Template not found; String: path to template
736
	 */
737 4
	function locate_template( $template_names, $load = false, $require_once = true ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
738
739 4
		if( is_string( $template_names ) && isset( $this->located_templates[ $template_names ] ) ) {
740
741
			$located = $this->located_templates[ $template_names ];
742
743
		} else {
744
745
			// Set $load to always false so we handle it here.
746 4
			$located = parent::locate_template( $template_names, false, $require_once );
747
748 4
			if( is_string( $template_names ) ) {
749
				$this->located_templates[ $template_names ] = $located;
750
			}
751
		}
752
753 4
		if ( $load && $located ) {
754
			load_template( $located, $require_once );
755
		}
756
757 4
		return $located;
758
	}
759
760
	/**
761
	 * Magic Method: Instead of throwing an error when a variable isn't set, return null.
762
	 * @param  string      $name Key for the data retrieval.
763
	 * @return mixed|null    The stored data.
764
	 */
765 3
	public function __get( $name ) {
766 3
		if( isset( $this->{$name} ) ) {
767 1
			return $this->{$name};
768
		} else {
769 2
			return NULL;
770
		}
771
	}
772
773
	/**
774
	 * Enable overrides of GravityView templates on a granular basis
775
	 *
776
	 * The loading order is:
777
	 *
778
	 * - view-[View ID]-table-footer.php
779
	 * - form-[Form ID]-table-footer.php
780
	 * - page-[ID of post or page where view is embedded]-table-footer.php
781
	 * - table-footer.php
782
	 *
783
	 * @see  Gamajo_Template_Loader::get_template_file_names() Where the filter is
784
	 * @param array $templates Existing list of templates.
785
	 * @param string $slug      Name of the template base, example: `table`, `list`, `datatables`, `map`
786
	 * @param string $name      Name of the template part, example: `body`, `footer`, `head`, `single`
787
	 *
788
	 * @return array $templates Modified template array, merged with existing $templates values
789
	 */
790 34
	function add_id_specific_templates( $templates, $slug, $name ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
791
792 34
		$additional = array();
793
794
		// form-19-table-body.php
795 34
		$additional[] = sprintf( 'form-%d-%s-%s.php', $this->getFormId(), $slug, $name );
796
797 34
		if( $view_id = $this->getViewId() ) {
798
			// view-3-table-body.php
799 30
			$additional[] = sprintf( 'view-%d-%s-%s.php', $view_id, $slug, $name );
800
		}
801
802 34
		if( $this->getPostId() ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->getPostId() of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
803
804
			// page-19-table-body.php
805 28
			$additional[] = sprintf( 'page-%d-%s-%s.php', $this->getPostId(), $slug, $name );
806
		}
807
808
		// Combine with existing table-body.php and table.php
809 34
		$templates = array_merge( $additional, $templates );
810
811 34
		gravityview()->log->debug( 'List of Template Files', array( 'data' => $templates ) );
812
813 34
		return $templates;
814
	}
815
816
	// Load the template
817 4
	public function render( $slug, $name, $require_once = true ) {
818
819 4
		$this->setTemplatePartSlug( $slug );
820
821 4
		$this->setTemplatePartName( $name );
822
823 4
		$template_file = $this->get_template_part( $slug, $name, false );
824
825 4
		gravityview()->log->debug( 'Rendering Template File: {path}', array( 'path' => $template_file ) );
826
827 4
		if( !empty( $template_file) ) {
828
829 4
			if ( $require_once ) {
830
				require_once( $template_file );
831
			} else {
832 4
				require( $template_file );
833
			}
834
835
		}
836 4
	}
837
838
	/**
839
	 * Output the widgets on before/after hooks.
840
	 *
841
	 * @param int|\GV\Template_Context $view_id_or_context The View ID or the context.
842
	 *
843
	 * @return void
844
	 */
845 33
	public function render_widget_hooks( $view_id_or_context ) {
846
847
	    /**
848
		 * @deprecated Numeric argument is deprecated. Pass a \GV\Template_Context instead.
849
		 */
850 33
		if ( is_numeric( $view_id_or_context ) ) {
851 4
			$view = \GV\View::by_id( $view_id_or_context );
852 4
			$is_single = gravityview_get_context() == 'single';
0 ignored issues
show
Deprecated Code introduced by
The function gravityview_get_context() has been deprecated with message: since 2.0.6.2 Use `gravityview()->request`

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
853 4
			$total_entries = GravityView_View::getInstance()->getTotalEntries();
854
855
			/**
856
			 * Fake new context for legacy template code.
857
			 */
858 4
			$view_id_or_context = \GV\Template_Context::from_template( array(
859 4
				'view' => $view,
860
			) );
861
862 31
		} else if ( $view_id_or_context instanceof \GV\Template_Context ) {
863 31
			$view = $view_id_or_context->view;
864 31
			$is_single = (boolean)$view_id_or_context->request->is_entry();
865 31
			$total_entries = $view_id_or_context->entries ? $view_id_or_context->entries->count() : 0;
866
867
		} else {
868
			gravityview()->log->error( 'No View ID or template context provided to render_widget_hooks' );
869
			return;
870
		}
871
872 33
		if ( $is_single ) {
873 9
			gravityview()->log->debug( 'Not rendering widgets; single entry' );
874 9
			return;
875
		}
876
877 26
		switch ( current_filter() ) {
878
			default:
879 26
			case 'gravityview/template/before':
880 26
			case 'gravityview_before':
881 26
				$zone = 'header';
882 26
				break;
883 26
			case 'gravityview/template/after':
884 4
			case 'gravityview_after':
885 26
				$zone = 'footer';
886 26
				break;
887
		}
888
889 26
		$widgets = $view->widgets->by_position( "$zone*" );
890
891
		/**
892
		 * Prevent output if no widgets to show.
893
		 * @since 1.16
894
		 */
895 26
		if ( ! $widgets->count() ) {
896 23
			gravityview()->log->debug( 'No widgets for View #{view_id} in zone {zone}', array( 'view_id' => $view->ID, 'zone' => $zone ) );
897 23
			return;
898
		}
899
900
		// Prevent being called twice
901 5
		if ( did_action( "gravityview/widgets/$zone/{$view->ID}/rendered" ) ) {
902
			gravityview()->log->debug( 'Not rendering {zone}; already rendered', array( 'zone' => $zone.'_'.$view->ID.'_widgets' ) );
903
			return;
904
		}
905
906 5
		$rows = \GV\Widget::get_default_widget_areas();
907
908
		// TODO: Move to sep. method, use an action instead
909 5
		wp_enqueue_style( 'gravityview_default_style' );
910
911 5
		$default_css_class = 'gv-grid gv-widgets-' . $zone;
912
913 5
		if ( ! $total_entries ) {
914 3
			$default_css_class .= ' gv-widgets-no-results';
915
		}
916
917
		/**
918
		 * @filter `gravityview/widgets/wrapper_css_class` The CSS class applied to the widget container `<div>`.
919
		 * @since 1.16.2
920
		 * @param string $css_class Default: `gv-grid gv-widgets-{zone}` where `{zone}` is replaced by the current `$zone` value. If the View has no results, adds ` gv-widgets-no-results`
921
		 * @param string $zone Current widget zone, either `header` or `footer`
922
		 * @param array $widgets Array of widget configurations for the current zone, as set by `gravityview_get_current_view_data()['widgets']`
923
		 */
924 5
		$css_class = apply_filters('gravityview/widgets/wrapper_css_class', $default_css_class, $zone, $widgets->as_configuration() );
925
926 5
		$css_class = gravityview_sanitize_html_class( $css_class );
927
928
		// TODO Convert to partials
929
		?>
930
		<div class="<?php echo $css_class; ?>">
931
			<?php
932 5
			foreach( $rows as $row ) {
933 5
				foreach( $row as $col => $areas ) {
934 5
					$column = ( $col == '2-2' ) ? '1-2 gv-right' : "$col gv-left";
935
				?>
936
					<div class="gv-grid-col-<?php echo esc_attr( $column ); ?>">
937
						<?php
938 5
						if ( ! empty( $areas ) ) {
939 5
							foreach ( $areas as $area ) {
940 5
								foreach ( $widgets->by_position( $zone . '_' . $area['areaid'] )->all() as $widget ) {
941 5
									do_action( sprintf( 'gravityview/widgets/%s/render', $widget->get_widget_id() ), $widget->configuration->all(), null, $view_id_or_context );
942
								}
943
							}
944
						} ?>
945 5
					</div>
946
				<?php } // $row ?>
947
			<?php } // $rows ?>
948 5
		</div>
949
950
		<?php
951
952
		/**
953
		 * Prevent widgets from being called twice.
954
		 * Checking for loop_start prevents themes and plugins that pre-process shortcodes from triggering the action before displaying. Like, ahem, the Divi theme and WordPress SEO plugin
955
		 */
956 5
		if ( did_action( 'wp_head' ) ) {
957
			do_action( "gravityview/widgets/$zone/{$view->ID}/rendered" );
958
		}
959 5
	}
960
961
	/**
962
	 * Include a file inside this context.
963
	 *
964
	 * @param string $path A path to the legacy template to include.
965
	 *
966
	 * @return void
967
	 */
968 2
	public function _include( $path ) {
969 2
		if ( file_exists( $path ) ) {
970 2
			include $path;
971
		}
972 2
	}
973
974
}
975
976