breznflow/includes/DownloadHandler.php
Michael fd83e4810b BreznFlow 1.0.0 — WordPress.org submission
Initial public release of BreznFlow, an n8n workflow renderer for WordPress.
Fully PHPCS-compliant (WordPress Coding Standards), security-hardened,
and ready for WordPress.org plugin review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:27:36 +00:00

84 lines
2.2 KiB
PHP

<?php
/**
* Handles workflow JSON file downloads.
*
* @package BreznFlow
* @since 1.0.0
*/
namespace BreznFlow;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Serves sanitized workflow JSON as a downloadable file when the
* breznflow_download query parameter is present.
*
* @since 1.0.0
*/
class DownloadHandler {
/**
* Registers the template_redirect hook for download handling.
*
* @since 1.0.0
* @return void
*/
public function register(): void {
add_action( 'template_redirect', array( $this, 'handle_download' ) );
}
/**
* Processes the download request and serves the JSON file.
*
* @since 1.0.0
* @return void
*/
public function handle_download(): void {
if ( ! isset( $_GET['breznflow_download'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return;
}
$post_id = (int) $_GET['breznflow_download']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
if ( $post_id <= 0 ) {
status_header( 400 );
exit;
}
$post = get_post( $post_id );
if ( ! $post || 'breznflow_workflow' !== $post->post_type || 'publish' !== $post->post_status ) {
status_header( 404 );
exit;
}
// Check if download is allowed.
$meta_download = (bool) get_post_meta( $post_id, '_breznflow_show_download', true );
$global_settings = get_option( 'breznflow_settings', array() );
$global_download = ! empty( $global_settings['allow_download'] );
if ( ! $meta_download || ! $global_download ) {
status_header( 403 );
exit;
}
// Read the already-sanitized JSON (NEVER raw).
$json = get_post_meta( $post_id, '_breznflow_raw_json', true );
if ( ! $json ) {
status_header( 404 );
exit;
}
$filename = 'workflow-' . $post_id . '.json';
header( 'Content-Type: application/json; charset=utf-8' );
header( 'Content-Disposition: attachment; filename="' . rawurlencode( $filename ) . '"' );
header( 'X-Content-Type-Options: nosniff' );
header( 'Cache-Control: no-store, no-cache, must-revalidate' );
header( 'Content-Length: ' . strlen( $json ) );
echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- JSON output for download, not HTML
exit;
}
}