GravityView  2.1.1
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  * Returns available fields given a form ID or a preset template ID
60  * AJAX callback
61  *
62  * @access public
63  * @return void
64  */
66 
67  //check nonce
68  $this->check_ajax_nonce();
69 
70  $context = isset($_POST['context']) ? esc_attr( $_POST['context'] ) : 'directory';
71 
72  // If Form was changed, JS sends form ID, if start fresh, JS sends template_id
73  if( !empty( $_POST['form_id'] ) ) {
74  do_action( 'gravityview_render_available_fields', (int) $_POST['form_id'], $context );
75  $this->_exit();
76  } elseif( !empty( $_POST['template_id'] ) ) {
77  $form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
78 
79  /** @see GravityView_Admin_Views::render_available_fields */
80  do_action( 'gravityview_render_available_fields', $form, $context );
81  $this->_exit();
82  }
83 
84  //if everything fails..
85  $this->_exit( false );
86  }
87 
88 
89  /**
90  * Returns template active areas given a template ID
91  * AJAX callback
92  *
93  * @access public
94  * @return void
95  */
96  function get_active_areas() {
97  $this->check_ajax_nonce();
98 
99  if( empty( $_POST['template_id'] ) ) {
100  $this->_exit( false );
101  }
102 
103  ob_start();
104  do_action( 'gravityview_render_directory_active_areas', $_POST['template_id'], 'directory', '', true );
105  $response['directory'] = ob_get_clean();
106 
107  ob_start();
108  do_action( 'gravityview_render_directory_active_areas', $_POST['template_id'], 'single', '', true );
109  $response['single'] = ob_get_clean();
110 
111  $response = array_map( 'gravityview_strip_whitespace', $response );
112 
113  $this->_exit( json_encode( $response ) );
114  }
115 
116  /**
117  * Fill in active areas with preset configuration according to the template selected
118  * @return void
119  */
121 
122  $this->check_ajax_nonce();
123 
124  if( empty( $_POST['template_id'] ) ) {
125  $this->_exit( false );
126  }
127 
128  // get the fields xml config file for this specific preset
129  $preset_fields_path = apply_filters( 'gravityview_template_fieldsxml', array(), $_POST['template_id'] );
130  // import fields
131  if( !empty( $preset_fields_path ) ) {
132  $presets = $this->import_fields( $preset_fields_path );
133  } else {
134  $presets = array( 'widgets' => array(), 'fields' => array() );
135  }
136 
137  $template_id = esc_attr( $_POST['template_id'] );
138 
139  // template areas
140  $template_areas_directory = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'directory' );
141  $template_areas_single = apply_filters( 'gravityview_template_active_areas', array(), $template_id, 'single' );
142 
143  // widget areas
144  $default_widget_areas = GravityView_Widget::get_default_widget_areas();
145 
146  ob_start();
147  do_action('gravityview_render_active_areas', $template_id, 'widget', 'header', $default_widget_areas, $presets['widgets'] );
148  $response['header'] = ob_get_clean();
149 
150  ob_start();
151  do_action('gravityview_render_active_areas', $template_id, 'widget', 'footer', $default_widget_areas, $presets['widgets'] );
152  $response['footer'] = ob_get_clean();
153 
154  ob_start();
155  do_action('gravityview_render_active_areas', $template_id, 'field', 'directory', $template_areas_directory, $presets['fields'] );
156  $response['directory'] = ob_get_clean();
157 
158  ob_start();
159  do_action('gravityview_render_active_areas', $template_id, 'field', 'single', $template_areas_single, $presets['fields'] );
160  $response['single'] = ob_get_clean();
161 
162  $response = array_map( 'gravityview_strip_whitespace', $response );
163 
164  gravityview()->log->debug( '[get_preset_fields_config] AJAX Response', array( 'data' => $response ) );
165 
166  $this->_exit( json_encode( $response ) );
167  }
168 
169  /**
170  * Create the preset form requested before the View save
171  *
172  * @return void
173  */
174  function create_preset_form() {
175 
176  $this->check_ajax_nonce();
177 
178  if( empty( $_POST['template_id'] ) ) {
179  gravityview()->log->error( 'Cannot create preset form; the template_id is empty.' );
180  $this->_exit( false );
181  }
182 
183  // get the xml for this specific template_id
184  $preset_form_xml_path = apply_filters( 'gravityview_template_formxml', '', $_POST['template_id'] );
185 
186  // import form
187  $form = $this->import_form( $preset_form_xml_path );
188 
189  // get the form ID
190  if( false === $form ) {
191  // send error to user
192  gravityview()->log->error( 'Error importing form for template id: {template_id}', array( 'template_id' => (int) $_POST['template_id'] ) );
193 
194  $this->_exit( false );
195  }
196 
197  $this->_exit( '<option value="'.esc_attr( $form['id'] ).'" selected="selected">'.esc_html( $form['title'] ).'</option>' );
198 
199  }
200 
201  /**
202  * Import Gravity Form XML or JSON
203  *
204  * @param string $xml_or_json_path Path to form XML or JSON file
205  * @return int|bool Imported form ID or false
206  */
207  function import_form( $xml_or_json_path = '' ) {
208 
209  gravityview()->log->debug( '[import_form] Import Preset Form. (File) {path}', array( 'path' => $xml_or_json_path ) );
210 
211  if( empty( $xml_or_json_path ) || !class_exists('GFExport') || !file_exists( $xml_or_json_path ) ) {
212  gravityview()->log->error( 'Class GFExport or file not found. file: {path}', array( 'path' => $xml_or_json_path ) );
213  return false;
214  }
215 
216  // import form
217  $forms = '';
218  $count = GFExport::import_file( $xml_or_json_path, $forms );
219 
220  gravityview()->log->debug( '[import_form] Importing form (Result) {count}', array( 'count' => $count ) );
221  gravityview()->log->debug( '[import_form] Importing form (Form) ', array( 'data' => $forms ) );
222 
223  if( $count != 1 || empty( $forms[0]['id'] ) ) {
224  gravityview()->log->error( 'Form Import Failed!' );
225  return false;
226  }
227 
228  // import success - return form id
229  return $forms[0];
230  }
231 
232 
233  /**
234  * Returns field options - called by ajax when dropping fields into active areas
235  * AJAX callback
236  *
237  * @access public
238  * @return void
239  */
240  function get_field_options() {
241  $this->check_ajax_nonce();
242 
243  if( empty( $_POST['template'] ) || empty( $_POST['area'] ) || empty( $_POST['field_id'] ) || empty( $_POST['field_type'] ) ) {
244  gravityview()->log->error( 'Required fields were not set in the $_POST request. ' );
245  $this->_exit( false );
246  }
247 
248  // Fix apostrophes added by JSON response
249  $_post = array_map( 'stripslashes_deep', $_POST );
250 
251  // Sanitize
252  $_post = array_map( 'esc_attr', $_post );
253 
254  // The GF type of field: `product`, `name`, `creditcard`, `id`, `text`
255  $input_type = isset($_post['input_type']) ? esc_attr( $_post['input_type'] ) : NULL;
256  $context = isset($_post['context']) ? esc_attr( $_post['context'] ) : NULL;
257 
258  $form_id = empty( $_post['form_id'] ) ? null : $_post['form_id'];
259  $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 );
260 
261  $response = gravityview_strip_whitespace( $response );
262 
263  $this->_exit( $response );
264  }
265 
266  /**
267  * Given a View id, calculates the assigned form, and returns the form fields (only the sortable ones )
268  * AJAX callback
269  *
270  *
271  * @access public
272  * @return void
273  */
274  function get_sortable_fields() {
275  $this->check_ajax_nonce();
276 
277  $form = '';
278 
279  // if form id is set, use it, else, get form from preset
280  if( !empty( $_POST['form_id'] ) ) {
281 
282  $form = (int) $_POST['form_id'];
283 
284  }
285  // get form from preset
286  elseif( !empty( $_POST['template_id'] ) ) {
287 
288  $form = GravityView_Ajax::pre_get_form_fields( $_POST['template_id'] );
289 
290  }
291 
292  $response = gravityview_get_sortable_fields( $form );
293 
294  $response = gravityview_strip_whitespace( $response );
295 
296  $this->_exit( $response );
297  }
298 
299  /**
300  * Get the the form fields for a preset (no form created yet)
301  * @param string $template_id Preset template
302  *
303  */
304  static function pre_get_form_fields( $template_id = '') {
305 
306  if( empty( $template_id ) ) {
307  gravityview()->log->error( 'Template ID not set.' );
308  return false;
309  } else {
310  $form_file = apply_filters( 'gravityview_template_formxml', '', $template_id );
311  if( !file_exists( $form_file ) ) {
312  gravityview()->log->error( 'Importing Form Fields for preset [{template_id}]. File not found. file: {path}', array( 'template_id' => $template_id, 'path' => $form_file ) );
313  return false;
314  }
315  }
316 
317  // Load xml parser (from GravityForms)
318  if( class_exists( 'GFCommon' ) ) {
319  $xml_parser = GFCommon::get_base_path() . '/xml.php';
320  } else {
321  $xml_parser = trailingslashit( WP_PLUGIN_DIR ) . 'gravityforms/xml.php';
322  }
323 
324  if( file_exists( $xml_parser ) ) {
325  require_once( $xml_parser );
326  } else {
327  gravityview()->log->debug( ' - Gravity Forms XML Parser not found {path}.', array( 'path' => $xml_parser ) );
328  return false;
329  }
330 
331  // load file
332  $xmlstr = file_get_contents( $form_file );
333 
334  $options = array(
335  "page" => array("unserialize_as_array" => true),
336  "form"=> array("unserialize_as_array" => true),
337  "field"=> array("unserialize_as_array" => true),
338  "rule"=> array("unserialize_as_array" => true),
339  "choice"=> array("unserialize_as_array" => true),
340  "input"=> array("unserialize_as_array" => true),
341  "routing_item"=> array("unserialize_as_array" => true),
342  "creditCard"=> array("unserialize_as_array" => true),
343  "routin"=> array("unserialize_as_array" => true),
344  "confirmation" => array("unserialize_as_array" => true),
345  "notification" => array("unserialize_as_array" => true)
346  );
347 
348  $xml = new RGXML($options);
349  $forms = $xml->unserialize($xmlstr);
350 
351  if( !$forms ) {
352  gravityview()->log->error( 'Importing Form Fields for preset [{template_id}]. Error importing file. (File) {path}', array( 'template_id' => $template_id, 'path' => $form_file ) );
353  return false;
354  }
355 
356  if( !empty( $forms[0] ) && is_array( $forms[0] ) ) {
357  $form = $forms[0];
358  }
359 
360  if( empty( $form ) ) {
361  gravityview()->log->error( '$form not set.', array( 'data' => $forms ) );
362  return false;
363  }
364 
365  gravityview()->log->debug( '[pre_get_available_fields] Importing Form Fields for preset [{template_id}]. (Form)', array( 'template_id' => $template_id, 'data' => $form ) );
366 
367  return $form;
368 
369  }
370 
371 
372  /**
373  * Import fields configuration from an exported WordPress View preset
374  * @param string $file path to file
375  * @return array Fields config array (unserialized)
376  */
377  function import_fields( $file ) {
378 
379  if( empty( $file ) || !file_exists( $file ) ) {
380  gravityview()->log->error( 'Importing Preset Fields. File not found. (File) {path}', array( 'path' => $file ) );
381  return false;
382  }
383 
384  if( !class_exists('WXR_Parser') ) {
385  include_once GRAVITYVIEW_DIR . 'includes/lib/xml-parsers/parsers.php';
386  }
387 
388  $parser = new WXR_Parser();
389  $presets = $parser->parse( $file );
390 
391  if(is_wp_error( $presets )) {
392  gravityview()->log->error( 'Importing Preset Fields failed. Threw WP_Error.', array( 'data' => $presets ) );
393  return false;
394  }
395 
396  if( empty( $presets['posts'][0]['postmeta'] ) && !is_array( $presets['posts'][0]['postmeta'] ) ) {
397  gravityview()->log->error( 'Importing Preset Fields failed. Meta not found in file. {path}', array( 'path' => $file ) );
398  return false;
399  }
400 
401  gravityview()->log->debug( '[import_fields] postmeta', array( 'data' => $presets['posts'][0]['postmeta'] ) );
402 
403  $fields = $widgets = array();
404  foreach( $presets['posts'][0]['postmeta'] as $meta ) {
405  switch ($meta['key']) {
406  case '_gravityview_directory_fields':
407  $fields = maybe_unserialize( $meta['value'] );
408  break;
409  case '_gravityview_directory_widgets':
410  $widgets = maybe_unserialize( $meta['value'] );
411  break;
412  }
413  }
414 
415  gravityview()->log->debug( '[import_fields] Imported Preset (Fields)', array( 'data' => $fields ) );
416  gravityview()->log->debug( '[import_fields] Imported Preset (Widgets)', array( 'data' => $widgets ) );
417 
418  return array(
419  'fields' => $fields,
420  'widgets' => $widgets
421  );
422  }
423 }
424 
const GRAVITYVIEW_DIR
"GRAVITYVIEW_DIR" "./" The absolute path to the plugin directory, with trailing slash ...
Definition: gravityview.php:40
import_form( $xml_or_json_path='')
Import Gravity Form XML or JSON.
Definition: class-ajax.php:207
$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:377
_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:174
static get_default_widget_areas()
Default widget areas.
gravityview()
Definition: _stubs.php:26
new GravityView_Ajax
Definition: class-ajax.php:425
get_sortable_fields()
Given a View id, calculates the assigned form, and returns the form fields (only the sortable ones ) ...
Definition: class-ajax.php:274
get_field_options()
Returns field options - called by ajax when dropping fields into active areas AJAX callback...
Definition: class-ajax.php:240
static pre_get_form_fields( $template_id='')
Get the the form fields for a preset (no form created yet)
Definition: class-ajax.php:304
get_available_fields_html()
Returns available fields given a form ID or a preset template ID AJAX callback.
Definition: class-ajax.php:65
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
get_active_areas()
Returns template active areas given a template ID AJAX callback.
Definition: class-ajax.php:96
get_preset_fields_config()
Fill in active areas with preset configuration according to the template selected.
Definition: class-ajax.php:120