.
*/
// Block direct file access. Prevent direct execution.
defined( 'ABSPATH' ) || exit;
define( 'ACTH_OPTION_KEY', 'acth_options' );
define( 'ACTH_VERSION', '1.20' );
/**
* Main plugin class.
*
* Wraps all hooks and callbacks to avoid polluting the global namespace.
*/
class AddCodeToHead {
/** @var AddCodeToHead|null Singleton instance. */
private static ?AddCodeToHead $instance = null;
/**
* Return (and, on first call, create) the singleton instance.
*
* @return AddCodeToHead
*/
public static function get_instance(): AddCodeToHead {
if ( null === self::$instance ) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Private constructor — use AddCodeToHead::get_instance() instead.
* Registers all WordPress action/filter hooks.
*/
private function __construct() {
add_action( 'admin_menu', array( $this, 'add_admin' ) );
add_action( 'admin_init', array( $this, 'admin_init' ) );
add_action( 'wp_head', array( $this, 'display' ) );
// Add "Settings" shortcut link on the Plugins list screen.
add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ),
array( $this, 'add_settings_link' ) );
}
// -------------------------------------------------------------------------
// Admin menu
// -------------------------------------------------------------------------
/**
* Register the options page under Settings.
*/
public function add_admin(): void {
add_options_page(
__( 'Add Code to Head', 'add-code-to-head' ),
__( 'Add Code to Head', 'add-code-to-head' ),
'manage_options',
'acth_plugin',
array( $this, 'plugin_options_page' )
);
}
/**
* Inject our "Settings" link on the Installed Plugins page
*
* @param string[] $links Existing action links.
* @return string[]
*/
public function add_settings_link( array $links ): array {
$settings_link = sprintf(
'%s',
esc_url( admin_url( 'options-general.php?page=acth_plugin' ) ),
esc_html__( 'Settings', 'add-code-to-head' )
);
array_unshift( $links, $settings_link );
return $links;
}
// -------------------------------------------------------------------------
// Options page rendering
// -------------------------------------------------------------------------
/**
* Render the options page.
* Capability is already enforced by add_options_page(), but we re-check
* here as a belt-and-suspenders guard before outputting anything.
*/
public function plugin_options_page(): void {
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
?>
$this->warning_html(),
)
);
add_settings_field(
'acth_string',
__( 'Code', 'add-code-to-head' ),
array( $this, 'text_field' ),
'acth_plugin',
'acth_section'
);
}
/**
* Build the warning banner shown above the textarea.
* Kept as a method so the string is constructed once
* and can be unit-tested.
*
* @return string Safe HTML string.
*/
private function warning_html(): string {
return sprintf(
'',
esc_html__( '⚠️ WARNING:', 'add-code-to-head' ),
esc_html__( 'All code entered here is added to every public page on the blog. Any script you add here will run on every page, for every visitor.', 'add-code-to-head' ),
esc_html__( 'Only Trusted Administrators should use this function.', 'add-code-to-head' )
);
}
// -------------------------------------------------------------------------
// Field rendering
// -------------------------------------------------------------------------
/**
* Render the textarea field.
*/
public function text_field(): void {
$options = get_option( ACTH_OPTION_KEY );
$val = isset( $options['text_string'] ) ? $options['text_string'] : '';
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- esc_textarea() applied.
printf(
'',
esc_attr( ACTH_OPTION_KEY ),
esc_attr( ACTH_OPTION_KEY ),
esc_textarea( $val )
);
}
// -------------------------------------------------------------------------
// Sanitization / validation
// -------------------------------------------------------------------------
/**
* Sanitize incoming option value before it is stored.
*
* Users with `unfiltered_html` (administrators on single-site installs) may
* save arbitrary markup — that is the intentional purpose of this plugin.
* All other roles have their input stripped to safe post-level HTML.
*
* @param array $input Raw POST input.
* @return array Sanitized options array.
*/
public function options_validate( array $input ): array {
$new = array();
$new['text_string'] = isset( $input['text_string'] ) ? trim( $input['text_string'] ) : '';
if ( ! current_user_can( 'unfiltered_html' ) ) {
$new['text_string'] = wp_kses_post( $new['text_string'] );
}
return $new;
}
// -------------------------------------------------------------------------
// Front-end output
// -------------------------------------------------------------------------
/**
* Echo the saved code into the public .
*
* The is_admin() guard prevents accidental output if hook timing ever changes.
*
* NOTE: Output is intentionally NOT escaped — arbitrary HTML/JS injection
* into the is the entire purpose of this plugin. Access is controlled
* at save-time via options_validate() and the manage_options capability.
*/
public function display(): void {
if ( is_admin() ) {
return;
}
$options = get_option( ACTH_OPTION_KEY );
$code = isset( $options['text_string'] ) ? $options['text_string'] : '';
if ( '' !== $code ) {
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo "\n" . $code . "\n";
}
}
}
// ****************************************************************************
// * === BOOTSTRAP === *
// * Direct instantiation via the singleton factory on the *
// * 'plugins_loaded' hook, the correct point to initialize a plugin. *
// ****************************************************************************
add_action( 'plugins_loaded', array( 'AddCodeToHead', 'get_instance' ) );