0 ) : ?>
gmdate( 'Y-m-d H:i:s' ),
'action' => $action,
'detail' => $detail,
]
);
$log = array_slice( $log, 0, 50 );
update_option( self::LOG_OPTION, $log, false );
}
/**
* Guard capability for admin-post handlers.
*/
private function assert_capability() {
if ( ! current_user_can( Admin::CAPABILITY ) ) {
wp_die( esc_html__( 'Permission denied.', 'phemightforms' ) );
}
}
/**
* Export all forms as ZIP (or single JSON fallback).
*/
public function export_forms() {
$this->assert_capability();
check_admin_referer( 'phemightforms_backup_export_forms' );
$posts = Form::all();
$items = [];
foreach ( $posts as $post ) {
$form = new Form( $post->ID );
if ( method_exists( $form, 'export_json' ) ) {
$decoded = json_decode( $form->export_json(), true );
if ( is_array( $decoded ) ) {
$items[] = $decoded;
}
} else {
$items[] = [
'title' => $form->title,
'config' => $form->config,
];
}
}
self::log( 'export_forms', sprintf( '%d forms', count( $items ) ) );
$payload = wp_json_encode( $items, JSON_PRETTY_PRINT );
$stamp = gmdate( 'Y-m-d' );
nocache_headers();
if ( class_exists( 'ZipArchive' ) ) {
$tmp = wp_tempnam( 'phf-backup' );
$zip = new \ZipArchive();
if ( true === $zip->open( $tmp, \ZipArchive::OVERWRITE ) ) {
$zip->addFromString( 'phemightforms-forms.json', $payload );
$zip->close();
header( 'Content-Type: application/zip' );
header( 'Content-Disposition: attachment; filename="phemightforms-forms-' . $stamp . '.zip"' );
header( 'Content-Length: ' . filesize( $tmp ) );
readfile( $tmp ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile
unlink( $tmp ); // phpcs:ignore WordPress.WP.AlternativeFunctions.unlink_unlink
exit;
}
}
header( 'Content-Type: application/json; charset=utf-8' );
header( 'Content-Disposition: attachment; filename="phemightforms-forms-' . $stamp . '.json"' );
echo $payload; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
exit;
}
/**
* Redirect to the shared CSV export for a form.
*/
public function export_entries() {
$this->assert_capability();
check_admin_referer( 'phemightforms_backup_export_entries' );
$form_id = isset( $_POST['form_id'] ) ? absint( $_POST['form_id'] ) : 0;
if ( ! $form_id ) {
wp_die( esc_html__( 'Select a form.', 'phemightforms' ) );
}
$form = new Form( $form_id );
self::log( 'export_entries', $form->exists() ? $form->title : (string) $form_id );
wp_safe_redirect( Export::export_url( $form_id ) );
exit;
}
/**
* Import forms from uploaded JSON.
*/
public function import_forms() {
$this->assert_capability();
check_admin_referer( 'phemightforms_backup_import' );
$redirect = add_query_arg( [ 'page' => Admin::SLUG . '-backup' ], admin_url( 'admin.php' ) );
if ( empty( $_FILES['backup_file']['tmp_name'] ) ) {
wp_safe_redirect( add_query_arg( 'backup_error', rawurlencode( __( 'No file uploaded.', 'phemightforms' ) ), $redirect ) );
exit;
}
$raw = file_get_contents( $_FILES['backup_file']['tmp_name'] ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
$data = json_decode( $raw, true );
if ( ! is_array( $data ) ) {
wp_safe_redirect( add_query_arg( 'backup_error', rawurlencode( __( 'Invalid JSON file.', 'phemightforms' ) ), $redirect ) );
exit;
}
// Single form object vs list.
$forms = isset( $data['config'] ) ? [ $data ] : $data;
$count = 0;
foreach ( $forms as $item ) {
if ( ! is_array( $item ) || empty( $item['config'] ) || ! is_array( $item['config'] ) ) {
continue;
}
$title = isset( $item['title'] ) ? sanitize_text_field( $item['title'] ) : __( 'Imported Form', 'phemightforms' );
$config = $item['config'];
if ( Form::save( $title, $config, 0 ) ) {
++$count;
}
}
self::log( 'import_forms', sprintf( '%d forms', $count ) );
wp_safe_redirect( add_query_arg( 'imported', $count, $redirect ) );
exit;
}
}