GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-ajax.php
Go to the documentation of this file.
1 <?php
2 
4 
5  function __construct() {
6 
7  //get field options
8  add_action( 'wp_ajax_gv_field_options', array( $this, 'get_field_options' ) );
9 
10  // get available fields
11  add_action( 'wp_ajax_gv_available_fields', array( $this, 'get_available_fields_html' ) );
12 
13  // get active areas
14  add_action( 'wp_ajax_gv_get_active_areas', array( $this, 'get_active_areas' ) );
15 
16  // get preset fields
17  add_action( 'wp_ajax_gv_get_preset_fields', array( $this, 'get_preset_fields_config' ) );
18 
19  // get preset fields
20  add_action( 'wp_ajax_gv_set_preset_form', array( $this, 'create_preset_form' ) );
21 
22  add_action( 'wp_ajax_gv_sortable_fields_form', array( $this, 'get_sortable_fields' ) );
23  }
24 
25  /**
26  * Handle exiting the script (for unit testing)
27  *
28  * @since 1.15
29  * @param bool|false $mixed
30  *
31  * @return bool
32  */
33  private function _exit( $mixed = NULL ) {
34 
35  /**
36  * Don't exit if we're running test suite.
37  * @since 1.15
38  */
39  if( defined( 'DOING_GRAVITYVIEW_TESTS' ) && DOING_GRAVITYVIEW_TESTS ) {
40  return $mixed;
41  }
42 
43  exit( $mixed );
44  }
45 
46  /** -------- AJAX ---------- */
47 
48  /**
49  * Verify the nonce. Exit if not verified.
50  * @return void
51  */
52  function check_ajax_nonce() {
53  if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'gravityview_ajaxviews' ) ) {
54  $this->_exit( false );
55  }
56  }
57 
58  /**
59  * AJAX action to get HTML markup for form(s) or template fields
60  * AJAX callback
61  *
62  * @return array|void Terminate request, exit with JSON response or return HTML markup
63  */
65 
66  $this->check_ajax_nonce();
67 
68  $context = rgpost( 'context' );
69 
70  // Return markup for a single or multiple contexts
71  if( $context ) {
72  $data = array(
73  esc_attr( $context ) => ''
74  );
75  } else {
76  $data = array(
77  'directory' => '',
78  'edit' => '',
79  'single' => ''
80  );
81  }
82 
83  if ( is_array( rgpost( 'form_preset_ids' ) ) ) {
84  $form_ids = rgpost( 'form_preset_ids' );
85  } else {
86  $this->_exit( false );
87  return; // If inside unit tests, which don't exit, don't continue.
88  }
89 
90  foreach ( $data as $context => $markup ) {
91  ob_start();
92 
93  do_action( 'gravityview_render_field_pickers', $context, $form_ids );
94 
95  $data[ $context ] = trim( ob_get_clean() );
96  }
97 
98  if ( defined( 'DOING_GRAVITYVIEW_TESTS' ) && DOING_GRAVITYVIEW_TESTS ) {
99  return $data;
100  }
101 
102  wp_send_json_success( $data );
103  }
104 
105  /**
106  * Returns template active areas given a template ID
107  * AJAX callback
108  *
109  * @return void
110  */
111  function get_active_areas() {
112  $this->check_ajax_nonce();
113 
114  if( empty( $_POST['template_id'] ) ) {
115  $this->_exit( false );
116  }
117 
118  ob_start();
119  do_action( 'gravityview_render_directory_active_areas', \GV\Utils::_POST('template_id'), 'directory', '', true, \GV\Utils::_POST( 'form_id', 0 ) );
120  $response['directory'] = ob_get_clean();
121 
122  ob_start();
123  do_action( 'gravityview_render_directory_active_areas', \GV\Utils::_POST('template_id'), 'single', '', true, \GV\Utils::_POST( 'form_id', 0 ) );
124  $response['single'] = ob_get_clean();
125 
126  $response = array_map( 'gravityview_strip_whitespace', $response );
127 
128  $this->_exit( json_encode( $response ) );
129  }
130 
131  /**
132  * Fill in active areas with preset configuration according to the template selected
133  * @return void
134  */
136 
137  $this->check_ajax_nonce();
138 
139  if( empty( $_POST['template_id'] ) ) {
140  $this->_exit( false );
141  }
142 
143  // get the fields xml config file for this specific preset
144  $preset_fields_path = apply_filters( 'gravityview_template_fieldsxml', array(), $_POST['template_id'] );
145  // import fields
146  if( !empty( $preset_fields_path ) ) {
147  $presets = $this->import_fields( $preset_fields_path );
148  } else {
149  $presets = array( 'widgets' => array(), 'fields' => array() );
150  }
151 
152  $template_id = esc_attr( $_POST['template_id'] );
153 
154  // template areas
155  $template_areas_directory = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'directory' );
156  $template_areas_single = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'single' );
157 
158  // widget areas
159  $default_widget_areas = \GV\Widget::get_default_widget_areas();
160 
161  ob_start();
162  do_action('gravityview_render_active_areas', $template_id, 'widget', 'header', $default_widget_areas, $presets['widgets'] );
163  $response['header'] = ob_get_clean();
164 
165  ob_start();
166  do_action('gravityview_render_active_areas', $template_id, 'widget', 'footer', $default_widget_areas, $presets['widgets'] );
167  $response['footer'] = ob_get_clean();
168 
169  ob_start();
170  do_action('gravityview_render_active_areas', $template_id, 'field', 'directory', $template_areas_directory, $presets['fields'] );
171  $response['directory'] = ob_get_clean();
172 
173  ob_start();
174  do_action('gravityview_render_active_areas', $template_id, 'field', 'single', $template_areas_single, $presets['fields'] );
175  $response['single'] = ob_get_clean();
176 
177  $response = array_map( 'gravityview_strip_whitespace', $response );
178 
179  gravityview()->log->debug( '[get_preset_fields_config] AJAX Response', array( 'data' => $response ) );
180 
181  $this->_exit( json_encode( $response ) );
182  }
183 
184  /**
185  * Create the preset form requested before the View save
186  *
187  * @return void
188  */
189  function create_preset_form() {
190 
191  $this->check_ajax_nonce();
192 
193  if( empty( $_POST['template_id'] ) ) {
194  gravityview()->log->error( 'Cannot create preset form; the template_id is empty.' );
195  $this->_exit( false );
196  }
197 
198  // get the xml for this specific template_id
199  $preset_form_xml_path = apply_filters( 'gravityview_template_formxml', '', $_POST['template_id'] );
200 
201  // import form
202  $form = $this->import_form( $preset_form_xml_path );
203 
204  // get the form ID
205  if( false === $form ) {
206  // send error to user
207  gravityview()->log->error( 'Error importing form for template id: {template_id}', array( 'template_id' => (int) $_POST['template_id'] ) );
208 
209  $this->_exit( false );
210  }
211 
212  $this->_exit( '<option value="'.esc_attr( $form['id'] ).'" selected="selected">'.esc_html( $form['title'] ).'</option>' );
213 
214  }
215 
216  /**
217  * Import Gravity Form XML or JSON
218  *
219  * @param string $xml_or_json_path Path to form XML or JSON file
220  * @return int|bool Imported form ID or false
221  */
222  function import_form( $xml_or_json_path = '' ) {
223 
224  gravityview()->log->debug( '[import_form] Import Preset Form. (File) {path}', array( 'path' => $xml_or_json_path ) );
225 
226  if( empty( $xml_or_json_path ) || !class_exists('GFExport') || !file_exists( $xml_or_json_path ) ) {
227  gravityview()->log->error( 'Class GFExport or file not found. file: {path}', array( 'path' => $xml_or_json_path ) );
228  return false;
229  }
230 
231  // import form
232  $forms = '';
233  $count = GFExport::import_file( $xml_or_json_path, $forms );
234 
235  gravityview()->log->debug( '[import_form] Importing form (Result) {count}', array( 'count' => $count ) );
236  gravityview()->log->debug( '[import_form] Importing form (Form) ', array( 'data' => $forms ) );
237 
238  if( $count != 1 || empty( $forms[0]['id'] ) ) {
239  gravityview()->log->error( 'Form Import Failed!' );
240  return false;
241  }
242 
243  // import success - return form id
244  return $forms[0];
245  }
246 
247 
248  /**
249  * Returns field options - called by ajax when dropping fields into active areas
250  * AJAX callback
251  *
252  * @return void
253  */
254  function get_field_options() {
255  $this->check_ajax_nonce();
256 
257  if( empty( $_POST['template'] ) || empty( $_POST['area'] ) || empty( $_POST['field_id'] ) || empty( $_POST['field_type'] ) ) {
258  gravityview()->log->error( 'Required fields were not set in the $_POST request. ' );
259  $this->_exit( false );
260  }
261 
262  // Fix apostrophes added by JSON response
263  $_post = array_map( 'stripslashes_deep', $_POST );
264 
265  // Sanitize
266  $_post = array_map( 'esc_attr', $_post );
267 
268  // The GF type of field: `product`, `name`, `creditcard`, `id`, `text`
269  $input_type = isset($_post['input_type']) ? esc_attr( $_post['input_type'] ) : NULL;
270  $context = isset($_post['context']) ? esc_attr( $_post['context'] ) : NULL;
271 
272  $form_id = empty( $_post['form_id'] ) ? null : $_post['form_id'];
273  $response = GravityView_Render_Settings::render_field_options( $form_id, $_post['field_type'], $_post['template'], $_post['field_id'], $_post['field_label'], $_post['area'], $input_type, '', '', $context );
274 
275  $response = gravityview_strip_whitespace( $response );
276 
277  $this->_exit( $response );
278  }
279 
280  /**
281  * Given a View id, calculates the assigned form, and returns the form fields (only the sortable ones )
282  * AJAX callback
283  *
284  *
285  * @return void
286  */
287  function get_sortable_fields() {
288  $this->check_ajax_nonce();
289 
290  $form = '';
291 
292  // if form id is set, use it, else, get form from preset
293  if( !empty( $_POST['form_id'] ) ) {
294 
295  $form = (int) $_POST['form_id'];
296 
297  }
298  // get form from preset
299  elseif( !empty( $_POST['template_id'] ) ) {
300 
301  $form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
302 
303  }
304 
305  $response = gravityview_get_sortable_fields( $form );
306 
307  $response = gravityview_strip_whitespace( $response );
308 
309  $this->_exit( $response );
310  }
311 
312  /**
313  * Get the form fields for a preset (no form created yet)
314  *
315  * @param string $template_id Preset template
316  *
317  * @return array|false
318  */
319  static function pre_get_form_fields( $template_id = '') {
320  if( empty( $template_id ) ) {
321  gravityview()->log->error( 'Template ID not set.' );
322  return false;
323  } else {
324  $form_file = apply_filters( 'gravityview_template_formxml', '', $template_id );
325  if( !file_exists( $form_file ) ) {
326  gravityview()->log->error( '[{template_id}] form file does not exist: {path}.', array( 'template_id' => $template_id, 'path' => $form_file ) );
327  return false;
328  }
329  }
330 
331  // Import logic from https://github.com/gravityforms/gravityforms/blob/11dc114df56e7f5116d7df1adc54000007c13ec5/export.php#L96 & https://github.com/gravityforms/gravityforms/blob/11dc114df56e7f5116d7df1adc54000007c13ec5/export.php#L106
332  $forms_json = file_get_contents( $form_file );
333 
334  $forms = json_decode( $forms_json, true );
335 
336  if ( ! $forms ) {
337  gravityview()->log->error( 'Could not read the {path} template file.', array( 'path' => $form_file ) );
338 
339  return false;
340  }
341 
342  $form = GFFormsModel::convert_field_objects( $forms[0] );
343  $form = GFFormsModel::sanitize_settings( $form );
344 
345  gravityview()->log->debug( '[pre_get_form_fields] Importing Form Fields for preset [{template_id}]. (Form)', array( 'template_id' => $template_id, 'data' => $form ) );
346 
347  return $form;
348  }
349 
350  /**
351  * Import fields configuration from an exported WordPress View preset
352  * @param string $file path to file
353  * @return array Fields config array (unserialized)
354  */
355  function import_fields( $file ) {
356 
357  if( empty( $file ) || !file_exists( $file ) ) {
358  gravityview()->log->error( 'Importing Preset Fields. File not found. (File) {path}', array( 'path' => $file ) );
359  return false;
360  }
361 
362  if( !class_exists('WXR_Parser') ) {
363  include_once GRAVITYVIEW_DIR . 'includes/lib/xml-parsers/parsers.php';
364  }
365 
366  $parser = new WXR_Parser();
367  $presets = $parser->parse( $file );
368 
369  if(is_wp_error( $presets )) {
370  gravityview()->log->error( 'Importing Preset Fields failed. Threw WP_Error.', array( 'data' => $presets ) );
371  return false;
372  }
373 
374  if( empty( $presets['posts'][0]['postmeta'] ) && !is_array( $presets['posts'][0]['postmeta'] ) ) {
375  gravityview()->log->error( 'Importing Preset Fields failed. Meta not found in file. {path}', array( 'path' => $file ) );
376  return false;
377  }
378 
379  gravityview()->log->debug( '[import_fields] postmeta', array( 'data' => $presets['posts'][0]['postmeta'] ) );
380 
381  $fields = $widgets = array();
382  foreach( $presets['posts'][0]['postmeta'] as $meta ) {
383  switch ($meta['key']) {
384  case '_gravityview_directory_fields':
385  $fields = maybe_unserialize( $meta['value'] );
386  break;
387  case '_gravityview_directory_widgets':
388  $widgets = maybe_unserialize( $meta['value'] );
389  break;
390  }
391  }
392 
393  gravityview()->log->debug( '[import_fields] Imported Preset (Fields)', array( 'data' => $fields ) );
394  gravityview()->log->debug( '[import_fields] Imported Preset (Widgets)', array( 'data' => $widgets ) );
395 
396  return array(
397  'fields' => $fields,
398  'widgets' => $widgets
399  );
400  }
401 }
402 
const GRAVITYVIEW_DIR
"GRAVITYVIEW_DIR" "./" The absolute path to the plugin directory, with trailing slash ...
Definition: gravityview.php:49
import_form( $xml_or_json_path='')
Import Gravity Form XML or JSON.
Definition: class-ajax.php:222
$forms
Definition: data-source.php:19
static render_field_options( $form_id, $field_type, $template_id, $field_id, $field_label, $area, $input_type=NULL, $uniqid='', $current='', $context='single', $item=array())
Render Field Options html (shown through a dialog box)
if(! function_exists( 'gravityview_sanitize_html_class')) gravityview_strip_whitespace( $string)
Replace multiple newlines, tabs, and spaces with a single space.
import_fields( $file)
Import fields configuration from an exported WordPress View preset.
Definition: class-ajax.php:355
_exit( $mixed=NULL)
Handle exiting the script (for unit testing)
Definition: class-ajax.php:33
create_preset_form()
Create the preset form requested before the View save.
Definition: class-ajax.php:189
static get_default_widget_areas()
Default widget areas.
if(gravityview() ->plugin->is_GF_25()) $form
new GravityView_Ajax
Definition: class-ajax.php:403
get_sortable_fields()
Given a View id, calculates the assigned form, and returns the form fields (only the sortable ones ) ...
Definition: class-ajax.php:287
get_field_options()
Returns field options - called by ajax when dropping fields into active areas AJAX callback...
Definition: class-ajax.php:254
static pre_get_form_fields( $template_id='')
Get the form fields for a preset (no form created yet)
Definition: class-ajax.php:319
get_available_fields_html()
AJAX action to get HTML markup for form(s) or template fields AJAX callback.
Definition: class-ajax.php:64
gravityview_get_sortable_fields( $formid, $current='')
Render dropdown (select) with the list of sortable fields from a form ID.
check_ajax_nonce()
--—— AJAX ----——
Definition: class-ajax.php:52
if(empty( $created_by)) $form_id
gravityview()
The main GravityView wrapper function.
get_active_areas()
Returns template active areas given a template ID AJAX callback.
Definition: class-ajax.php:111
get_preset_fields_config()
Fill in active areas with preset configuration according to the template selected.
Definition: class-ajax.php:135