`
* name the renderer emits via
* `wp_nonce_field($action, $name)` and the handler reads
* from `$_POST`.
* - `FORM_FIELD_PREFIX` — the top-level `$_POST` key under
* which every settings field is namespaced
* (`affilun_settings[rendering][default_template]` etc.). The
* parser reads `$_POST[FORM_FIELD_PREFIX]` as the root of
* the form payload.
* - `FORM_ACTION` — the `admin-post.php?action=...` value
* that drives WordPress's `admin_post_{action}` action
* dispatch. The renderer emits it as the `` value; the {@see \Affilun\Presentation\Admin\AdminServiceProvider}
* subscribes the corresponding `admin_post_affilun_save_settings`
* hook.
*
* The {@see self::validateNonce()} helper exists so the POST
* handler ({@see SaveSettingsHandler}) can perform nonce
* verification through an injected closure rather than calling
* `wp_verify_nonce()` directly. That keeps the handler fully
* testable in pure-unit mode where WordPress is not loaded;
* the production wiring forwards to `wp_verify_nonce()`
* verbatim. Per §6.4 the nonce value itself is never logged.
*
* @package Affilun\Presentation\Admin\Page
*/
declare(strict_types=1);
namespace Affilun\Presentation\Admin\Page;
/**
* Static helper carrying the §13.10 save-form literals (nonce
* action / nonce field / form-field prefix / admin-post action).
*
* See the file-level docblock for how the §13 Settings admin
* page's renderer / parser / POST handler share these literals
* to round-trip a save request through `admin-post.php`.
*/
final class SettingsFormToken {
/**
* Action literal passed to `wp_create_nonce()` /
* `wp_verify_nonce()`.
*/
public const NONCE_ACTION = 'affilun_settings_save';
/**
* `` name the renderer emits via
* `wp_nonce_field()` and the handler reads from `$_POST`.
*/
public const NONCE_FIELD = '_affilun_settings_nonce';
/**
* Top-level `$_POST` key under which every settings field is
* namespaced.
*/
public const FORM_FIELD_PREFIX = 'affilun_settings';
/**
* `admin-post.php?action=...` value driving WordPress's
* `admin_post_{action}` dispatch.
*/
public const FORM_ACTION = 'affilun_save_settings';
/**
* Action literal passed to `wp_create_nonce()` / `wp_verify_nonce()`
* for the Amazon bulk resync button.
*/
public const AMAZON_RESYNC_NONCE_ACTION = 'affilun_amazon_resync';
/**
* Nonce field name for the Amazon bulk resync button.
*/
public const AMAZON_RESYNC_NONCE_FIELD = '_affilun_amazon_resync_nonce';
/**
* `admin-post.php?action=...` value for Amazon bulk resync.
*/
public const AMAZON_RESYNC_FORM_ACTION = 'affilun_resync_amazon_products';
/**
* Return the nonce action literal.
*/
public static function nonceAction(): string {
return self::NONCE_ACTION;
}
/**
* Return the nonce-field name literal.
*/
public static function nonceField(): string {
return self::NONCE_FIELD;
}
/**
* Return the form-field prefix literal.
*/
public static function formFieldPrefix(): string {
return self::FORM_FIELD_PREFIX;
}
/**
* Return the `admin-post.php` action literal.
*/
public static function formAction(): string {
return self::FORM_ACTION;
}
/**
* Validate a nonce value against {@see self::NONCE_ACTION}
* via the supplied verifier closure.
*
* The closure abstracts `wp_verify_nonce()` so tests can
* inject fake verifiers without touching globals; production
* wiring forwards the call verbatim.
*
* @param callable $verifier Verifier closure. Signature:
* `function (string $action, string $value): bool`.
* @param string $nonceValue Nonce value to verify.
*
* @phpstan-param callable(string, string): bool $verifier
*/
public static function validateNonce( callable $verifier, string $nonceValue ): bool {
return (bool) $verifier( self::NONCE_ACTION, $nonceValue );
}
}