-
Notifications
You must be signed in to change notification settings - Fork 19
Open
Labels
Description
TODO
- If updating an entry, grab the existing Multi File Upload entry data so the newly-generated PDF can be added to the existing list of files.
- Add support for the Update Fields step. This acts in reverse to the other steps, in that the data is pulled from another entry and saved to fields in the current one (rather than pushing to another entry)
- Test a Remote server
<?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 );