Completed
Push — develop ( 82fa3b...268ce1 )
by Gennady
14:11
created

GravityView_View::__get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 7
ccs 3
cts 4
cp 0.75
crap 2.0625
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
	 * @var string
28
	 */
29
	protected $filter_prefix = 'gravityview';
30
31
	/**
32
	 * Directory name where custom templates for this plugin should be found in the theme.
33
	 * @var string
34
	 */
35
	protected $theme_template_directory = 'gravityview';
36
37
	/**
38
	 * Reference to the root directory path of this plugin.
39
	 * @var string
40
	 */
41
	protected $plugin_directory = GRAVITYVIEW_DIR;
42
43
	/**
44
	 * Store templates locations that have already been located
45
	 * @var array
46
	 */
47
	protected $located_templates = array();
48
49
	/**
50
	 * The name of the template, like "list", "table", or "datatables"
51
	 * @var string
52
	 */
53
	protected $template_part_slug = '';
54
55
	/**
56
	 * The name of the file part, like "body" or "single"
57
	 * @var string
58
	 */
59
	protected $template_part_name = '';
60
61
	/**
62
	 * @var int Gravity Forms form ID
63
	 */
64
	protected $form_id = NULL;
65
66
	/**
67
	 * @var int View ID
68
	 * @todo: this needs to be public until extensions support 1.7+
69
	 */
70
	public $view_id = NULL;
71
72
	/**
73
	 * @var array Fields for the form
74
	 */
75
	protected $fields = array();
76
77
	/**
78
	 * @var string Current screen. Defaults to "directory" or "single"
79
	 */
80
	protected $context = 'directory';
81
82
	/**
83
	 * @var int|null If in embedded post or page, the ID of it
84
	 */
85
	protected $post_id = NULL;
86
87
	/**
88
	 * @var array Gravity Forms form array at ID $form_id
89
	 */
90
	protected $form = NULL;
91
92
	/**
93
	 * @var array Configuration for the View
94
	 */
95
	protected $atts = array();
96
97
	/**
98
	 * @var array Entries for the current result. Single item in array for single entry View
99
	 */
100
	protected $entries = array();
101
102
	/**
103
	 * @var int Total entries count for the current result.
104
	 */
105
	protected $total_entries = 0;
106
107
	/**
108
	 * @var string The label to display back links
109
	 */
110
	protected $back_link_label = '';
111
112
	/**
113
	 * @var array Array with `offset` and `page_size` keys
114
	 */
115
	protected $paging = array();
116
117
	/**
118
	 * @var array Array with `sort_field` and `sort_direction` keys
119
	 */
120
	protected $sorting = array();
121
122
	/**
123
	 * @var bool Whether to hide the results until a search is performed
124
	 * @since 1.5.4
125
	 */
126
	protected $hide_until_searched = false;
127
128
	/**
129
	 * Current entry in the loop
130
	 * @var array
131
	 */
132
	protected $_current_entry = array();
133
134
	/**
135
	 * @var array
136
	 */
137
	protected $_current_field = array();
138
139
	/**
140
	 * @var GravityView_View
141
	 */
142
	static $instance = NULL;
143
144
	/**
145
	 * Construct the view object
146
	 * @param  array       $atts Associative array to set the data of
147
	 */
148 100
	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...
149
150 100
		$atts = wp_parse_args( $atts, array(
151 100
			'form_id' => NULL,
152
			'view_id' => NULL,
153
			'fields'  => NULL,
154
			'context' => NULL,
155
			'post_id' => NULL,
156
			'form'    => NULL,
157
			'atts'	  => NULL,
158
		) );
159
160 100
		foreach ($atts as $key => $value) {
161 100
			if( is_null( $value ) ) {
162 100
				continue;
163
			}
164 17
			$this->{$key} = $value;
165
		}
166
167
168
		// Add granular overrides
169 100
		add_filter( $this->filter_prefix . '_get_template_part', array( $this, 'add_id_specific_templates' ), 10, 3 );
170
171
		// widget logic
172 100
		add_action( 'gravityview/template/before', array( $this, 'render_widget_hooks' ) );
173 100
		add_action( 'gravityview/template/after', array( $this, 'render_widget_hooks' ) );
