Completed
Push — master ( 8a7f17...ef3c16 )
by Zack
26:51 queued 23:00
created

Field_Template   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 427
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 98.39%

Importance

Changes 0
Metric Value
dl 0
loc 427
ccs 122
cts 124
cp 0.9839
rs 9
c 0
b 0
f 0
wmc 35
lcom 1
cbo 8

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 1
A __destruct() 0 3 1
D add_id_specific_templates() 0 130 23
D render() 0 205 10
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 23 and the first side effect is on line 6.

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

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

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

Loading history...
2
namespace GV;
3
4
/** If this file is called directly, abort. */
5
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6
	die();
7
}
8
9
/**
10
 * Load up the Gamajo Template Loader.
11
 *
12
 * @see https://github.com/GaryJones/Gamajo-Template-Loader
13
 */
14
if ( ! class_exists( 'Gamajo_Template_Loader' ) ) {
15
	require gravityview()->plugin->dir( 'future/lib/class-gamajo-template-loader.php' );
16
}
17
18
/**
19
 * The Field Template class.
20
 *
21
 * Attached to a \GV\Field and used by a \GV\Field_Renderer.
22
 */
23
abstract class Field_Template extends Template {
24
	/**
25
	 * Prefix for filter names.
26
	 * @var string
27
	 */
28
	protected $filter_prefix = 'gravityview/template/fields';
29
30
	/**
31
	 * Directory name where custom templates for this plugin should be found in the theme.
32
	 * @var string
33
	 */
34
	protected $theme_template_directory = 'gravityview/fields/';
35
36
	/**
37
	 * Directory name where the default templates for this plugin are found.
38
	 * @var string
39
	 */
40
	protected $plugin_template_directory = 'templates/fields/';
41
42
	/**
43
	 * @var \GV\Field The field connected to this template.
44
	 */
45
	public $field;
46
47
	/**
48
	 * @var \GV\View The view context.
49
	 */
50
	public $view;
51
52
	/**
53
	 * @var \GV\Source The source context.
54
	 */
55
	public $source;
56
57
	/**
58
	 * @var \GV\Entry The entry context.
59
	 */
60
	public $entry;
61
62
	/**
63
	 * @var \GV\Request The request context.
64
	 */
65
	public $request;
66
67
	/**
68
	 * @var string The template slug to be loaded (like "table", "list")
69
	 */
70
	public static $slug;
71
72
	/**
73
	 * Initializer.
74
	 *
75
	 * @param \GV\Field $field The field about to be rendered.
76
	 * @param \GV\View $view The view in this context, if applicable.
77
	 * @param \GV\Source $source The source (form) in this context, if applicable.
78
	 * @param \GV\Entry $entry The entry in this context, if applicable.
79
	 * @param \GV\Request $request The request in this context, if applicable.
80
	 */
81 51
	public function __construct( Field $field, View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
82 51
		$this->field = $field;
83 51
		$this->view = $view;
84 51
		$this->source = $source;
85 51
		$this->entry = $entry;
86 51
		$this->request = $request;
87
88
		/** Add granular overrides. */
89 51
		add_filter( $this->filter_prefix . '_get_template_part', $this->_add_id_specific_templates_callback  = self::add_id_specific_templates( $this ), 10, 3 );
0 ignored issues
show
Bug introduced by
The property _add_id_specific_templates_callback 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...
90
91 51
		parent::__construct();
92 51
	}
93
94 51
	public function __destruct() {
95 51
		remove_filter( $this->filter_prefix . '_get_template_part', $this->_add_id_specific_templates_callback );;
96 51
	}
97
98
	/**
99
	 * Enable granular template overrides based on current post, view, form, field types, etc.
100
	 *
101
	 * Why? See https://github.com/gravityview/GravityView/issues/1024
102
	 *
103
	 * @param \GV\Field_Template $template The template instance.
104
	 * @return callable The callback bound to `get_template_part`. See `\GV\Field_Template::__construct`
105
	 */
106 51
	public static function add_id_specific_templates( $template ) {
107
108 51
		$inputType  = null;
109 51
		$field_type = null;
110 51
		$field_id   = null;
111 51
		$view_id    = null;
112 51
		$form_id    = null;
113 51
		$is_view    = $template->request && $template->request->is_view();
114
115 51
		if ( $template->field ) {
116 51
			$inputType  = $template->field->inputType;
0 ignored issues
show
Bug introduced by
The property inputType does not seem to exist in GV\Field.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
117 51
			$field_type = $template->field->type;
0 ignored issues
show
Bug introduced by
The property type does not seem to exist in GV\Field.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
118 51
			$field_id   = $template->field->ID;
119
		}
120
121 51
		if ( $template->view ) {
122 51
			$view_id = $template->view->ID;
0 ignored issues
show
Bug introduced by
The property ID does not seem to exist in GV\View.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
123 51
			$form_id = $template->view->form ? $template->view->form->ID : null;
124
		}
125
126 51
		$class = get_class( $template );
127
128
		/**
129
		 * Enable granular template overrides based on current post, view, form, field types, etc.
130
		 *
131
		 * The hierarchy is as follows:
132
		 *
133
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field-[Field type]-html.php
134
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field-[Field inputType]-html.php
135
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field-html.php
136
		 * - post-[ID of post of page where view is embedded]-field-[Field type]-html.php
137
		 * - post-[ID of post of page where view is embedded]-field-[Field inputType]-html.php
138
		 * - post-[ID of post of page where view is embedded]-field-html.php
139
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field-[Field type].php
140
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field-[Field inputType].php
141
		 * - post-[ID of post of page where view is embedded]-view-[View ID]-field.php
142
		 * - post-[ID of post of page where view is embedded]-field-[Field type].php
143
		 * - post-[ID of post of page where view is embedded]-field-[Field inputType].php
144
		 * - post-[ID of post of page where view is embedded]-field.php
145
		 * - form-[Form ID]-field-[Field ID]-html.php
146
		 * - form-[Form ID]-field-[Field ID].php
147
		 * - form-[Form ID]-field-[Field type]-html.php
148
		 * - form-[Form ID]-field-[Field inputType]-html.php
149
		 * - form-[Form ID]-field-[Field type].php
150
		 * - form-[Form ID]-field-[Field inputType].php
151
		 * - view-[View ID]-field-[Field type]-html.php
152
		 * - view-[View ID]-field-[Field inputType]-html.php
153
		 * - view-[View ID]-field-[Field type].php
154
		 * - view-[View ID]-field-[Field inputType].php
155
		 * - field-[Field type]-html.php
156
		 * - field-[Field inputType]-html.php
157
		 * - field-[Field type].php
158
		 * - field-[Field inputType].php
159
		 * - field-html.php
160
		 * - field.php
161
		 *
162
		 * @see  Gamajo_Template_Loader::get_template_file_names() Where the filter is
163
		 * @param array $templates Existing list of templates.
164
		 * @param string $slug      Name of the template base, example: `html`, `json`, `xml`
165
		 * @param string $name      Name of the template part.
166
		 *
167
		 * @return array $templates Modified template array, merged with existing $templates values
168
		 */
169 51
		return function( $templates, $slug, $name ) use ( $class, $inputType, $field_type, $view_id, $is_view, $form_id, $field_id ) {
170 51
			$specifics = array();
171
172 51
			list( $slug_dir, $slug_name ) = $class::split_slug( $slug, $name );
173
174 51
			global $post;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
175
176 51
			if ( $is_view && $post ) {
177 5
				if ( $field_type ) {
178 5
					$specifics []= sprintf( '%spost-%d-view-%d-field-%s-%s.php', $slug_dir, $post->ID, $view_id, $field_type, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
179 5
					$inputType && $specifics []= sprintf( '%spost-%d-view-%d-field-%s-%s.php', $slug_dir, $post->ID, $view_id, $inputType, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
180 5
					$specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $field_type );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
181 5
					$inputType && $specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $inputType );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
182 5
					$specifics []= sprintf( '%spost-%d-field-%s-%s.php', $slug_dir, $post->ID, $field_type, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
183 5
					$inputType && $specifics []= sprintf( '%spost-%d-field-%s-%s.php', $slug_dir, $post->ID, $inputType, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
184 5
					$specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $field_type );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
185 5
					$inputType &&  $specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $inputType );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
186
				}
187
188 5
				$specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
189 5
				$specifics []= sprintf( '%spost-%d-view-%d-field.php', $slug_dir, $post->ID, $view_id );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
190 5
				$specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
191 5
				$specifics []= sprintf( '%spost-%d-field.php', $slug_dir, $post->ID );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
192
			}
193
			
194
			/** Field-specific */
195 51
			if ( $field_id && $form_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $field_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. 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 string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $form_id 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...
196
197 51
				if ( $field_id ) {
198 51
					$specifics []= sprintf( '%sform-%d-field-%d-%s.php', $slug_dir, $form_id, $field_id, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
199 51
					$specifics []= sprintf( '%sform-%d-field-%d.php', $slug_dir, $form_id, $field_id );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
200
				}
201
202 51
				if ( $field_type ) {
203 51
					$specifics []= sprintf( '%sform-%d-field-%s-%s.php', $slug_dir, $form_id, $field_type, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
204 51
					$inputType && $specifics []= sprintf( '%sform-%d-field-%s-%s.php', $slug_dir, $form_id, $inputType, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
205 51
					$specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $field_type );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
206 51
					$inputType && $specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $inputType );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
207
208 51
					$specifics []= sprintf( '%sview-%d-field-%s-%s.php', $slug_dir, $view_id, $field_type, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
209 51
					$inputType && $specifics []= sprintf( '%sview-%d-field-%s-%s.php', $slug_dir, $view_id, $inputType, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
210 51
					$specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $field_type );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
211 51
					$inputType && $specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $inputType );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
212
213 51
					$specifics []= sprintf( '%sfield-%s-%s.php', $slug_dir, $field_type, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
214 51
					$inputType && $specifics []= sprintf( '%sfield-%s-%s.php', $slug_dir, $inputType, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
215 51
					$specifics []= sprintf( '%sfield-%s.php', $slug_dir, $field_type );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
216 51
					$inputType && $specifics []= sprintf( '%sfield-%s.php', $slug_dir, $inputType );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
217
				}
218
			}
219
220 51
			if ( $form_id ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $form_id 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...
221
				/** Generic field templates */
222 51
				$specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
223 51
				$specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
224
225 51
				$specifics []= sprintf( '%sview-%d-field.php', $slug_dir, $view_id );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
226 51
				$specifics []= sprintf( '%sform-%d-field.php', $slug_dir, $form_id );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
227
			}
228
229 51
			$specifics []= sprintf( '%sfield-%s.php', $slug_dir, $slug_name );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
230 51
			$specifics []= sprintf( '%sfield.php', $slug_dir );
0 ignored issues
show
introduced by
Expected 1 space before "="; 0 found
Loading history...
231
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
232
233 51
			return array_merge( $specifics, $templates );
234 51
		};
235
	}
236
237
	/**
238
	 * Output some HTML.
239
	 *
240
	 * @todo Move to \GV\Field_HTML_Template, but call filters here?
241
	 *
242
	 * @return void
243
	 */
244 51
	public function render() {
245
246
		/** Retrieve the value. */
247 51
		$display_value = $value = $this->field->get_value( $this->view, $this->source, $this->entry );
248
249 51
		$source = $this->source;
250 51
		$source_backend = $source ? $source::$backend : null;
251
252 51
		\GV\Mocks\Legacy_Context::load( array(
253 51
			'field' => $this->field,
254
		) );
255
256
		/** Alter the display value according to Gravity Forms. */
257 51
		if ( $source_backend == \GV\Source::BACKEND_GRAVITYFORMS ) {
258
			/** Prevent any PHP warnings that may be generated. */
259 39
			ob_start();
260
261 39
			$display_value = \GFCommon::get_lead_field_display( $this->field->field, $value, $this->entry['currency'], false, 'html' );
0 ignored issues
show
Documentation introduced by
The property field does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
262
263 39
			if ( $errors = ob_get_clean() ) {
264
				gravityview()->log->error( 'Errors when calling GFCommon::get_lead_field_display()', array( 'data' => $errors ) );
265
			}
266
267
			/** Call the Gravity Forms field value filter. */
268 39
			$display_value = apply_filters( 'gform_entry_field_value', $display_value, $this->field->field, $this->entry->as_entry(), $this->source->form );
0 ignored issues
show
Documentation introduced by
The property field does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
Bug introduced by
The property form does not seem to exist in GV\Source.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
269
270
			/** Replace merge tags for admin-only fields. */
271 39
			if ( ! empty( $this->field->field->adminOnly ) ) {
0 ignored issues
show
Documentation introduced by
The property field does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
272
				$display_value = \GravityView_API::replace_variables( $display_value, $this->form->form, $this->entry->as_entry(), false, false );
0 ignored issues
show
Bug introduced by
The property form 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...
273
			}
274
		}
275
276 51
		$context = Template_Context::from_template( $this, compact( 'display_value', 'value' ) );
277
278
		/**
279
		 * Make various pieces of data available to the template
280
		 *  under the $gravityview scoped variable.
281
		 *
282
		 * @filter `gravityview/template/field/context`
283
		 * @param \GV\Template_Context $context The context for this template.
284
		 * @since 2.0
285
		 */
286 51
		$this->push_template_data( apply_filters( 'gravityview/template/field/context', $context ), 'gravityview' );
287
288
		/** Bake the template. */
289 51
		ob_start();
290 51
		$this->located_template = $this->get_template_part( static::$slug );
291 51
		$output = ob_get_clean();
292
293 51
		if ( empty( $output ) ) {
294
			/**
295
			 * @filter `gravityview_empty_value` What to display when a field is empty
296
			 * @deprecated Use the `gravityview/field/value/empty` filter instead
297
			 * @param string $value (empty string)
298
			 */
299 17
			$output = apply_filters( 'gravityview_empty_value', $output );
300
301
			/**
302
			 * @filter `gravityview/field/value/empty` What to display when this field is empty.
303
			 * @param string $value The value to display (Default: empty string)
304
			 * @param \GV\Template_Context The template context this is being called from.
305
			 */
306 17
			$output = apply_filters( 'gravityview/field/value/empty', $output, Template_Context::from_template( $this ) );
307
308 17
			$context = Template_Context::from_template( $this, compact( 'display_value', 'value' ) );
309
		}
310
311 51
		gravityview()->log->info( 'Field template for field #{field_id} loaded: {located_template}', array( 'field_id' => $this->field->ID, 'located_template' => $this->located_template ) );
312
313 51
		$this->pop_template_data( 'gravityview' );
314
315
		/** A compatibility array that's required by some of the deprecated filters. */
316
		$field_compat = array(
317 51
			'form' => $source_backend == \GV\Source::BACKEND_GRAVITYFORMS ? $this->source->form : null,
318 51
			'field_id' => $this->field->ID,
319 51
			'field' => $this->field->field,
0 ignored issues
show
Documentation introduced by
The property field does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
320 51
			'field_settings' => $this->field->as_configuration(),
321 51
			'value' => $value,
322 51
			'display_value' => $display_value,
323 51
			'format' => 'html',
324 51
			'entry' => $this->entry->as_entry(),
325 51
			'field_type' => $this->field->type,
0 ignored issues
show
Documentation introduced by
The property type does not exist on object<GV\Field>. Since you implemented __get, maybe consider adding a @property annotation.

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

<?php

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

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

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

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

}

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

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

See also the PhpDoc documentation for @property.

Loading history...
326 51
			'field_path' => $this->located_template,
327
		);
328
329 51
		$pre_link_compat_callback = function( $output, $context ) use ( $field_compat ) {
330 51
			$field = $context->field;
331
332
			/**
333
			 * @filter `gravityview_field_entry_value_{$field_type}_pre_link` Modify the field value output for a field type before Show As Link setting is applied. Example: `gravityview_field_entry_value_number_pre_link`
334
			 * @since 1.16
335
			 * @param string $output HTML value output
336
			 * @param array  $entry The GF entry array
337
			 * @param array  $field_settings Settings for the particular GV field
338
			 * @param array  $field Field array, as fetched from GravityView_View::getCurrentField()
339
			 *
340
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
341
			 */
342 51
			$output = apply_filters( "gravityview_field_entry_value_{$field->type}_pre_link", $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
343
344 51
			$output = apply_filters( 'gravityview_field_entry_value_pre_link', $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
345
346
			/**
347
			 * Link to the single entry by wrapping the output in an anchor tag
348
			 *
349
			 * Fields can override this by modifying the field data variable inside the field. See /templates/fields/post_image.php for an example.
350
			 */
351 51
			if ( ! empty( $field->show_as_link ) && ! \gv_empty( $output, false, false ) ) {
352 2
				$link_atts = empty( $field->new_window ) ? array() : array( 'target' => '_blank' );
353
354 2
				$permalink = $context->entry->get_permalink( $context->view, $context->request );
355 2
				$output = \gravityview_get_link( $permalink, $output, $link_atts );
356
357
				/**
358
				 * @filter `gravityview_field_entry_link` Modify the link HTML
359
				 * @param string $link HTML output of the link
360
				 * @param string $href URL of the link
361
				 * @param array  $entry The GF entry array
362
				 * @param array $field_settings Settings for the particular GV field
363
				 * @deprecated Use `gravityview/template/field/entry_link`
364
				 */
365 2
				$output = apply_filters( 'gravityview_field_entry_link', $output, $permalink, $context->entry->as_entry(), $field->as_configuration() );
366
367
				/**
368
				 * @filter `gravityview/template/field/entry_link` Modify the link HTML
369
				 * @since 2.0
370
				 * @param string $link HTML output of the link
371
				 * @param string $href URL of the link
372
				 * @param \GV\Template_Context $context The context
373
				 */
374 2
				$output = apply_filters( 'gravityview/template/field/entry_link', $output, $permalink, $context );
375
			}
376
377 51
			return $output;
378 51
		};
379
380 51
		$post_link_compat_callback = function( $output, $context ) use ( $field_compat ) {
381 51
			$field = $context->field;
382
383
			/**
384
			 * @filter `gravityview_field_entry_value_{$field_type}` Modify the field value output for a field type. Example: `gravityview_field_entry_value_number`
385
			 * @since 1.6
386
			 * @param string $output HTML value output
387
			 * @param array  $entry The GF entry array
388
			 * @param  array $field_settings Settings for the particular GV field
389
			 * @param array $field Current field being displayed
390
			 *
391
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
392
			 */
393 51
			$output = apply_filters( "gravityview_field_entry_value_{$field->type}", $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
394
395
			/**
396
			 * @filter `gravityview_field_entry_value` Modify the field value output for all field types
397
			 * @param string $output HTML value output
398
			 * @param array  $entry The GF entry array
399
			 * @param  array $field_settings Settings for the particular GV field
400
			 * @param array $field_data  {@since 1.6}
401
			 *
402
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
403
			 */
404 51
			$output = apply_filters( 'gravityview_field_entry_value', $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
405
406
			/**
407
			 * @filter `gravityview/template/field/{$field_type}/output` Modify the field output for a field type.
408
			 *
409
			 * @since 2.0
410
			 *
411
			 * @param string $output The current output.
412
			 * @param \GV\Template_Context The template context this is being called from.
413
			 */
414 51
			return apply_filters( "gravityview/template/field/{$field->type}/output", $output, $context );
415 51
		};
416
417
		/**
418
		 * Okay, what's this whole pre/post_link compat deal, huh?
419
		 *
420
		 * Well, the `gravityview_field_entry_value_{$field_type}_pre_link` filter
421
		 *  is expected to be applied before the value is turned into an entry link.
422
		 *
423
		 * And then `gravityview_field_entry_value_{$field_type}` and `gravityview_field_entry_value`
424
		 *  are called afterwards.
425
		 *
426
		 * So we're going to use filter priorities to make sure this happens inline with
427
		 *  our new filters, in the correct sequence. Pre-link called with priority 5 and
428
		 *  post-link called with priority 9. Then everything else.
429
		 *
430
		 * If a new code wants to alter the value before it is hyperlinked (hyperlinkified?),
431
		 *  it should hook into a priority between -inf. and 8. Afterwards: 10 to +inf.
432
		 */
433
		add_filter( 'gravityview/template/field/output', $pre_link_compat_callback, 5, 2 );
434
		add_filter( 'gravityview/template/field/output', $post_link_compat_callback, 9, 2 );
435
436
		/**
437
		 * @filter `gravityview/template/field/output` Modify the field output for a field.
438
		 *
439
		 * @since 2.0
440
		 *
441
		 * @param string $output The current output.
442
		 * @param \GV\Template_Context The template this is being called from.
443
		 */
444
		echo apply_filters( "gravityview/template/field/output", $output, $context );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'apply_filters'
Loading history...
Coding Style Comprehensibility introduced by
The string literal gravityview/template/field/output does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
445
446
		remove_filter( 'gravityview/template/field/output', $pre_link_compat_callback, 5 );
447
		remove_filter( 'gravityview/template/field/output', $post_link_compat_callback, 9 );
448
	}
449
}
450
451
/** Load implementations. */
452
require gravityview()->plugin->dir( 'future/includes/class-gv-template-field-html.php' );
453