Completed
Pull Request — master (#1442)
by Zack
08:53 queued 06:21
created

Field_Template::render()   D

Complexity

Conditions 13
Paths 145

Size

Total Lines 227

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 59
CRAP Score 13.0432

Importance

Changes 0
Metric Value
cc 13
nc 145
nop 0
dl 0
loc 227
ccs 59
cts 63
cp 0.9365
crap 13.0432
rs 4.9932
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
namespace GV;
3
4
/** If this file is called directly, abort. */
5
if ( ! defined( 'GRAVITYVIEW_DIR' ) ) {
6
	die();
7
}
8
9
/**
10
 * Load up the Gamajo Template Loader.
11
 *
12
 * @see https://github.com/GaryJones/Gamajo-Template-Loader
13
 */
14
if ( ! class_exists( '\GV\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 94
	public function __construct( Field $field, View $view = null, Source $source = null, Entry $entry = null, Request $request = null ) {
82 94
		$this->field = $field;
83 94
		$this->view = $view;
84 94
		$this->source = $source;
85 94
		$this->entry = $entry;
86 94
		$this->request = $request;
87
88
		/** Add granular overrides. */
89 94
		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 94
		parent::__construct();
92 94
	}
93
94 94
	public function __destruct() {
95 94
		remove_filter( $this->filter_prefix . '_get_template_part', $this->_add_id_specific_templates_callback );;
96 94
	}
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 94
	public static function add_id_specific_templates( $template ) {
107
108 94
		$inputType  = null;
109 94
		$field_type = null;
110 94
		$field_id   = null;
111 94
		$view_id    = null;
112 94
		$form_id    = null;
113 94
		$is_view    = $template->request && $template->request->is_view();
114
115 94
		if ( $template->field ) {
116 94
			$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 94
			$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 94
			$field_id   = $template->field->ID;
119
		}
120
121 94
		if ( $template->view ) {
122 94
			$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 94
			$form_id = $template->view->form ? $template->view->form->ID : null;
124
		}
125
126 94
		$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
		return function( $templates, $slug, $name ) use ( $class, $inputType, $field_type, $view_id, $is_view, $form_id, $field_id ) {
170 94
			$specifics = array();
171
172 94
			list( $slug_dir, $slug_name ) = $class::split_slug( $slug, $name );
173
174 94
			global $post;
175
176 94
			if ( $is_view && $post ) {
177 10
				if ( $field_type ) {
178 10
					$specifics []= sprintf( '%spost-%d-view-%d-field-%s-%s.php', $slug_dir, $post->ID, $view_id, $field_type, $slug_name );
179 10
					$inputType && $specifics []= sprintf( '%spost-%d-view-%d-field-%s-%s.php', $slug_dir, $post->ID, $view_id, $inputType, $slug_name );
180 10
					$specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $field_type );
181 10
					$inputType && $specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $inputType );
182 10
					$specifics []= sprintf( '%spost-%d-field-%s-%s.php', $slug_dir, $post->ID, $field_type, $slug_name );
183 10
					$inputType && $specifics []= sprintf( '%spost-%d-field-%s-%s.php', $slug_dir, $post->ID, $inputType, $slug_name );
184 10
					$specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $field_type );
185 10
					$inputType &&  $specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $inputType );
186
				}
187
188 10
				$specifics []= sprintf( '%spost-%d-view-%d-field-%s.php', $slug_dir, $post->ID, $view_id, $slug_name );
189 10
				$specifics []= sprintf( '%spost-%d-view-%d-field.php', $slug_dir, $post->ID, $view_id );
190 10
				$specifics []= sprintf( '%spost-%d-field-%s.php', $slug_dir, $post->ID, $slug_name );
191 10
				$specifics []= sprintf( '%spost-%d-field.php', $slug_dir, $post->ID );
192
			}
193
194
			/** Field-specific */
195 94
			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 94
				if ( $field_id ) {
198 94
					$specifics []= sprintf( '%sform-%d-field-%d-%s.php', $slug_dir, $form_id, $field_id, $slug_name );
199 94
					$specifics []= sprintf( '%sform-%d-field-%d.php', $slug_dir, $form_id, $field_id );
200
201 94
					if ( $view_id ) {
202 94
						$specifics []= sprintf( '%sview-%d-field-%d.php', $slug_dir, $view_id, $field_id );
203
					}
204
				}
205
206 94
				if ( $field_type ) {
207 94
					$specifics []= sprintf( '%sform-%d-field-%s-%s.php', $slug_dir, $form_id, $field_type, $slug_name );
208 94
					$inputType && $specifics []= sprintf( '%sform-%d-field-%s-%s.php', $slug_dir, $form_id, $inputType, $slug_name );
209 94
					$specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $field_type );
210 94
					$inputType && $specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $inputType );