174
175
		/**
176
		 * Clear the current entry after the loop is done
177
		 * @since 1.7.3
178
		 */
179 100
		add_action( 'gravityview_footer', array( $this, 'clearCurrentEntry' ), 500 );
180
181 100
		self::$instance = &$this;
182 100
	}
183
184
	/**
185
	 * @param null $passed_post
186
	 *
187
	 * @return GravityView_View
188
	 */
189 140
	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...
190
191 140
		if( empty( self::$instance ) ) {
192 100
			self::$instance = new self( $passed_post );
193
		}
194
195 140
		return self::$instance;
196
	}
197
198
	/**
199
	 * @param string|null $key The key to a specific attribute of the current field
200
	 * @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
201
	 */
202 68
	public function getCurrentField( $key = NULL ) {
203
204 68
		if( !empty( $key ) ) {
205
			if( isset( $this->_current_field[ $key ] ) ) {
206
				return $this->_current_field[ $key ];
207
			}
208
			return NULL;
209
		}
210
211 68
		return $this->_current_field;
212
	}
213
214
	public function setCurrentFieldSetting( $key, $value ) {
215
216
		if( !empty( $this->_current_field ) ) {
217
			$this->_current_field['field_settings'][ $key ] = $value;
218
		}
219
220
	}
221
222
	public function getCurrentFieldSetting( $key ) {
223
		$settings = $this->getCurrentField('field_settings');
224
225
		if( $settings && !empty( $settings[ $key ] ) ) {
226
			return $settings[ $key ];
227
		}
228
229
		return NULL;
230
	}
231
232
	/**
233
	 * @param array $passed_field
234
	 */
235 63
	public function setCurrentField( $passed_field ) {
236
237 63
		$existing_field = $this->getCurrentField();
238
239 63
		$set_field = wp_parse_args( $passed_field, $existing_field );
240
241 63
		$this->_current_field = $set_field;
242
243
		/**
244
		 * Backward compatibility
245
		 * @deprecated 1.6.2
246
		 */
247 63
		$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...
248 63
	}
249
250
	/**
251
	 * @param string|null $key The key to a specific field in the fields array
252
	 * @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.
253
	 */
254 15
	public function getAtts( $key = NULL ) {
255
256 15
		if( !empty( $key ) ) {
257 1
			if( isset( $this->atts[ $key ] ) ) {
258 1
				return $this->atts[ $key ];
259
			}
260
			return NULL;
261
		}
262
263 14
		return $this->atts;
264
	}
265
266
	/**
267
	 * @param array $atts
268
	 */
269 14
	public function setAtts( $atts ) {
270 14
		$this->atts = $atts;
271 14
	}
272
273
	/**
274
	 * @return array
275
	 */
276 85
	public function getForm() {
277 85
		return $this->form;
278
	}
279
280
	/**
281
	 * @param array $form
282
	 */
283 15
	public function setForm( $form ) {
284 15
		$this->form = $form;
285 15
	}
286
287
	/**
288
	 * @return int|null
289
	 */
290 16
	public function getPostId() {
291 16
		return $this->post_id;
292
	}
293
294
	/**
295
	 * @param int|null $post_id
296
	 */
297 9
	public function setPostId( $post_id ) {
298 9
		$this->post_id = $post_id;
299 9
	}
300
301
	/**
302
	 * @return string
303
	 */
304 68
	public function getContext() {
305 68
		return $this->context;
306
	}
307
308
	/**
309
	 * @param string $context
310
	 */
311 14
	public function setContext( $context ) {
312 14
		$this->context = $context;
313 14
	}
314
315
	/**
316
	 * @param string|null $key The key to a specific field in the fields array
317
	 * @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.
318
	 */
319 14
	public function getFields( $key = null ) {
320
321 14
		$fields = empty( $this->fields ) ? NULL : $this->fields;
322
323 14
		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...
324
			$fields = isset( $fields[ $key ] ) ? $fields[ $key ] : NULL;
325
		}
326
327 14
		return $fields;
328
	}
329
330
	/**
331
     * Get the fields for a specific context
332
     *
333
     * @since 1.19.2
334
     *
335
	 * @param string $context [Optional] "directory", "single", or "edit"
336
	 *
337
	 * @return array Array of GravityView field layout configurations
338
	 */
