1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @file class-gravityview-field-sequence.php |
4
|
|
|
* @package GravityView |
5
|
|
|
* @subpackage includes\fields |
6
|
|
|
*/ |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Add a sequence field. |
10
|
|
|
* @since develop |
11
|
|
|
*/ |
12
|
|
|
class GravityView_Field_Sequence extends GravityView_Field { |
13
|
|
|
|
14
|
|
|
var $name = 'sequence'; |
15
|
|
|
|
16
|
|
|
var $contexts = array( 'single', 'multiple' ); |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* @var bool |
20
|
|
|
*/ |
21
|
|
|
var $is_sortable = false; |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* @var bool |
25
|
|
|
*/ |
26
|
|
|
var $is_searchable = false; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* @var bool |
30
|
|
|
*/ |
31
|
|
|
var $is_numeric = true; |
32
|
|
|
|
33
|
|
|
var $_custom_merge_tag = 'sequence'; |
34
|
|
|
|
35
|
|
|
var $group = 'gravityview'; |
36
|
|
|
|
37
|
|
|
public function __construct() { |
38
|
|
|
|
39
|
|
|
$this->label = esc_html__( 'Result Number', 'gravityview' ); |
40
|
|
|
|
41
|
|
|
add_filter( 'gravityview/metaboxes/tooltips', array( $this, 'field_tooltips') ); |
42
|
|
|
|
43
|
|
|
parent::__construct(); |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* Add tooltips |
48
|
|
|
* @param array $tooltips Existing tooltips |
49
|
|
|
* @return array Modified tooltips |
50
|
|
|
*/ |
51
|
|
|
public function field_tooltips( $tooltips ) { |
52
|
|
|
|
53
|
|
|
$return = $tooltips; |
54
|
|
|
|
55
|
|
|
$return['reverse_sequence'] = array( |
56
|
|
|
'title' => __('Reverse the order of the result numbers', 'gravityview'), |
57
|
|
|
'value' => __('Output row numbers in descending order. If enabled, numbers will go from high to low.', 'gravityview'), |
58
|
|
|
); |
59
|
|
|
|
60
|
|
|
return $return; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
public function field_options( $field_options, $template_id, $field_id, $context, $input_type ) { |
64
|
2 |
|
|
65
|
2 |
|
unset ( $field_options['search_filter'] ); |
66
|
|
|
|
67
|
2 |
|
$new_fields = array( |
68
|
|
|
'start' => array( |
69
|
2 |
|
'type' => 'number', |
70
|
2 |
|
'label' => __( 'First Row Number', 'gravityview' ), |
71
|
|
|
'value' => '1', |
72
|
|
|
'merge_tags' => false, |
73
|
|
|
), |
74
|
|
|
'reverse' => array( |
75
|
|
|
'type' => 'checkbox', |
76
|
|
|
'label' => __( 'Reverse the order of the result numbers', 'gravityview' ), |
77
|
2 |
|
'tooltip' => 'reverse_sequence', |
78
|
1 |
|
'value' => '', |
79
|
1 |
|
), |
80
|
1 |
|
); |
81
|
1 |
|
|
82
|
1 |
|
return $new_fields + $field_options; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* Replace {sequence} Merge Tags inside Custom Content fields |
87
|
|
|
* |
88
|
|
|
* TODO: |
89
|
|
|
* - Find a better way to infer current View data (without using legacy code) |
90
|
|
|
* - Add tests |
91
|
|
|
* |
92
|
|
|
* @param array $matches |
93
|
|
|
* @param string $text |
94
|
|
|
* @param array $form |
95
|
|
|
* @param array $entry |
96
|
|
|
* @param bool $url_encode |
97
|
|
|
* @param bool $esc_html |
98
|
|
|
* |
99
|
|
|
* @return string |
100
|
|
|
*/ |
101
|
|
|
public function replace_merge_tag( $matches = array(), $text = '', $form = array(), $entry = array(), $url_encode = false, $esc_html = false ) { |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
$view_data = gravityview_get_current_view_data(); // TODO: Don't use legacy code... |
105
|
|
|
|
106
|
|
|
if ( empty( $view_data ) ) { |
107
|
|
|
return ''; |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
$return = $text; |
111
|
|
|
|
112
|
|
|
$context = new \GV\Template_Context(); |
113
|
|
|
$context->view = \GV\View::by_id( $view_data['view_id'] ); |
114
|
|
|
$context->entry = \GV\GF_Entry::from_entry( $entry ); |
115
|
|
|
|
116
|
|
|
$gv_field = \GV\Internal_Field::by_id( 'sequence' ); |
117
|
|
|
|
118
|
|
|
foreach ( $matches as $match ) { |
119
|
|
|
|
120
|
|
|
$full_tag = $match[0]; |
121
|
|
|
$property = $match[1]; |
122
|
|
|
|
123
|
|
|
$gv_field->reverse = false; |
|
|
|
|
124
|
|
|
$gv_field->start = 1; |
|
|
|
|
125
|
|
|
|
126
|
|
|
$modifiers = explode( ',', trim( $property ) ); |
127
|
|
|
|
128
|
|
|
foreach ( $modifiers as $modifier ) { |
129
|
|
|
|
130
|
|
|
$modifier = trim( $modifier ); |
131
|
|
|
|
132
|
|
|
if ( 'reverse' === $modifier ) { |
133
|
|
|
$gv_field->reverse = true; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
$maybe_start = explode( ':', $modifier ); |
137
|
|
|
|
138
|
|
|
if( 'start' === rgar( $maybe_start, 0 ) && is_numeric( rgar( $maybe_start, 1 ) ) ) { |
139
|
|
|
$gv_field->start = (int) rgar( $maybe_start, 1 ); |
140
|
|
|
} |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
$context->field = $gv_field; |
144
|
|
|
|
145
|
|
|
$return = str_replace( $full_tag, $this->get_sequence( $context ), $return ); |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
return $return; |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Calculate the current sequence number for the context. |
153
|
|
|
* |
154
|
|
|
* @param \GV\Template_Context $context The context. |
155
|
|
|
* |
156
|
|
|
* @return int The sequence number for the field/entry within the view results. |
157
|
|
|
*/ |
158
|
|
|
public function get_sequence( $context ) { |
159
|
|
|
static $startlines = array(); |
160
|
|
|
|
161
|
|
|
$context_key = md5( json_encode( |
162
|
|
|
array( |
163
|
|
|
$context->view->ID, |
164
|
|
|
\GV\Utils::get( $context, 'field/UID' ), //TODO: Generate UID when using Merge Tag |
165
|
|
|
) |
166
|
|
|
) ); |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Figure out the starting number. |
170
|
|
|
*/ |
171
|
|
|
if ( $context->request && $entry = $context->request->is_entry() ) { |
172
|
|
|
$sql_query = ''; |
173
|
|
|
add_filter( 'gform_gf_query_sql', $callback = function( $sql ) use ( &$sql_query ) { |
174
|
|
|
$sql_query = $sql; |
175
|
|
|
return $sql; |
176
|
|
|
} ); |
177
|
|
|
|
178
|
|
|
$total = $context->view->get_entries()->total(); |
179
|
|
|
remove_filter( 'gform_gf_query_sql', $callback ); |
180
|
|
|
|
181
|
|
|
unset( $sql_query['paginate'] ); |
182
|
|
|
|
183
|
|
|
global $wpdb; |
184
|
|
|
|
185
|
|
|
foreach ( $wpdb->get_results( implode( ' ', $sql_query ), ARRAY_A ) as $n => $result ) { |
186
|
|
|
if ( in_array( $entry->ID, $result ) ) { |
187
|
|
|
return $context->field->reverse ? ( $total - $n ) : ( $n + 1 ); |
|
|
|
|
188
|
|
|
} |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return 0; |
192
|
|
|
} elseif ( ! isset( $startlines[ $context_key ] ) ) { |
193
|
|
|
$pagenum = max( 0, \GV\Utils::_GET( 'pagenum', 1 ) - 1 ); |
194
|
|
|
$pagesize = $context->view->settings->get( 'page_size', 25 ); |
195
|
|
|
|
196
|
|
|
if ( $context->field->reverse ) { |
|
|
|
|
197
|
|
|
$startlines[ $context_key ] = $context->view->get_entries()->total() - ( $pagenum * $pagesize ); |
198
|
|
|
$startlines[ $context_key ] += $context->field->start - 1; |
|
|
|
|
199
|
|
|
} else { |
200
|
|
|
$startlines[ $context_key ] = ( $pagenum * $pagesize ) + $context->field->start; |
|
|
|
|
201
|
|
|
} |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
return $context->field->reverse ? $startlines[ $context_key ]-- : $startlines[ $context_key ]++; |
|
|
|
|
205
|
|
|
} |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
new GravityView_Field_Sequence; |
209
|
|
|
|
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.