Completed
Pull Request — develop (#1444)
by Zack
06:23
created

GravityView_View::clearCurrentEntry()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

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 3
ccs 3
cts 3
cp 1
crap 1
rs 10
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 109
	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 109
		$atts = wp_parse_args( $atts, array(
158 109
			'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 109
		foreach ($atts as $key => $value) {
168 109
			if( is_null( $value ) ) {
169 109
				continue;
170
			}
171 22
			$this->{$key} = $value;
172
		}
173
174
175
		// Add granular overrides
176 109
		add_filter( $this->filter_prefix . '_get_template_part', array( $this, 'add_id_specific_templates' ), 10, 3 );
177
178
		// widget logic
179 109
		add_action( 'gravityview/template/before', array( $this, 'render_widget_hooks' ) );
180 109
		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 109
		add_action( 'gravityview_footer', array( $this, 'clearCurrentEntry' ), 500 );
187
188 109
		self::$instance = &$this;
189 109
	}
190
191
	/**
192
	 * @param null $passed_post
193
	 *
194
	 * @return GravityView_View
195
	 */
196 151
	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 151
		if( empty( self::$instance ) ) {
199 109
			self::$instance = new self( $passed_post );
200
		}
201
202 151
		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 87
	public function getCurrentField( $key = NULL ) {
210
211 87
		if( !empty( $key ) ) {
212
			if( isset( $this->_current_field[ $key ] ) ) {
213
				return $this->_current_field[ $key ];
214
			}
215
			return NULL;
216
		}
217
218 87
		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 78
	public function setCurrentField( $passed_field ) {
243
244 78
		$existing_field = $this->getCurrentField();
245
246 78
		$set_field = wp_parse_args( $passed_field, $existing_field );
247
248 78
		$this->_current_field = $set_field;
249
250
		/**
251
		 * Backward compatibility
252
		 * @deprecated 1.6.2
253
		 */
254 78
		$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 78
	}
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 57
	public function getAtts( $key = NULL ) {
262
263 57
		if( !empty( $key ) ) {
264 23
			if( isset( $this->atts[ $key ] ) ) {
265 23
				return $this->atts[ $key ];
266
			}
267
			return NULL;
268
		}
269
270 35
		return $this->atts;
271
	}
272
273
	/**
274
	 * @param array $atts
275
	 */
276 35
	public function setAtts( $atts ) {
277 35
		$this->atts = $atts;
278 35
	}
279
280
	/**
281
	 * @return array
282
	 */
283 109
	public function getForm() {
284 109
		return $this->form;
285
	}
286
287
	/**
288
	 * @param array $form
289
	 */
290 36
	public function setForm( $form ) {
291 36
		$this->form = $form;
292 36
	}
293
294
	/**
295
	 * @return int|null
296
	 */
297 37
	public function getPostId() {
298 37
		return $this->post_id;
299
	}
300
301
	/**
302
	 * @param int|null $post_id
303
	 */
304 29
	public function setPostId( $post_id ) {
305 29
		$this->post_id = $post_id;
306 29
	}
307
308
	/**
309
	 * @return string
310
	 */
311 87
	public function getContext() {
312 87
		return $this->context;
313
	}
314
315
	/**
316
	 * @param string $context
317
	 */
318 35
	public function setContext( $context ) {
319 35
		$this->context = $context;
320 35
	}
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 35
	public function getFields( $key = null ) {
327
328 35
		$fields = empty( $this->fields ) ? NULL : $this->fields;
329
330 35
		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 35
		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 25
	public function setFields( $fields ) {
371 25
		$this->fields = $fields;
372 25
	}
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 1
	public function getField( $key ) {
379
380 1
		if( !empty( $key ) ) {
381 1
			if( isset( $this->fields[ $key ] ) ) {
382 1
				return $this->fields[ $key ];
383
			}
384
		}
385
386
		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 58
	public function getViewId() {
401 58
		return absint( $this->view_id );
402
	}
403
404
	/**
405
	 * @param int $view_id
406
	 */
407 35
	public function setViewId( $view_id ) {
408 35
		$this->view_id = intval( $view_id );
409 35
	}
410
411
	/**
412
	 * @return int
413
	 */
414 35
	public function getFormId() {
415 35
		return $this->form_id;
416
	}
417
418
	/**
419
	 * @param int $form_id
420
	 */
421 35
	public function setFormId( $form_id ) {
422 35
		$this->form_id = $form_id;
423 35
	}
424
425
	/**
426
	 * @return array
427
	 */
428 57
	public function getEntries() {
429 57
		return $this->entries;
430
	}
431
432
	/**
433
	 * @param array $entries
434
	 */
435 35
	public function setEntries( $entries ) {
436 35
		$this->entries = $entries;
437 35
	}
438
439
	/**
440
	 * @return int
441
	 */
442 36
	public function getTotalEntries() {
443 36
		return (int)$this->total_entries;
444
	}
445
446
	/**
447
	 * @param int $total_entries
448
	 */
449 36
	public function setTotalEntries( $total_entries ) {
450 36
		$this->total_entries = intval( $total_entries );
451 36
	}
452
453
	/**
454
	 * @return array
455
	 */
456 36
	public function getPaging() {
457
458
	    $default_params = array(
459 36
            'offset' => 0,
460
            'page_size' => 20,
461
        );
462
463 36
		return wp_parse_args( $this->paging, $default_params );
464
	}
465
466
	/**
467
	 * @param array $paging
468
	 */
469 31
	public function setPaging( $paging ) {
470 31
		$this->paging = $paging;
471 31
	}
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 2
			gravityview()->log->debug( 'No entries. Returning empty array.' );
493
494 2
			return array();
495
		}
496
497 1
		$first = empty( $offset ) ? 1 : $offset + 1;
498
499
		// If the page size + starting entry is larger than total, the total is the max.
500 1
		$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 1
		list( $first, $last, $total ) = apply_filters( 'gravityview_pagination_counts', array( $first, $last, $total ) );
508
509 1
		return array( 'first' => (int) $first, 'last' => (int) $last, 'total' => (int) $total );
510
	}
511
512
	/**
513
	 * @return array
514
	 */
515 35
	public function getSorting() {
516
517
		$defaults_params = array(
518 35
            'sort_field' => 'date_created',
519
            'sort_direction' => 'ASC',
520
            'is_numeric' => false,
521
        );
522
523 35
		return wp_parse_args( $this->sorting, $defaults_params );
524
	}
525
526
	/**
527
	 * @param array $sorting
528
	 */
529 73
	public function setSorting( $sorting ) {
530 73
		$this->sorting = $sorting;
531 73
	}
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 36
	public function getBackLinkLabel( $do_replace = true ) {
542 36
		if ( $do_replace ) {
543 1
			$back_link_label = GravityView_API::replace_variables( $this->back_link_label, $this->getForm(), $this->getCurrentEntry() );
544 1
			return do_shortcode( $back_link_label );
545
		}
546
547 35
		return $this->back_link_label;
548
	}
549
550
	/**
551
	 * @param string $back_link_label
552
	 */
553 36
	public function setBackLinkLabel( $back_link_label ) {
554 36
		$this->back_link_label = $back_link_label;
555 36
	}
556
557
	/**
558
	 * @return boolean
559
	 */
560 35
	public function isHideUntilSearched() {
561 35
		return $this->hide_until_searched;
562
	}
563
564
	/**
565
	 * @param boolean $hide_until_searched
566
	 */
567 35
	public function setHideUntilSearched( $hide_until_searched ) {
568 35
		$this->hide_until_searched = $hide_until_searched;
569 35
	}
570
571
	/**
572
	 * @return string
573
	 */
574 1
	public function getTemplatePartSlug() {
575 1
		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 87
	public function getCurrentEntry() {
604
605 87
		if( in_array( $this->getContext(), array( 'edit', 'single') ) ) {
606 5
			$entries = $this->getEntries();
607 5
			$entry = $entries[0];
608
		} else {
609 87
			$entry = $this->_current_entry;
610
		}
611
612
		/** @since 1.16 Fixes DataTables empty entry issue */
613 87
		if ( empty( $entry ) && ! empty( $this->_current_field['entry'] ) ) {
614
			$entry = $this->_current_field['entry'];
615
		}
616
617 87
		return $entry;
618
	}
619
620
	/**
621
	 * @param array $current_entry
622
	 * @return void
623
	 */
624 31
	public function setCurrentEntry( $current_entry ) {
625 31
		$this->_current_entry = $current_entry;
626 31
	}
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 19
	public function clearCurrentEntry() {
635 19
		$this->_current_entry = NULL;
636 19
	}
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 1
	public function renderZone( $zone = '', $atts = array(), $echo = true ) {
652
653 1
		if ( empty( $zone ) ) {
654
			gravityview()->log->error( 'No zone defined.');
655
			return NULL;
656
		}
657
658
		$defaults = array(
659 1
			'slug' => $this->getTemplatePartSlug(),
660 1
			'context' => $this->getContext(),
661 1
			'entry' => $this->getCurrentEntry(),
662 1
			'form' => $this->getForm(),
663 1
			'hide_empty' => $this->getAtts('hide_empty'),
664
		);
665
666 1
		$final_atts = wp_parse_args( $atts, $defaults );
667
668 1
		$output = '';
669
670 1
		$final_atts['zone_id'] = "{$final_atts['context']}_{$final_atts['slug']}-{$zone}";
671
672 1
		$fields = $this->getField( $final_atts['zone_id'] );
673
674
		// Backward compatibility
675 1
		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 1
		if ( empty( $fields ) ) {
686
687
			gravityview()->log->error( 'Empty zone configuration for {zone_id}.', array( 'zone_id' => $final_atts['zone_id'] ) );
688
689
			return NULL;
690
		}
691
692 1
		$field_output = '';
693 1
		foreach ( $fields as $field ) {
694 1
			$final_atts['field'] = $field;
695
696 1
			$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 1
		if ( empty( $field_output ) && apply_filters( 'gravityview/render/hide-empty-zone', false, null ) ) {
708
			return NULL;
709
		}
710
711 1
		if( !empty( $final_atts['wrapper_class'] ) ) {
712
			$output .= '<div class="'.gravityview_sanitize_html_class( $final_atts['wrapper_class'] ).'">';
713
		}
714
715 1
		$output .= $field_output;
716
717 1
		if( !empty( $final_atts['wrapper_class'] ) ) {
718
			$output .= '</div>';
719
		}
720
721 1
		if( $echo ) {
722 1
			echo $output;
723
		}
724
725 1
		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 5
	public function __get( $name ) {
766 5
		if( isset( $this->{$name} ) ) {
767 1
			return $this->{$name};
768
		} else {
769 4
			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 32
	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 32
		$additional = array();
793
794
		// form-19-table-body.php
795 32
		$additional[] = sprintf( 'form-%d-%s-%s.php', $this->getFormId(), $slug, $name );
796
797 32
		if( $view_id = $this->getViewId() ) {
798
			// view-3-table-body.php
799 27
			$additional[] = sprintf( 'view-%d-%s-%s.php', $view_id, $slug, $name );
800
		}
801
802 32
		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 27
			$additional[] = sprintf( 'page-%d-%s-%s.php', $this->getPostId(), $slug, $name );
806
		}
807
808
		// Combine with existing table-body.php and table.php
809 32
		$templates = array_merge( $additional, $templates );
810
811 32
		gravityview()->log->debug( 'List of Template Files', array( 'data' => $templates ) );
812
813 32
		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 31
	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 31
		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 29
		} else if ( $view_id_or_context instanceof \GV\Template_Context ) {
863 29
			$view = $view_id_or_context->view;
864 29
			$is_single = (boolean)$view_id_or_context->request->is_entry();
865 29
			$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 31
		if ( $is_single ) {
873 5
			gravityview()->log->debug( 'Not rendering widgets; single entry' );
874 5
			return;
875
		}
876
877 26
		switch ( current_filter() ) {
878
			default:
879 26
			case 'gravityview/template/before':
880 20
			case 'gravityview_before':
881 26
				$zone = 'header';
882 26
				break;
883 20
			case 'gravityview/template/after':
884 4
			case 'gravityview_after':
885 20
				$zone = 'footer';
886 20
				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 5
			$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