339
	public function getContextFields( $context = '' ) {
340
341
	    if( '' === $context ) {
342
	        $context = $this->getContext();
343
        }
344
345
		$fields = $this->getFields();
346
347
        foreach ( (array) $fields as $key => $context_fields ) {
348
349
            // Formatted as `{context}_{template id}-{zone name}`, so we want just the $context to match against
350
            $matches = explode( '_', $key );
351
352
            if( isset( $matches[0] ) && $matches[0] === $context ) {
353
                return $context_fields;
354
            }
355
        }
356
357
		return array();
358
    }
359
360
	/**
361
	 * @param array $fields
362
	 */
363 8
	public function setFields( $fields ) {
364 8
		$this->fields = $fields;
365 8
	}
366
367
	/**
368
	 * @param string $key The key to a specific field in the fields array
369
	 * @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.
370
	 */
371
	public function getField( $key ) {
372
373
		if( !empty( $key ) ) {
374
			if( isset( $this->fields[ $key ] ) ) {
375
				return $this->fields[ $key ];
376
			}
377
		}
378
379
		return NULL;
380
	}
381
382
	/**
383
	 * @param string $key The key to a specific field in the fields array
384
	 * @param mixed $value The value to set for the field
385
	 */
386
	public function setField( $key, $value ) {
387
		$this->fields[ $key ] = $value;
388
	}
389
390
	/**
391
	 * @return int
392
	 */
393 33
	public function getViewId() {
394 33
		return absint( $this->view_id );
395
	}
396
397
	/**
398
	 * @param int $view_id
399
	 */
400 14
	public function setViewId( $view_id ) {
401 14
		$this->view_id = intval( $view_id );
402 14
	}
403
404
	/**
405
	 * @return int
406
	 */
407 14
	public function getFormId() {
408 14
		return $this->form_id;
409
	}
410
411
	/**
412
	 * @param int $form_id
413
	 */
414 14
	public function setFormId( $form_id ) {
415 14
		$this->form_id = $form_id;
416 14
	}
417
418
	/**
419
	 * @return array
420
	 */
421 48
	public function getEntries() {
422 48
		return $this->entries;
423
	}
424
425
	/**
426
	 * @param array $entries
427
	 */
428 14
	public function setEntries( $entries ) {
429 14
		$this->entries = $entries;
430 14
	}
431
432
	/**
433
	 * @return int
434
	 */
435 15
	public function getTotalEntries() {
436 15
		return (int)$this->total_entries;
437
	}
438
439
	/**
440
	 * @param int $total_entries
441
	 */
442 15
	public function setTotalEntries( $total_entries ) {
443 15
		$this->total_entries = intval( $total_entries );
444 15
	}
445
446
	/**
447
	 * @return array
448
	 */
449 15
	public function getPaging() {
450
451
	    $default_params = array(
452 15
            'offset' => 0,
453
            'page_size' => 20,
454
        );
455
456 15
		return wp_parse_args( $this->paging, $default_params );
457
	}
458
459
	/**
460
	 * @param array $paging
461
	 */
462 9
	public function setPaging( $paging ) {
463 9
		$this->paging = $paging;
464 9
	}
465
466
	/**
467
	 * Get an array with pagination information
468
	 *
469
	 * @since 1.13
470
	 * 
471
	 * @return array {
472
	 *  @type int $first The starting entry number (counter, not ID)
473
	 *  @type int $last The last displayed entry number (counter, not ID)
474
	 *  @type int $total The total number of entries
475
	 * }
476
	 */