211
212 94
					$specifics []= sprintf( '%sview-%d-field-%s-%s.php', $slug_dir, $view_id, $field_type, $slug_name );
213 94
					$inputType && $specifics []= sprintf( '%sview-%d-field-%s-%s.php', $slug_dir, $view_id, $inputType, $slug_name );
214 94
					$specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $field_type );
215 94
					$inputType && $specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $inputType );
216
217 94
					$specifics []= sprintf( '%sfield-%s-%s.php', $slug_dir, $field_type, $slug_name );
218 94
					$inputType && $specifics []= sprintf( '%sfield-%s-%s.php', $slug_dir, $inputType, $slug_name );
219 94
					$specifics []= sprintf( '%sfield-%s.php', $slug_dir, $field_type );
220 94
					$inputType && $specifics []= sprintf( '%sfield-%s.php', $slug_dir, $inputType );
221
				}
222
			}
223
224 94
			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...
225
				/** Generic field templates */
226 94
				$specifics []= sprintf( '%sview-%d-field-%s.php', $slug_dir, $view_id, $slug_name );
227 94
				$specifics []= sprintf( '%sform-%d-field-%s.php', $slug_dir, $form_id, $slug_name );
228
229 94
				$specifics []= sprintf( '%sview-%d-field.php', $slug_dir, $view_id );
230 94
				$specifics []= sprintf( '%sform-%d-field.php', $slug_dir, $form_id );
231
			}
232
233
			/**
234
			 * Legacy.
235
			 * Ignore some types that conflict.
236
			 */
237 94
			if ( ! in_array( $field_type, array( 'notes' ) ) ) {
238 93
				$specifics []= sprintf( '%s.php', $field_type );
239 93
				$specifics []= sprintf( 'fields/%s.php', $field_type );
240
			}
241
242 94
			$specifics []= sprintf( '%sfield-%s.php', $slug_dir, $slug_name );
243 94
			$specifics []= sprintf( '%sfield.php', $slug_dir );
244
245 94
			return array_merge( $specifics, $templates );
246 94
		};
247
	}
248
249
	/**
250
	 * Output some HTML.
251
	 *
252
	 * @todo Move to \GV\Field_HTML_Template, but call filters here?
253
	 *
254
	 * @return void
255
	 */
