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>
188 lines
4.2 KiB
PHP
188 lines
4.2 KiB
PHP
<?php
|
|
/**
|
|
* Theme management admin page.
|
|
*
|
|
* @package BreznFlow
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
namespace BreznFlow\Admin;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
use BreznFlow\Features\ThemeImporter;
|
|
use BreznFlow\Features\ThemeRegistry;
|
|
|
|
/**
|
|
* Handles theme import, deletion, and the themes admin page rendering.
|
|
*
|
|
* @since 1.0.0
|
|
*/
|
|
class ThemesPage {
|
|
|
|
/**
|
|
* Registers admin_init hooks for import and delete handling.
|
|
*
|
|
* @since 1.0.0
|
|
* @return void
|
|
*/
|
|
public function register(): void {
|
|
add_action( 'admin_init', array( $this, 'handle_import' ) );
|
|
add_action( 'admin_init', array( $this, 'handle_delete' ) );
|
|
}
|
|
|
|
/**
|
|
* Processes the theme import form submission.
|
|
* Runs early in admin_init so wp_safe_redirect() works before any output.
|
|
*/
|
|
public function handle_import(): void {
|
|
if ( ! isset( $_GET['page'] ) || 'breznflow-themes' !== $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
return;
|
|
}
|
|
|
|
if ( empty( $_POST['_wpnonce'] ) || empty( $_FILES['breznflow_theme_file'] ) ) {
|
|
return;
|
|
}
|
|
|
|
check_admin_referer( 'breznflow_theme_import' );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Insufficient permissions.', 'breznflow' ) );
|
|
}
|
|
|
|
$file = $_FILES['breznflow_theme_file']; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
|
|
|
// Verify file extension.
|
|
$filename = isset( $file['name'] ) ? sanitize_file_name( $file['name'] ) : '';
|
|
if ( ! str_ends_with( $filename, '.breznflow.json' ) && ! str_ends_with( $filename, '.json' ) ) {
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'error' => 'invalid_file',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
if ( ! isset( $file['tmp_name'] ) || ! is_uploaded_file( $file['tmp_name'] ) ) {
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'error' => 'upload_failed',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
|
$raw = file_get_contents( $file['tmp_name'] );
|
|
if ( false === $raw ) {
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'error' => 'read_failed',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
$data = json_decode( $raw, true );
|
|
if ( ! is_array( $data ) ) {
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'error' => 'invalid_json',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
$result = ThemeImporter::import( $data );
|
|
|
|
if ( is_wp_error( $result ) ) {
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'error' => 'validation',
|
|
'message' => rawurlencode( $result->get_error_message() ),
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'imported' => '1',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Processes a theme delete action.
|
|
*/
|
|
public function handle_delete(): void {
|
|
if ( ! isset( $_GET['page'] ) || 'breznflow-themes' !== $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
return;
|
|
}
|
|
|
|
if ( empty( $_GET['action'] ) || 'delete_theme' !== $_GET['action'] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
return;
|
|
}
|
|
|
|
$id = isset( $_GET['theme_id'] ) ? sanitize_key( $_GET['theme_id'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
|
|
if ( '' === $id ) {
|
|
return;
|
|
}
|
|
|
|
check_admin_referer( 'breznflow_theme_delete_' . $id );
|
|
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
wp_die( esc_html__( 'Insufficient permissions.', 'breznflow' ) );
|
|
}
|
|
|
|
ThemeImporter::delete( $id );
|
|
|
|
wp_safe_redirect(
|
|
add_query_arg(
|
|
array(
|
|
'page' => 'breznflow-themes',
|
|
'deleted' => '1',
|
|
),
|
|
admin_url( 'admin.php' )
|
|
)
|
|
);
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Renders the themes management page.
|
|
*
|
|
* @since 1.0.0
|
|
* @return void
|
|
*/
|
|
public function render(): void {
|
|
require BREZNFLOW_DIR . 'includes/Admin/views/themes.php';
|
|
}
|
|
}
|