477 1
	public function getPaginationCounts() {
478
479 1
		$paging = $this->getPaging();
480 1
		$offset = $paging['offset'];
481 1
		$page_size = $paging['page_size'];
482 1
		$total = $this->getTotalEntries();
483
484 1
		if ( empty( $total ) ) {
485 1
			gravityview()->log->debug( 'No entries. Returning empty array.' );
486
487 1
			return array();
488
		}
489
490 1
		$first = empty( $offset ) ? 1 : $offset + 1;
491
492
		// If the page size + starting entry is larger than total, the total is the max.
493 1
		$last = ( $offset + $page_size > $total ) ? $total : $offset + $page_size;
494
495
		/**
496
		 * @filter `gravityview_pagination_counts` Modify the displayed pagination numbers
497
		 * @since 1.13
498
		 * @param array $counts Array with $first, $last, $total numbers in that order
499
		 */
500 1
		list( $first, $last, $total ) = apply_filters( 'gravityview_pagination_counts', array( $first, $last, $total ) );
501
502 1
		return array( 'first' => (int) $first, 'last' => (int) $last, 'total' => (int) $total );
503
	}
504
505
	/**
506
	 * @return array
507
	 */
508 14
	public function getSorting() {
509
510
		$defaults_params = array(
511 14
            'sort_field' => 'date_created',
512
            'sort_direction' => 'ASC',
513
            'is_numeric' => false,
514
        );
515
516 14
		return wp_parse_args( $this->sorting, $defaults_params );
517
	}
518
519
	/**
520
	 * @param array $sorting
521
	 */
522 67
	public function setSorting( $sorting ) {
523 67
		$this->sorting = $sorting;
524 67
	}
525
526
	/**
527
	 * @param boolean $do_replace Perform merge tag and shortcode processing on the label. Default: true.
528
	 * @since 2.0
529
	 *
530
	 * @deprecated Use $template->get_back_label();
531
	 *
532
	 * @return string
533
	 */
534 15
	public function getBackLinkLabel( $do_replace = true ) {
535 15
		if ( $do_replace ) {
536 1
			$back_link_label = GravityView_API::replace_variables( $this->back_link_label, $this->getForm(), $this->getCurrentEntry() );
537 1
			return do_shortcode( $back_link_label );
538
		}
539
540 14
		return $this->back_link_label;
541
	}
542
543
	/**
544
	 * @param string $back_link_label
545
	 */
546 15
	public function setBackLinkLabel( $back_link_label ) {
547 15
		$this->back_link_label = $back_link_label;
548 15
	}
549
550
	/**
551
	 * @return boolean
552
	 */
553 14
	public function isHideUntilSearched() {
554 14
		return $this->hide_until_searched;
555
	}
556
557
	/**
558
	 * @param boolean $hide_until_searched
559
	 */
560 14
	public function setHideUntilSearched( $hide_until_searched ) {
561 14
		$this->hide_until_searched = $hide_until_searched;
562 14
	}
563
564
	/**
565
	 * @return string
566
	 */
567
	public function getTemplatePartSlug() {
568
		return $this->template_part_slug;
569
	}
570
571
	/**
572
	 * @param string $template_part_slug
573
	 */
574 1
	public function setTemplatePartSlug( $template_part_slug ) {
575 1
		$this->template_part_slug = $template_part_slug;
576 1
	}
577
578
	/**
579
	 * @return string
580
	 */
581
	public function getTemplatePartName() {
582
		return $this->template_part_name;
583
	}
584
585
	/**
586
	 * @param string $template_part_name
587
	 */
588 1
	public function setTemplatePartName( $template_part_name ) {
589 1
		$this->template_part_name = $template_part_name;
590 1
	}
591
592
	/**
593
	 * Return the current entry. If in the loop, the current entry. If single entry, the currently viewed entry.
594
	 * @return array
595
	 */
596 68
	public function getCurrentEntry() {
597
598 68
		if( in_array( $this->getContext(), array( 'edit', 'single') ) ) {
599 21
			$entries = $this->getEntries();
600 21
			$entry = $entries[0];
601
		} else {
602 51
			$entry = $this->_current_entry;
603
		}
604
605
		/** @since 1.16 Fixes DataTables empty entry issue */
606 68
		if ( empty( $entry ) && ! empty( $this->_current_field['entry'] ) ) {
607 1
			$entry = $this->_current_field['entry'];
608
		}
609
610 68
		return $entry;
611
	}
612
613
	/**
614
	 * @param array $current_entry
615
	 * @return void
616
	 */
617 15
	public function setCurrentEntry( $current_entry ) {
618 15
		$this->_current_entry = $current_entry;
619 15
	}