256 94
	public function render() {
257 94
		if ( ! $entry = $this->entry->from_field( $this->field ) ) {
258
			gravityview()->log->error( 'Entry is invalid for field. Returning empty.' );
259
			return;
260
		}
261
262
		/** Retrieve the value. */
263 94
		$display_value = $value = $this->field->get_value( $this->view, $this->source, $entry );
264
265 94
		$source = $this->source;
266 94
		$source_backend = $source ? $source::$backend : null;
267
268 94
		\GV\Mocks\Legacy_Context::load( array(
269 94
			'field' => $this->field,
270
		) );
271
272
		/** Alter the display value according to Gravity Forms. */
273 94
		if ( $source_backend == \GV\Source::BACKEND_GRAVITYFORMS ) {
274
			/** Prevent any PHP warnings that may be generated. */
275 57
			ob_start();
276
277 57
			$display_value = \GFCommon::get_lead_field_display( $this->field->field, $value, $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...
278
279 57
			if ( $errors = ob_get_clean() ) {
280
				gravityview()->log->error( 'Errors when calling GFCommon::get_lead_field_display()', array( 'data' => $errors ) );
281
			}
282
283
			// `gform_entry_field_value` expects a GF_Field, but $this->field->field can be NULL
284 57
			if ( ! $this->field->field instanceof GF_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...
285 57
				$gf_field = \GF_Fields::create( $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...
286
			}
287
288
			/** Call the Gravity Forms field value filter. */
289 57
			$display_value = apply_filters( 'gform_entry_field_value', $display_value, $gf_field, $entry->as_entry(), $this->source->form );
0 ignored issues
show
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...
Bug introduced by
The variable $gf_field does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
290
291 57
			unset( $gf_field );
292
293
			/** Replace merge tags for admin-only fields. */
294 57
			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...
295
				$display_value = \GravityView_API::replace_variables( $display_value, $this->form->form, $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...
296
			}
297
		}
298
299 94
		$context = Template_Context::from_template( $this, compact( 'display_value', 'value' ) );
300
301
		/**
302
		 * Make various pieces of data available to the template
303
		 *  under the $gravityview scoped variable.
304
		 *
305
		 * @filter `gravityview/template/field/context`
306
		 * @param \GV\Template_Context $context The context for this template.
307
		 * @since 2.0
308
		 */
309 94
		$this->push_template_data( apply_filters( 'gravityview/template/field/context', $context ), 'gravityview' );
310
311
		/** Bake the template. */
312 94
		ob_start();
313 94
		$this->located_template = $this->get_template_part( static::$slug );
314 94
		$output = ob_get_clean();
315
316 94
		if ( empty( $output ) ) {
317
			/**
318
			 * @filter `gravityview_empty_value` What to display when a field is empty
319
			 * @deprecated Use the `gravityview/field/value/empty` filter instead
320
			 * @param string $value (empty string)
321
			 */
322 30
			$output = apply_filters( 'gravityview_empty_value', $output );
323
324
			/**
325
			 * @filter `gravityview/field/value/empty` What to display when this field is empty.
326
			 * @param string $value The value to display (Default: empty string)
327
			 * @param \GV\Template_Context The template context this is being called from.
328
			 */
329 30
			$output = apply_filters( 'gravityview/field/value/empty', $output, Template_Context::from_template( $this ) );
330
331 30
			$context = Template_Context::from_template( $this, compact( 'display_value', 'value' ) );
332
		}
333
334 94
		gravityview()->log->info( 'Field template for field #{field_id} loaded: {located_template}', array( 'field_id' => $this->field->ID, 'located_template' => $this->located_template ) );
335
336 94
		$this->pop_template_data( 'gravityview' );
337
338
		/** A compatibility array that's required by some of the deprecated filters. */
339
		$field_compat = array(
340 94
			'form' => $source_backend == \GV\Source::BACKEND_GRAVITYFORMS ? $this->source->form : ( $this->view->form ? $this->view->form->form : null ),
0 ignored issues
show
Documentation introduced by
The property $form is declared private in GV\Form. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write 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.");
        }
    }

}

Since the property has write access only, you can use the @property-write 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...
341 94
			'field_id' => $this->field->ID,
342 94
			'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...
343 94
			'field_settings' => $this->field->as_configuration(),
344 94
			'value' => $value,
345 94
			'display_value' => $display_value,
346 94
			'format' => 'html',
347 94
			'entry' => $entry->as_entry(),
348 94
			'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...
349 94
			'field_path' => $this->located_template,
350
		);
351
352
		/**
353
		 * Wrap output in a link, if enabled in the field settings
354
		 *
355
		 * @todo Cleanup
356
		 *
357
		 * @param string $output HTML value output
358
		 * @param \GV\Template_Context $context
359
		 *
360
		 * @return mixed|string|void
361
		 */
