Completed
Pull Request — develop (#1487)
by Gennady
07:54
created

GravityView_Field_Custom   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 214
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 7

Test Coverage

Coverage 32.93%

Importance

Changes 0
Metric Value
dl 0
loc 214
ccs 27
cts 82
cp 0.3293
rs 10
c 0
b 0
f 0
wmc 23
lcom 0
cbo 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 1
A field_options() 0 44 2
B show_field_in_edit_entry() 0 44 6
C add_filtersorts() 0 59 14
1
<?php
2
/**
3
 * @file class-gravityview-field-custom.php
4
 * @package GravityView
5
 * @subpackage includes\fields
6
 */
7
8
/**
9
 * Add custom options for Code field
10
 * @since 1.2
11
 */
12
class GravityView_Field_Custom extends GravityView_Field {
13
14
	var $name = 'custom';
15
16
	var $contexts = array( 'single', 'multiple', 'edit' );
17
18
	/**
19
	 * @var bool
20
	 * @since 1.15.3
21
	 */
22
	var $is_sortable = true;
23
24
	/**
25
	 * @var bool
26
	 * @since 1.15.3
27
	 */
28
	var $is_searchable = false;
29
30
	var $group = 'gravityview';
31
32
	public function __construct() {
33
34
		$this->label = esc_html__( 'Custom Content', 'gravityview' );
35
36
		add_filter( 'gravityview/edit_entry/form_fields', array( $this, 'show_field_in_edit_entry' ), 10, 4 );
37
38
		add_filter( 'gravityview/view/add_filtersorts', array( $this, 'add_filtersorts' ), 10, 2 );
39
40
		/**
41
		 * @filter `gravityview/fields/custom/sortable` Whether the custom content field should be sortable or not.
42
		 * @param bool $sortable
43
		 */
44
		$this->is_sortable = apply_filters( 'gravityview/fields/custom/sortable', $this->is_sortable );
45
46
		parent::__construct();
47
	}
48
49
	/**
50
	 * @inheritDoc
51
	 * @since 2.9.1 Added "This content is numeric" setting
52
	 */
53
	public function field_options( $field_options, $template_id, $field_id, $context, $input_type, $form_id ) {
54
55
		unset ( $field_options['search_filter'], $field_options['show_as_link'] );
56
57
		$new_fields = array(
58
			'content' => array(
59
				'type' => 'textarea',
60
				'label' => __( 'Custom Content', 'gravityview' ),
61
				'desc' => sprintf( __( 'Enter text or HTML. Also supports shortcodes. You can show or hide data using the %s shortcode (%slearn more%s).', 'gravityview' ), '<code>[gvlogic]</code>', '<a href="https://docs.gravityview.co/article/252-gvlogic-shortcode" data-beacon-article-sidebar="552355bfe4b0221aadf2572b">', '</a>' ) . ' ' . sprintf( __( 'Click the arrow icon next to the content area to add %sMerge Tags%s.', 'gravityview' ), '<a href="https://docs.gravityview.co/article/76-merge-tags" data-beacon-article-inline="54c67bbbe4b051242988551d">', '</a>' ),
62
				'value' => '',
63
				'class'	=> 'code',
64
				'merge_tags' => 'force',
65
				'rows' => 15,
66
				'show_all_fields' => true, // Show the `{all_fields}` and `{pricing_fields}` merge tags
67
			),
68
			'wpautop' => array(
69
				'type' => 'checkbox',
70
				'label' => __( 'Automatically add paragraphs to content', 'gravityview' ),
71
				'tooltip' => __( 'Wrap each block of text in an HTML paragraph tag (recommended for text).', 'gravityview' ),
72
				'value' => '',
73
			),
74
			'oembed' => array(
75
				'type' => 'checkbox',
76
				'label' => __( 'Render oEmbeds', 'gravityview' ),
77
				'desc' => sprintf( _x( 'Automatically convert oEmbed URLs into embedded content (%slearn more%s).', 'HTML link pointing to WordPress article on oEmbed', 'gravityview' ), '<a href="https://codex.wordpress.org/Embeds" rel="external noopener noreferrer">', '</a>' ),
78
				'value' => '',
79
			),
80
			'admin_label' => array(
81
				'type' => 'text',
82
				'class' => 'widefat',
83
				'label' => __( 'Admin Label', 'gravityview' ),
84
				'desc' => __( 'A label that is only shown in the GravityView View configuration screen.', 'gravityview' ),
85
				'value' => '',
86
			),
87
		);
88
89
		$this->add_field_support( 'is_numeric', $new_fields );
90
91
		if ( 'edit' === $context ) {
92
			unset( $field_options['custom_label'], $field_options['show_label'], $field_options['allow_edit_cap'], $new_fields['wpautop'], $new_fields['oembed'] );
93
		}
94
95
		return $new_fields + $field_options;
96
	}
97
98
	/**
99
	 * Adds the GravityView Custom Content field to the Edit Entry form
100
	 *
101
	 * It does this by pretending to be a HTML field so that Gravity Forms displays it
102
	 *
103
	 * @since 1.19.2
104
	 *
105
	 * @param GF_Field[] $fields Gravity Forms form fields
106
	 * @param array|null $edit_fields Fields for the Edit Entry tab configured in the View Configuration
107
	 * @param array $form GF Form array (`fields` key modified to have only fields configured to show in Edit Entry)
108
	 * @param int $view_id View ID
109
	 *
110
	 * @return GF_Field[] If Custom Content field exists, returns fields array with the fields inserted. Otherwise, returns unmodified fields array.
111
	 */
112
	public function show_field_in_edit_entry( $fields, $edit_fields = null, $form = array(), $view_id = 0 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $view_id is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
113
114
		// Not configured; show all fields.
115
		if ( is_null( $edit_fields ) ) {
116
			return $fields;
117
		}
118
119
		$new_fields = array();
120
		$i = 0;
121
122
		$entry = gravityview()->request->is_edit_entry();
123
124
		// Loop through the configured Edit Entry fields and add Custom Content fields if there are any
125
		// TODO: Make this available to other custom GV field types
126
		foreach ( (array) $edit_fields as $edit_field ) {
127
128
			if( 'custom' === \GV\Utils::get( $edit_field, 'id') ) {
129
130
				$field_data = array(
131
					'label' => \GV\Utils::get( $edit_field, 'custom_label' ),
132
					'customLabel' => \GV\Utils::get( $edit_field, 'custom_label' ),
133
				    'content' => \GV\Utils::get( $edit_field, 'content' ),
134
				);
135
136
				// Replace merge tags in the content
137
				foreach ( $field_data as $key => $field_datum ) {
138
					$field_data[ $key ] = GravityView_Merge_Tags::replace_variables( $field_datum, $form, $entry->as_entry(), false, false );
139
				}
140
141
				$field_data['cssClass'] = \GV\Utils::get( $edit_field, 'custom_class' );
142
143
				$new_fields[] = new GF_Field_HTML( $field_data );
144
145
			} else {
146
				if( isset( $fields[ $i ] ) ) {
147
					$new_fields[] =  $fields[ $i ];
148
				}
149
				$i++;
150
			}
151
152
		}
153
154
		return $new_fields;
155
	}
156
157
	/**
158
	 * Sort by custom content field if required!
159
	 *
160
	 * @param \GV\View $view The view.
161
	 * @param \GV\Request $request The request.
162
	 *
163
	 * @return void
164
	 */
165 75
	public function add_filtersorts( $view, $request ) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
166 75
		if ( ! $view->fields->by_type( 'custom' )->count() ) {
167 66
			return; // No sorts.
168
		}
169
170 9
		if ( ! $sorts = \GV\Utils::_GET( 'sort' ) ) {
171 9
			$sorts = array_combine( (array)$view->settings->get( 'sort_field' ), (array)$view->settings->get( 'sort_direction' ) );
172
		}
173
174 9
		if ( strpos( implode( ':', array_keys( $sorts ) ), 'custom_' ) === false ) {
175 8
			return; // No custom sorts here.
176
		}
177
178
		add_filter( 'gravityview/entries/sort', $callback = function( $compare, $entry1, $entry2, $view, $request ) use ( $sorts ) {
179
			/**
180
			 * We'll actually need to sort everything on the PHP side now.
181
			 * This is weird...
182
			 */
183 1
			$renderer = new \GV\Field_Renderer();
184
185 1
			foreach ( $sorts as $key => $direction ) {
186 1
				if ( strpos( $key, 'custom_' ) === 0 ) {
187 1
					$field = $view->fields->get( str_replace( 'custom_', '', $key ) );
188
				} else {
189
					$field  = is_numeric( $key ) ? \GV\GF_Field::by_id( $view->form, $key ) : \GV\Internal_Field::by_id( $key );
190
				}
191
192 1
				$source = is_numeric( $key ) ? $view->form : new \GV\Internal_Source();
193
194 1
				$value1 = $renderer->render( $field, $view, $source, $entry1, $request );
195 1
				$value2 = $renderer->render( $field, $view, $source, $entry2, $request );
196
197 1
				if ( $value1 === $value2 ) {
198 1
					continue;
199
				}
200
201 1
				if ( $field->is_numeric ) { // @todo do we not have a filter that controls sorting?
202 1
					if ( is_numeric( $value1 ) ) {
203 1
						$value1 = floatval( $value1 );
204
					}
205
206 1
					if ( is_numeric( $value2 ) ) {
207 1
						$value2 = floatval( $value2 );
208
					}
209
210 1
					return strnatcmp( $value1, $value2 ) * ( ( strtolower( $direction ) == 'desc' ) ? -1 : 1 );
211
				} else {
212 1
					return strcmp( $value1, $value2 ) * ( ( strtolower( $direction ) == 'desc' ) ? -1 : 1 );
213
				}
214
215
			}
216
217 1
			return 0; // They're the same.
218 1
		}, 10, 5 );
219
220
		add_action( 'gravityview/view/remove_filtersorts', function() use ( $callback ) {
221
			remove_action( 'gravityview/entries/sort', $callback );
222 1
		} );
223 1
	}
224
225
}
226
227
new GravityView_Field_Custom;
228