620
621
	/**
622
	 * Clear the current entry after all entries in the loop have been displayed.
623
	 *
624
	 * @since 1.7.3
625
	 * @return void
626
	 */
627 5
	public function clearCurrentEntry() {
628 5
		$this->_current_entry = NULL;
629 5
	}
630
631
	/**
632
	 * Render an output zone, as configured in the Admin
633
	 *
634
	 * @since 1.16.4 Added $echo parameter
635
	 *
636
	 * @param string $zone The zone name, like 'footer-left'
637
	 * @param array $atts
638
	 * @param bool $echo Whether to print the output
639
	 *
640
	 * @deprecated This will never get called in new templates.
641
	 *
642
	 * @return string|null
643
	 */
644
	public function renderZone( $zone = '', $atts = array(), $echo = true ) {
645
646
		if ( empty( $zone ) ) {
647
			gravityview()->log->error( 'No zone defined.');
648
			return NULL;
649
		}
650
651
		$defaults = array(
652
			'slug' => $this->getTemplatePartSlug(),
653
			'context' => $this->getContext(),
654
			'entry' => $this->getCurrentEntry(),
655
			'form' => $this->getForm(),
656
			'hide_empty' => $this->getAtts('hide_empty'),
657
		);
658
659
		$final_atts = wp_parse_args( $atts, $defaults );
660
661
		$output = '';
662
663
		$final_atts['zone_id'] = "{$final_atts['context']}_{$final_atts['slug']}-{$zone}";
664
665
		$fields = $this->getField( $final_atts['zone_id'] );
666
667
		// Backward compatibility
668
		if ( 'table' === $this->getTemplatePartSlug() ) {
669
			/**
670
			 * @filter `gravityview_table_cells` Modify the fields displayed in a table
671
			 * @param array $fields
672
			 * @param \GravityView_View $this
673
			 * @deprecated Use `gravityview/template/table/fields`
674
			 */
675
			$fields = apply_filters("gravityview_table_cells", $fields, $this );
676
		}
677
678
		if ( empty( $fields ) ) {
679
680
			gravityview()->log->error( 'Empty zone configuration for {zone_id}.', array( 'zone_id' => $final_atts['zone_id'] ) );
681
682
			return NULL;
683
		}
684
685
		$field_output = '';
686
		foreach ( $fields as $field ) {
687
			$final_atts['field'] = $field;
688
689
			$field_output .= gravityview_field_output( $final_atts );
690
		}
691
692
		/**
693
		 * If a zone has no field output, choose whether to show wrapper
694
		 * False by default to keep backward compatibility
695
		 * @since 1.7.6
696
		 * @param boolean $hide_empty_zone Default: false
697
		 * @since 2.0
698
		 * @param \GV\Template_Context $context The context. Null here. Since this path is deprecated.
699
		 */
700
		if ( empty( $field_output ) && apply_filters( 'gravityview/render/hide-empty-zone', false, null ) ) {
701
			return NULL;
702
		}
703
704
		if( !empty( $final_atts['wrapper_class'] ) ) {
705
			$output .= '<div class="'.gravityview_sanitize_html_class( $final_atts['wrapper_class'] ).'">';
706
		}
707
708
		$output .= $field_output;
709
710
		if( !empty( $final_atts['wrapper_class'] ) ) {
711
			$output .= '</div>';
712
		}
713
714
		if( $echo ) {
715
			echo $output;
716
		}
717
718
		return $output;
719
	}
720
721
	/**
722
	 * In order to improve lookup times, we store located templates in a local array.
723
	 *
724
	 * This improves performance by up to 1/2 second on a 250 entry View with 7 columns showing
725
	 *
726
	 * @inheritdoc
727
	 * @see Gamajo_Template_Loader::locate_template()
728
	 * @return null|string NULL: Template not found; String: path to template
729
	 */
730 1
	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...
731
732 1
		if( is_string( $template_names ) && isset( $this->located_templates[ $template_names ] ) ) {
733
734
			$located = $this->located_templates[ $template_names ];
735
736
		} else {
737
738
			// Set $load to always false so we handle it here.
739 1
			$located = parent::locate_template( $template_names, false, $require_once );
740
741 1
			if( is_string( $template_names ) ) {
742
				$this->located_templates[ $template_names ] = $located;
743
			}
744
		}
