GravityView  2.17
The best, easiest way to display Gravity Forms entries on your website.
class-gravityview-field-fileupload.php
Go to the documentation of this file.
1 <?php
2 /**
3  * @file class-gravityview-field-fileupload.php
4  * @package GravityView
5  * @subpackage includes\fields
6  */
7 
9 
10  var $name = 'fileupload';
11 
12  var $_gf_field_class_name = 'GF_Field_FileUpload';
13 
14  var $is_searchable = true;
15 
16  var $search_operators = array( 'contains' );
17 
18  var $group = 'advanced';
19 
20  var $icon = 'dashicons-upload';
21 
22  public function __construct() {
23  $this->label = esc_html__( 'File Upload', 'gk-gravityview' );
24  parent::__construct();
25  }
26 
27  public function field_options( $field_options, $template_id, $field_id, $context, $input_type, $form_id ) {
28 
29  unset( $field_options['search_filter'] );
30 
31  if( 'edit' === $context ) {
32  return $field_options;
33  }
34 
35  $add_options['link_to_file'] = array(
36  'type' => 'checkbox',
37  'label' => __( 'Display as a Link:', 'gk-gravityview' ),
38  'desc' => __('Display the uploaded files as links, rather than embedded content.', 'gk-gravityview'),
39  'value' => false,
40  'merge_tags' => false,
41  );
42 
43  $add_options['image_width'] = array(
44  'type' => 'text',
45  'label' => __( 'Custom Width:', 'gk-gravityview' ),
46  'desc' => __( 'Override the default image width (250).', 'gk-gravityview' ),
47  'value' => '250',
48  'merge_tags' => false,
49  );
50 
51  $field = \GV\GF_Field::by_id( \GV\GF_Form::by_id( $form_id), $field_id );
52 
53  // Only allow alt text on single files currently.
54  if( empty( $field->field->multipleFiles ) ) {
55 
56  $add_options['alt_text'] = array(
57  'type' => 'text',
58  'label' => __( 'Alternative text', 'gk-gravityview' ),
59  'desc' => __( 'Define an alternative text description of a file. For supported file types only. By default, the field label is used.', 'gk-gravityview' ),
60  'value' => false,
61  'merge_tags' => 'force',
62  'group' => 'advanced',
63  );
64 
65  }
66 
67  return $add_options + $field_options;
68  }
69 
70  /**
71  * Trick the GF fileupload field to render with the proper HTML ID to enable the plupload JS to work properly
72  *
73  * @param array $form The Form Object currently being processed.
74  * @param string|array $value The field value. From default/dynamic population, $_POST, or a resumed incomplete submission.
75  * @param null|array $entry Null or the Entry Object currently being edited.
76  * @param GF_Field_FileUpload $field Gravity Forms field
77  *
78  * @return string
79  */
81 
82  $field->_is_entry_detail = true;
83 
84  $return = $field->get_field_input( $form, $field_value, $entry );
85 
86  return $return;
87  }
88 
89  /**
90  * Replaces insecure file paths with secure file paths for WordPress media shortcode output
91  *
92  * The WordPress media shortcodes need to be passed insecure file paths so WordPress can parse the extension]
93  * that is being rendered and properly generate the code. Once that shortcode is rendered, we then replace the
94  * insecure file paths with the secure file paths used by Gravity Forms.
95  *
96  * @since 2.10.3
97  *
98  * @param string $rendered The output of the WordPress audio/video shortcodes.
99  * @param string $insecure_file_path Insecure path to the file, showing the directory structure.
100  * @param string $secure_file_path Secure file path using Gravity Forms rewrites.
101  *
102  * @return string HTML output with insecure file paths converted to secure.
103  */
104  static private function replace_insecure_wp_shortcode_output( $rendered = '', $insecure_file_path = '', $secure_file_path = '' ) {
105 
106  // The shortcode adds instance URL args: add_query_arg( '_', $instance, $atts[ $fallback ] )
107  // these break the path, since we already have "?" in the URL
108  $rendered = str_replace( '?_=', '&_=', $rendered );
109 
110  $rendered = str_replace( esc_attr( $insecure_file_path ), esc_attr( $secure_file_path ), $rendered );
111  $rendered = str_replace( esc_html( $insecure_file_path ), esc_html( $secure_file_path ), $rendered );
112  $rendered = str_replace( esc_url( $insecure_file_path ), esc_url( $secure_file_path ), $rendered );
113  $rendered = str_replace( trim( $insecure_file_path ), trim( $secure_file_path ), $rendered );
114 
115  return $rendered;
116  }
117 
118  /**
119  * Return an array of files prepared for output.
120  *
121  * Processes files by file type and generates unique output for each. Returns array for each file, with the following keys:
122  * - `file_path` => The file path of the file, with a line break
123  * - `html` => The file output HTML formatted
124  *
125  * @since 1.2
126  * @todo Support `playlist` shortcode for playlist of video/audio
127  * @param string $value Field value passed by Gravity Forms. String of file URL, or serialized string of file URL array
128  * @param string $gv_class Field class to add to the output HTML
129  *
130  * @since 2.0
131  * @param \GV\Template_Context The context.
132  *
133  * @return array Array of file output, with `file_path` and `html` keys (see comments above)
134  */
135  static function get_files_array( $value, $gv_class, $context = null ) {
136 
137  if ( $context instanceof \GV\Template_Context ) {
138  $field = $context->field->field;
139  $field_settings = $context->field->as_configuration();
140  $entry = $context->entry->as_entry();
141  $field_value = $context->value;
142  global $post;
143  $base_id = $post ? $post->ID : $context->view->ID;
144 
145  $is_single = $context->request->is_entry();
146  $lightbox = $context->view->settings->get( 'lightbox', false );
147 
148  /** A compatibility array that's required by some of the deprecated filters. */
149  $field_compat = array(
150  'form' => (isset($context->source->form) ? $context->source->form : ''),
151  'field_id' => $context->field->ID,
152  'field' => $field,
153  'field_settings' => $field_settings,
154  'value' => $field_value,
155  'display_value' => $context->display_value,
156  'format' => 'html',
157  'entry' => $entry,
158  'field_type' => $context->field->type,
159  'field_path' => (isset($context->template->located_template) ? $context->template->located_template : ''),
160  );
161  } else {
162 
163  _doing_it_wrong( __METHOD__, '2.0', 'Please pass a \GV\Template_Context object as the 3rd parameter' );
164 
166  /** @deprecated path */
167  $gv_field_array = $gravityview_view->getCurrentField();
168 
169  /** @type GF_Field_FileUpload $field */
170  $field = \GV\Utils::get( $gv_field_array, 'field' );
171  $field_settings = \GV\Utils::get( $gv_field_array, 'field_settings' );
172  $entry = \GV\Utils::get( $gv_field_array, 'entry' );
173  $field_value = \GV\Utils::get( $gv_field_array, 'value' );
174  $base_id = null;
175 
176  $is_single = gravityview_get_context() === 'single';
177  $lightbox = ! empty( $gravityview_view->atts['lightbox'] );
178  $field_compat = $gravityview_view->getCurrentField();
179  }
180 
181  $output_arr = array();
182 
183  // Get an array of file paths for the field.
184  $file_paths = (int) \GV\Utils::get( $field, 'multipleFiles' ) !== 1 ? array( $value ) : $value;
185 
186  // The $value JSON was probably truncated; let's check lead_detail_long.
187  if ( ! is_array( $file_paths ) ) {
188  $full_value = RGFormsModel::get_lead_field_value( $entry, $field );
189  $file_paths = json_decode( $full_value );
190  }
191 
192  if ( ! is_array( $file_paths ) ) {
193  gravityview()->log->error( 'Field does not have a valid image array. JSON decode may have failed.', array( 'data' => array( '$value' => $value, '$field_value' => $field_value ) ) );
194  return $output_arr;
195  }
196 
197  $field_settings_backup = $field_settings;
198  // Process each file path
199  foreach ( $file_paths as $index => $file_path ) {
200 
201  $rendered = null;
202 
203  $file_info = self::get_file_info( $file_path, $field, $field_settings, $context, $index );
204 
205  $file_path = $file_info['file_path'];
206  $basename = $file_info['basename'];
207  $extension = $file_info['extension'];
208  $insecure_file_path = $file_info['insecure_file_path'];
209  $secure_file_path = $file_info['secure_file_path'];
210  $is_secure = $file_info['is_secure'];
211 
212  $disable_lightbox = false;
213  $text = $basename;
214 
215  $alt = \GV\Utils::get( $field_settings, 'alt_text' );
216  $alt = ( '' === $alt ) ? $field_settings['label'] : $alt;
217  $alt = GFCommon::replace_variables( $alt, GFAPI::get_form( $entry['form_id'] ), $entry );
218 
219  // Audio
220  if ( in_array( $extension, wp_get_audio_extensions() ) ) {
221  if ( shortcode_exists( 'audio' ) ) {
222 
223  /**
224  * @filter `gravityview_audio_settings` Modify the settings passed to the `wp_video_shortcode()` function
225  * @since 1.2
226  * @param array $audio_settings Array with `src` and `class` keys
227  * @since 2.0
228  * @param \GV\Template_Context $context The context.
229  */
230  $audio_settings = apply_filters( 'gravityview_audio_settings', array(
231  'src' => $insecure_file_path, // Needs to be insecure path so WP can parse extension
232  'class' => 'wp-audio-shortcode gv-audio gv-field-id-'.$field_settings['id']
233  ), $context );
234 
235  /**
236  * Generate the audio shortcode
237  * @see http://codex.wordpress.org/Audio_Shortcode
238  * @see https://developer.wordpress.org/reference/functions/wp_audio_shortcode/
239  */
240  $rendered = wp_audio_shortcode( $audio_settings );
241 
242  if ( $is_secure ) {
243  $rendered = self::replace_insecure_wp_shortcode_output( $rendered, $insecure_file_path, $secure_file_path );
244  }
245  }
246 
247  // Video
248  } else if ( in_array( $extension, wp_get_video_extensions() ) ) {
249 
250  if ( shortcode_exists( 'video' ) ) {
251 
252  /**
253  * @filter `gravityview_video_settings` Modify the settings passed to the `wp_video_shortcode()` function
254  * @since 1.2
255  * @param array $video_settings Array with `src` and `class` keys
256  * @since 2.0
257  * @param \GV\Template_Context $context The context.
258  */
259  $video_settings = apply_filters( 'gravityview_video_settings', array(
260  'src' => $insecure_file_path, // Needs to be insecure path so WP can parse extension
261  'class' => 'wp-video-shortcode gv-video gv-field-id-'.$field_settings['id']
262  ), $context );
263 
264  /**
265  * Generate the video shortcode
266  * @see http://codex.wordpress.org/Video_Shortcode
267  * @see https://developer.wordpress.org/reference/functions/wp_video_shortcode/
268  */
269  $rendered = wp_video_shortcode( $video_settings );
270 
271  if ( $is_secure ) {
272  $rendered = self::replace_insecure_wp_shortcode_output( $rendered, $insecure_file_path, $secure_file_path );
273  }
274  }
275 
276  // PDF or Text
277  } else if ( in_array( $extension, array( 'pdf', 'txt' ), true ) ) {
278 
279  // Don't add query arg when exporting as CSV
280  if ( $context instanceof \GV\Template_Context && ! ( $context->template instanceof \GV\Field_CSV_Template ) ) {
281  // File needs to be displayed in an IFRAME
282  $file_path = add_query_arg( array( 'gv-iframe' => 'true' ), $file_path );
283  }
284 
285  $field_settings['link_to_file'] = true;
286 
287  // Images
288  } else if ( in_array( $extension, GravityView_Image::get_image_extensions() ) ) {
289  $width = \GV\Utils::get( $field_settings, 'image_width', 250 );
290 
291  $image_atts = array(
292  'src' => $file_path,
293  'class' => 'gv-image gv-field-id-' . $field_settings['id'],
294  'alt' => $alt,
295  'width' => ( $is_single ? null : ( $width ? $width: 250 ) )
296  );
297 
298  if ( $is_secure ) {
299  $image_atts['validate_src'] = false;
300  }
301 
302  /**
303  * Modify the default image attributes for uploaded images
304  *
305  * @since 2.0
306  * @see GravityView_Image For the available attributes
307  *
308  * @param array $image_atts
309  */
310  $image_atts = apply_filters( 'gravityview/fields/fileupload/image_atts', $image_atts );
311 
313 
314  $gv_entry = \GV\GF_Entry::from_entry( $entry );
315 
316  $entry_slug = $gv_entry->get_slug();
317 
318  unset( $gv_entry );
319 
320  if ( $lightbox && empty( $field_settings['show_as_link'] ) ) {
321 
322  $lightbox_link_atts = array(
323  'rel' => sprintf( "%s-%s", $gv_class, $entry_slug ),
324  'class' => '',
325  );
326 
327  $lightbox_link_atts = apply_filters( 'gravityview/fields/fileupload/link_atts', $lightbox_link_atts, $field_compat, $context );
328 
329  $rendered = gravityview_get_link( $file_path, $image->html(), $lightbox_link_atts );
330  } else {
331  $rendered = $image->html();
332  }
333 
334  // Show as link should render the image regardless.
335  if ( ! empty( $field_settings['show_as_link'] ) ) {
336  $text = $rendered;
337  }
338  }
339  // For all other non-media file types (ZIP, for example), always show as a link regardless of setting.
340  else {
341  $field_settings['link_to_file'] = true;
342  $disable_lightbox = true;
343  }
344 
345  /**
346  * @filter `gravityview/fields/fileupload/disable_link` Filter to alter the default behaviour of wrapping images (or image names) with a link to the content object
347  * @since 1.5.1
348  * @param bool $disable_wrapped_link whether to wrap the content with a link to the content object.
349  * @param array $field_compat Current GravityView field array
350  * @see GravityView_API:field_value() for info about $gravityview_view->field_data
351  * @since 2.0
352  * @param \GV\Template_Context $context The context.
353  */
354  $disable_wrapped_link = apply_filters( 'gravityview/fields/fileupload/disable_link', false, $field_compat, $context );
355 
356  // Output textualized content where
357  if ( ! $disable_wrapped_link && ( ! empty( $field_settings['link_to_file'] ) || ! empty( $field_settings['show_as_link'] ) ) ) {
358  /**
359  * Modify the link text (defaults to the file name)
360  *
361  * @since 1.7
362  *
363  * @param string $content The existing anchor content. Could be `<img>` tag, audio/video embed or the file name
364  * @param array $field_compat Current GravityView field array
365  * @since 2.0
366  * @param \GV\Template_Context $context The context.
367  */
368  $content = apply_filters( 'gravityview/fields/fileupload/link_content', $text, $field_compat, $context );
369 
370  if ( empty( $field_settings['show_as_link'] ) ) {
371  /**
372  * @filter `gravityview/fields/fileupload/link_atts` Modify the link attributes for a file upload field
373  * @since 2.0 Added $context
374  * @since 2.11 Added $additional_details
375  * @param array|string $link_atts Array or attributes string
376  * @param array $field_compat Current GravityView field array
377  * @param \GV\Template_Context $context The context.
378  * @param array $additional_details Array of additional details about the file. {
379  * @type string $file_path URL to file.
380  * @type string $insecure_file_path URL to insecure file.
381  * }
382  */
383  $link_atts = apply_filters( 'gravityview/fields/fileupload/link_atts', array( 'target' => '_blank' ), $field_compat, $context, compact( 'file_path', 'insecure_file_path', 'disable_lightbox' ) );
384 
386  }
387  } else {
388  $content = empty( $rendered ) ? $text : $rendered;
389  }
390 
391  $output_arr[] = array(
392  'file_path' => $file_path,
393  'content' => $content
394  );
395 
396  $field_settings = $field_settings_backup; // reset to default
397  } // End foreach loop
398 
399  /**
400  * @filter `gravityview/fields/fileupload/files_array` Modify the files array
401  * @since 1.7
402  * @since 2.0 Added $context
403  * @param array $output_arr Associative array of files. {
404  * @type string $file_path The path to the file as stored in Gravity Forms.
405  * @type string $content The generated output for the file.
406  * }
407  * @param array $field_compat Current GravityView field array.
408  * @param \GV\Template_Context $context The context.
409  */
410  $output_arr = apply_filters( 'gravityview/fields/fileupload/files_array', $output_arr, $field_compat, $context );
411 
412  return $output_arr;
413  }
414 
415  /**
416  * Prepares information about the file.
417  *
418  * @since 2.16
419  *
420  * @param string $file_path The file path as returned from Gravity Forms.
421  * @param GF_Field_FileUpload $field The file upload field.
422  * @param array $field_settings GravityView settings for the field {@see \GV\Field::as_configuration()}
423  * @param \GV\Template_Context $context
424  * @param int $index The index of the current file in the array of files.
425  *
426  * @return array{file_path: string, insecure_file_path: string,secure_file_path: string,basename:string,extension:string,is_secure: bool}
427  */
428  private static function get_file_info( $file_path, $field, $field_settings, $context, $index ) {
429 
430  // If the site is HTTPS, use HTTPS
431  if ( function_exists( 'set_url_scheme' ) ) {
432  $file_path = set_url_scheme( $file_path );
433  }
434 
435  // This is from Gravity Forms's code
436  $file_path = esc_attr( str_replace( ' ', '%20', $file_path ) );
437 
438  // Get file path information
439  $file_path_info = pathinfo( $file_path );
440 
441  // If pathinfo() gave us the extension of the file, run the switch statement using that.
442  $extension = empty( $file_path_info['extension'] ) ? null : strtolower( $file_path_info['extension'] );
443 
444  /**
445  * @filter `gravityview/fields/fileupload/extension` Modify the file extension before it's used in display logic
446  * @since 2.13.5
447  *
448  * @param string $extension The extension of the file, as parsed by `pathinfo()`.
449  * @param string $file_path Path to the file uploaded by Gravity Forms.
450  */
451  $extension = apply_filters( 'gravityview/fields/fileupload/extension', $extension, $file_path );
452 
453  $basename = $file_path_info['basename'];
454 
455  // Get the secure download URL
456  $is_secure = false;
457  $insecure_file_path = $file_path;
458  $secure_file_path = $field->get_download_url( $file_path );
459 
460  if ( $secure_file_path !== $file_path ) {
461  $file_path = $secure_file_path;
462  $is_secure = true;
463  }
464 
465  /**
466  * @filter `gravityview/fields/fileupload/file_path` Modify the file path before generating a link to it
467  * @since 1.22.3
468  * @since 2.0 Added $context parameter
469  * @since 2.8.2
470  *
471  * @param string $file_path Path to the file uploaded by Gravity Forms
472  * @param array $field_settings Array of GravityView field settings
473  * @param \GV\Template_Context $context The context.
474  * @param int $index The current index of the $file_paths array being processed
475  */
476  $file_path = apply_filters( 'gravityview/fields/fileupload/file_path', $file_path, $field_settings, $context, $index );
477 
478  return array(
479  'file_path' => $file_path,
480  'insecure_file_path' => $insecure_file_path,
481  'secure_file_path' => $secure_file_path,
482  'basename' => $basename,
483  'extension' => $extension,
484  'is_secure' => $is_secure,
485  );
486  }
487 }
488 
Modify field settings by extending this class.
$image
Definition: post_image.php:98
Generic class for generating image tag.
static getInstance( $passed_post=NULL)
get_field_input( $form, $field_value, $entry, $field)
Trick the GF fileupload field to render with the proper HTML ID to enable the plupload JS to work pro...
$field_settings['content']
Definition: custom.php:27
gravityview_get_link( $href='', $anchor_text='', $atts=array())
Generate an HTML anchor tag with a list of supported attributes.
global $post
Definition: delete-entry.php:7
static from_entry( $entry)
Construct a instance from a Gravity Forms entry array.
$image_atts
Definition: post_image.php:92
static get_file_info( $file_path, $field, $field_settings, $context, $index)
Prepares information about the file.
if(gravityview() ->plugin->is_GF_25()) $form
static by_id( $form, $field_id)
Get a by and Field ID.
if(empty( $field_settings['content'])) $content
Definition: custom.php:37
static get_files_array( $value, $gv_class, $context=null)
Return an array of files prepared for output.
static replace_insecure_wp_shortcode_output( $rendered='', $insecure_file_path='', $secure_file_path='')
Replaces insecure file paths with secure file paths for WordPress media shortcode output...
field_options( $field_options, $template_id, $field_id, $context, $input_type, $form_id)
if(empty( $created_by)) $form_id
static get( $array, $key, $default=null)
Grab a value from an array or an object or default.
gravityview()
The main GravityView wrapper function.
gravityview_get_context()
Returns the current GravityView context, or empty string if not GravityView.
Definition: class-api.php:1330
$entry_slug
Definition: notes.php:30
$entry
Definition: notes.php:27
if(false !==strpos( $value, '00:00')) $field_id
string $field_id ID of the field being displayed
Definition: time.php:22
static get_image_extensions()
Returns an array of file extensions recognized by GravityView as images.
$field_value
Definition: checkbox.php:24