<?php
/* Register PDFs in Gravity Flow Generic Map */
add_filter( 'gravityflow_step_settings_fields', function ( $settings, $step_id ) {
$gflow = \Gravity_Flow::get_instance();
if ( $step_id ) {
$step = $gflow->get_step( $step_id );
$step_type = $step !== false ? $step->get_type() : '';
} else {
$step_type = $gflow->get_setting( 'step_type' );
}
/* skip unsupported steps */
if ( ! in_array( $step_type, [ 'new_entry', 'update_entry' ], true ) ) {
return $settings;
}
/* skip forms without PDFs configured */
$form_id = absint( rgget( 'id' ) );
$pdfs = \GPDFAPI::get_form_pdfs( $form_id );
if ( is_wp_error( $pdfs ) || empty( $pdfs ) ) {
return $settings;
}
$mapping_key = 'value_field';
foreach ( $settings as $i => $setting_group ) {
if (
empty( $setting_group['class'] ) ||
empty( $setting_group['fields'] ) ||
$setting_group['class'] !== 'gravityflow-step-settings'
) {
continue;
}
foreach ( $setting_group['fields'] as $j => $field ) {
// only target the generic map field
if ( empty( $field['name'] ) || $field['name'] !== 'mappings' ) {
continue;
}
// verify expected data structure
if ( ! isset( $field[ $mapping_key ]['choices'] ) || ! is_array( $field[ $mapping_key ]['choices'] ) ) {
continue;
}
// add PDFs to list
foreach ( $pdfs as $pdf ) {
/* Ignore inactive pdf template. */
if ( ( $pdf['active'] ?? false ) === false ) {
continue;
}
$field[ $mapping_key ]['choices'][] = [
'label' => __( 'PDF: ' ) . $pdf['name'] ?? '',
'value' => sprintf(
'gpdf:%s',
$pdf['id'] ?? '',
),
];
}
$settings[ $i ]['fields'][ $j ] = $field;
break;
}
}
return $settings;
}, 10, 2 );
/**
* Generates a PDF and saves it in a File Upload field
*
* @param array $target_entry
* @param array $target_form
* @param array $entry
* @param array $form
*
* @param \Gravity_Flow_Step $step
*
* @return array
*/
$gravityflow_form_connector_save_pdf_to_fileupload = function ( $target_entry, $target_form, $entry, $form, $mappings, $server_type ) {
foreach ( $mappings as $mapping ) {
if ( strpos( $mapping['value'], 'gpdf:' ) !== 0 ) {
continue;
}
/* Get the target info */
$target_field_id = trim( $mapping['key'] ) === 'gf_custom' ? trim( $mapping['custom_key'] ) : trim( $mapping['key'] );
$target_field = \GFAPI::get_field( $target_form, $target_field_id );
/* Verify target is a file upload field */
if ( $target_field === false || $target_field->get_input_type() !== 'fileupload' ) {
gravity_flow()->log_error( __METHOD__ . '(): target is not a File Upload field for: ' . $mapping['value'] );
continue;
}
/* Generate the PDF */
$pdf_id = explode( ':', $mapping['value'] )[1] ?? '';
$pdf_path = \GPDFAPI::create_pdf( $entry['id'] ?? 0, $pdf_id );
if ( is_wp_error( $pdf_path ) ) {
gravity_flow()->log_error( sprintf( __METHOD__ . '(): could not generate PDF for entry ID%d and PDF ID %s.', $entry['id'] ?? 0, $mapping['value'] ) );
continue;
}
/*
* Move the PDF to the upload directory
* If the target is the local site then we'll save to the target upload folder
* If the target is remove then we'll save to the source upload folder
*/
$upload_root_info = \GF_Field_FileUpload::get_upload_root_info( $server_type === 'remote' ? $form['id'] : $target_form['id'] );
/* Create the directory if it doesn't exist */
wp_mkdir_p( $upload_root_info['path'] );
$file_name = wp_basename( $pdf_path, '.pdf' );
$extension = '.pdf';
/* Get unique target info */
$counter = 1;
$target_filename = $file_name . $extension;
$target_path = $upload_root_info['path'] . $target_filename;
while ( is_file( $target_path ) ) {
$target_filename = $file_name . $counter . $extension;
$target_path = $upload_root_info['path'] . $target_filename;
$counter++;
}
/* Verify there's been no path traversal */
$path_to_test = realpath( dirname( $target_path ) );
if ( $path_to_test === false || strpos( $path_to_test, realpath( $upload_root_info['path'] ) ) !== 0 ) {
gravity_flow()->log_error( __METHOD__ . '(): Path traversal detected in target path: ' . $target_path );
continue;
}
/* Move PDF to target form upload directory */
if ( copy( $pdf_path, $target_path ) ) {
\GFFormsModel::set_permissions( $target_path );
/* prepare info for DB storage */
$target_url = $upload_root_info['url'] . $target_filename;
if ( ! $target_field->multipleFiles ) {
$target_entry[ $target_field_id ] = $target_url;
} else {
$value = ! empty( $target_entry[ $target_field_id ] ) ? json_decode( $target_entry[ $target_field_id ], true ) : [];
$value[] = $target_url;
$target_entry[ $target_field_id ] = json_encode( $value );
}
}
}
return $target_entry;
};
add_filter( 'gravityflowformconnector_new_entry', function ( $new_entry, $entry, $form, $target_form, $step ) use ( $gravityflow_form_connector_save_pdf_to_fileupload ) {
return $gravityflow_form_connector_save_pdf_to_fileupload(
$new_entry,
$target_form,
$entry,
$form,
$step->mappings,
$step->server_type
);
}, 10, 5 );
add_filter( 'gravityflowformconnector_update_entry', function ( $new_entry, $entry, $form, $target_form, $step ) use ( $gravityflow_form_connector_save_pdf_to_fileupload ) {
return $gravityflow_form_connector_save_pdf_to_fileupload(
$new_entry,
$target_form,
$entry,
$form,
$step->mappings,
$step->server_type
);
}, 10, 5 );
TODO