745
746 1
		if ( $load && $located ) {
747
			load_template( $located, $require_once );
748
		}
749
750 1
		return $located;
751
	}
752
753
	/**
754
	 * Magic Method: Instead of throwing an error when a variable isn't set, return null.
755
	 * @param  string      $name Key for the data retrieval.
756
	 * @return mixed|null    The stored data.
757
	 */
758 1
	public function __get( $name ) {
759 1
		if( isset( $this->{$name} ) ) {
760
			return $this->{$name};
761
		} else {
762 1
			return NULL;
763
		}
764
	}
765
766
	/**
767
	 * Enable overrides of GravityView templates on a granular basis
768
	 *
769
	 * The loading order is:
770
	 *
771
	 * - view-[View ID]-table-footer.php
772
	 * - form-[Form ID]-table-footer.php
773
	 * - page-[ID of post or page where view is embedded]-table-footer.php
774
	 * - table-footer.php
775
	 *
776
	 * @see  Gamajo_Template_Loader::get_template_file_names() Where the filter is
777
	 * @param array $templates Existing list of templates.
778
	 * @param string $slug      Name of the template base, example: `table`, `list`, `datatables`, `map`
779
	 * @param string $name      Name of the template part, example: `body`, `footer`, `head`, `single`
780
	 *
781
	 * @return array $templates Modified template array, merged with existing $templates values
782
	 */
783 12
	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...
784
785 12
		$additional = array();
786
787
		// form-19-table-body.php
788 12
		$additional[] = sprintf( 'form-%d-%s-%s.php', $this->getFormId(), $slug, $name );
789
790 12
		if( $view_id = $this->getViewId() ) {
791
			// view-3-table-body.php
792 11
			$additional[] = sprintf( 'view-%d-%s-%s.php', $view_id, $slug, $name );
793
		}
794
795 12
		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...
796
797
			// page-19-table-body.php
798 11
			$additional[] = sprintf( 'page-%d-%s-%s.php', $this->getPostId(), $slug, $name );
799
		}
800
801
		// Combine with existing table-body.php and table.php
802 12
		$templates = array_merge( $additional, $templates );
803
804 12
		gravityview()->log->debug( 'List of Template Files', array( 'data' => $templates ) );
805
806 12
		return $templates;
807
	}
808
809
	// Load the template
810 1
	public function render( $slug, $name, $require_once = true ) {
811
812 1
		$this->setTemplatePartSlug( $slug );
813
814 1
		$this->setTemplatePartName( $name );
815
		
816 1
		$template_file = $this->get_template_part( $slug, $name, false );
817
818 1
		gravityview()->log->debug( 'Rendering Template File: {path}', array( 'path' => $template_file ) );
819
820 1
		if( !empty( $template_file) ) {
821
822 1
			if ( $require_once ) {
823
				require_once( $template_file );
824
			} else {
825 1
				require( $template_file );
826
			}
827
828
		}
829 1
	}
830
831
	/**
832
	 * Output the widgets on before/after hooks.
833
	 *
834
	 * @param int|\GV\Template_Context $view_id_or_context The View ID or the context.
835
	 *
836
	 * @return void
837
	 */