362
		$pre_link_compat_callback = function( $output, $context ) use ( $field_compat ) {
363 94
			$field = $context->field;
364
365
			/**
366
			 * @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`
367
			 * @since 1.16
368
			 * @param string $output HTML value output
369
			 * @param array  $entry The GF entry array
370
			 * @param array  $field_settings Settings for the particular GV field
371
			 * @param array  $field Field array, as fetched from GravityView_View::getCurrentField()
372
			 *
373
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
374
			 */
375 94
			$output = apply_filters( "gravityview_field_entry_value_{$field->type}_pre_link", $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
376
377 94
			$output = apply_filters( 'gravityview_field_entry_value_pre_link', $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
378
379
			/**
380
			 * Link to the single entry by wrapping the output in an anchor tag
381
			 *
382
			 * Fields can override this by modifying the field data variable inside the field. See /templates/fields/post_image.php for an example.
383
			 */
384 94
			if ( ! empty( $field->show_as_link ) && ! \gv_empty( $output, false, false ) ) {
385 4
				$link_atts = empty( $field->new_window ) ? array() : array( 'target' => '_blank' );
386
387 4
				$permalink = $context->entry->get_permalink( $context->view, $context->request );
388 4
				$output = \gravityview_get_link( $permalink, $output, $link_atts );
389
390
				/**
391
				 * @filter `gravityview_field_entry_link` Modify the link HTML
392
				 * @param string $link HTML output of the link
393
				 * @param string $href URL of the link
394
				 * @param array  $entry The GF entry array
395
				 * @param array $field_settings Settings for the particular GV field
396
				 * @deprecated Use `gravityview/template/field/entry_link`
397
				 */
398 4
				$output = apply_filters( 'gravityview_field_entry_link', $output, $permalink, $context->entry->as_entry(), $field->as_configuration() );
399
400
				/**
401
				 * @filter `gravityview/template/field/entry_link` Modify the link HTML
402
				 * @since 2.0
403
				 * @param string $link HTML output of the link
404
				 * @param string $href URL of the link
405
				 * @param \GV\Template_Context $context The context
406
				 */
407 4
				$output = apply_filters( 'gravityview/template/field/entry_link', $output, $permalink, $context );
408
			}
409
410 94
			return $output;
411 94
		};
412
413
		// TODO Cleanup
414
		$post_link_compat_callback = function( $output, $context ) use ( $field_compat ) {
415 94
			$field = $context->field;
416
417
			/**
418
			 * @filter `gravityview_field_entry_value_{$field_type}` Modify the field value output for a field type. Example: `gravityview_field_entry_value_number`
419
			 * @since 1.6
420
			 * @param string $output HTML value output
421
			 * @param array  $entry The GF entry array
422
			 * @param  array $field_settings Settings for the particular GV field
423
			 * @param array $field Current field being displayed
424
			 *
425
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
426
			 */
427 94
			$output = apply_filters( "gravityview_field_entry_value_{$field->type}", $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
428
429
			/**
430
			 * @filter `gravityview_field_entry_value` Modify the field value output for all field types
431
			 * @param string $output HTML value output
432
			 * @param array  $entry The GF entry array
433
			 * @param  array $field_settings Settings for the particular GV field
434
			 * @param array $field_data  {@since 1.6}
435
			 *
436
			 * @deprecated Use the `gravityview/field/{$field_type}/output` or `gravityview/field/output` filters instead.
437
			 */
438 94
			$output = apply_filters( 'gravityview_field_entry_value', $output, $context->entry->as_entry(), $field->as_configuration(), $field_compat );
439
440
			/**
441
			 * @filter `gravityview/template/field/{$field_type}/output` Modify the field output for a field type.
442
			 *
443
			 * @since 2.0
444
			 *
445
			 * @param string $output The current output.
446
			 * @param \GV\Template_Context The template context this is being called from.
447
			 */
448 94
			return apply_filters( "gravityview/template/field/{$field->type}/output", $output, $context );
449 94
		};
450
451
		/**
452
		 * Okay, what's this whole pre/post_link compat deal, huh?
453
		 *
454
		 * Well, the `gravityview_field_entry_value_{$field_type}_pre_link` filter
455
		 *  is expected to be applied before the value is turned into an entry link.
456
		 *
457
		 * And then `gravityview_field_entry_value_{$field_type}` and `gravityview_field_entry_value`
458
		 *  are called afterwards.
459
		 *
460
		 * So we're going to use filter priorities to make sure this happens inline with
461
		 *  our new filters, in the correct sequence. Pre-link called with priority 5 and
462
		 *  post-link called with priority 9. Then everything else.
463
		 *
464
		 * If a new code wants to alter the value before it is hyperlinked (hyperlinkified?),
465
		 *  it should hook into a priority between -inf. and 8. Afterwards: 10 to +inf.
466
		 */
467 94
		add_filter( 'gravityview/template/field/output', $pre_link_compat_callback, 5, 2 );
468 94
		add_filter( 'gravityview/template/field/output', $post_link_compat_callback, 9, 2 );
469
470
		/**
471
		 * @filter `gravityview/template/field/output` Modify the field output for a field.
472
		 *
473
		 * @since 2.0
474
		 *
475
		 * @param string $output The current output.
476
		 * @param \GV\Template_Context The template this is being called from.
477
		 */
478 94
		echo apply_filters( "gravityview/template/field/output", $output, $context );
479
480 94
		remove_filter( 'gravityview/template/field/output', $pre_link_compat_callback, 5 );
481 94
		remove_filter( 'gravityview/template/field/output', $post_link_compat_callback, 9 );
482 94
	}
483
}
484
485
/** Load implementations. */
486
require gravityview()->plugin->dir( 'future/includes/class-gv-template-field-html.php' );
487
require gravityview()->plugin->dir( 'future/includes/class-gv-template-field-csv.php' );
488