838 11
	public function render_widget_hooks( $view_id_or_context ) {
839
840
	    /**
841
		 * @deprecated Numeric argument is deprecated. Pass a \GV\Template_Context instead.
842
		 */
843 11
		if ( is_numeric( $view_id_or_context ) ) {
844
			$view = \GV\View::by_id( $view_id_or_context );
845
			$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...
846
			$total_entries = GravityView_View::getInstance()->getTotalEntries();
847
848
			/**
849
			 * Fake new context for legacy template code.
850
			 */
851
			$view_id_or_context = \GV\Template_Context::from_template( array(
852
				'view' => $view,
853
			) );
854
855 11
		} else if ( $view_id_or_context instanceof \GV\Template_Context ) {
856 11
			$view = $view_id_or_context->view;
857 11
			$is_single = (boolean)$view_id_or_context->request->is_entry();
858 11
			$total_entries = $view_id_or_context->entries ? $view_id_or_context->entries->count() : 0;
859
860
		} else {
861
			gravityview()->log->error( 'No View ID or template context provided to render_widget_hooks' );
862
			return;
863
		}
864
865 11
		if ( $is_single ) {
866 4
			gravityview()->log->debug( 'Not rendering widgets; single entry' );
867 4
			return;
868
		}
869
870 7
		switch ( current_filter() ) {
871
			default:
872 7
			case 'gravityview/template/before':
873 6
			case 'gravityview_before':
874 7
				$zone = 'header';
875 7
				break;
876 6
			case 'gravityview/template/after':
877
			case 'gravityview_after':
878 6
				$zone = 'footer';
879 6
				break;
880
		}
881
882 7
		$widgets = $view->widgets->by_position( "$zone*" );
883
884
		/**
885
		 * Prevent output if no widgets to show.
886
		 * @since 1.16
887
		 */
888 7
		if ( ! $widgets->count() ) {
889 6
			gravityview()->log->debug( 'No widgets for View #{view_id} in zone {zone}', array( 'view_id' => $view->ID, 'zone' => $zone ) );
890 6
			return;
891
		}
892
893
		// Prevent being called twice
894 1
		if ( did_action( "gravityview/widgets/$zone/{$view->ID}/rendered" ) ) {
895
			gravityview()->log->debug( 'Not rendering {zone}; already rendered', array( 'zone' => $zone.'_'.$view->ID.'_widgets' ) );
896
			return;
897
		}
898
899 1
		$rows = \GV\Widget::get_default_widget_areas();
900
901
		// TODO: Move to sep. method, use an action instead
902 1
		wp_enqueue_style( 'gravityview_default_style' );
903
904 1
		$default_css_class = 'gv-grid gv-widgets-' . $zone;
905
906 1
		if ( ! $total_entries ) {
907 1
			$default_css_class .= ' gv-widgets-no-results';
908
		}
909
910
		/**
911
		 * @filter `gravityview/widgets/wrapper_css_class` The CSS class applied to the widget container `<div>`.
912
		 * @since 1.16.2
913
		 * @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`
914
		 * @param string $zone Current widget zone, either `header` or `footer`
915
		 * @param array $widgets Array of widget configurations for the current zone, as set by `gravityview_get_current_view_data()['widgets']`
916
		 */
917 1
		$css_class = apply_filters('gravityview/widgets/wrapper_css_class', $default_css_class, $zone, $widgets->as_configuration() );
918
919 1
		$css_class = gravityview_sanitize_html_class( $css_class );
920
921
		// TODO Convert to partials
922
		?>
923
		<div class="<?php echo $css_class; ?>">
924
			<?php
925 1
			foreach( $rows as $row ) {
926 1
				foreach( $row as $col => $areas ) {
927 1
					$column = ( $col == '2-2' ) ? '1-2 gv-right' : "$col gv-left";
928
				?>
929
					<div class="gv-grid-col-<?php echo esc_attr( $column ); ?>">
930
						<?php
931 1
						if ( ! empty( $areas ) ) {
932 1
							foreach ( $areas as $area ) {
933 1
								foreach ( $widgets->by_position( $zone . '_' . $area['areaid'] )->all() as $widget ) {
934 1
									do_action( sprintf( 'gravityview/widgets/%s/render', $widget->get_widget_id() ), $widget->configuration->all(), null, $view_id_or_context );
935
								}
936
							}
937
						} ?>
938 1
					</div>
939
				<?php } // $row ?>
940
			<?php } // $rows ?>
941 1
		</div>
942
943
		<?php
944
945
		/**
946
		 * Prevent widgets from being called twice.
947
		 * 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
948
		 */
949 1
		if ( did_action( 'wp_head' ) ) {
950
			do_action( "gravityview/widgets/$zone/{$view->ID}/rendered" );
951
		}
952 1
	}
953
954
	/**
955
	 * Include a file inside this context.
956
	 *
957
	 * @param string $path A path to the legacy template to include.
958
	 *
959
	 * @return void
960
	 */
961
	public function _include( $path ) {
962
		if ( file_exists( $path ) ) {
963
			include $path;
964
		}
965
	}
966
967
}
968
969