You've already forked wp-prometheus
Initial plugin setup (v0.0.1)
Some checks failed
Create Release Package / build-release (push) Failing after 48s
Some checks failed
Create Release Package / build-release (push) Failing after 48s
- Create initial WordPress plugin structure - Add Prometheus metrics collector with default metrics - Implement authenticated /metrics endpoint with Bearer token - Add license management integration - Create admin settings page under Settings > Metrics - Set up Gitea CI/CD pipeline for automated releases - Add extensibility via wp_prometheus_collect_metrics hook Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
406
src/Admin/Settings.php
Normal file
406
src/Admin/Settings.php
Normal file
@@ -0,0 +1,406 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin settings class.
|
||||
*
|
||||
* @package WP_Prometheus
|
||||
*/
|
||||
|
||||
namespace Magdev\WpPrometheus\Admin;
|
||||
|
||||
use Magdev\WpPrometheus\License\Manager as LicenseManager;
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings class.
|
||||
*
|
||||
* Handles plugin settings page in the WordPress admin.
|
||||
*/
|
||||
class Settings {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_menu', array( $this, 'add_settings_page' ) );
|
||||
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add settings page to admin menu.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add_settings_page(): void {
|
||||
add_options_page(
|
||||
__( 'Metrics Settings', 'wp-prometheus' ),
|
||||
__( 'Metrics', 'wp-prometheus' ),
|
||||
'manage_options',
|
||||
'wp-prometheus',
|
||||
array( $this, 'render_settings_page' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register plugin settings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register_settings(): void {
|
||||
// License settings section.
|
||||
add_settings_section(
|
||||
'wp_prometheus_license_section',
|
||||
__( 'License Settings', 'wp-prometheus' ),
|
||||
array( $this, 'render_license_section' ),
|
||||
'wp-prometheus'
|
||||
);
|
||||
|
||||
// Auth token section.
|
||||
add_settings_section(
|
||||
'wp_prometheus_auth_section',
|
||||
__( 'Authentication', 'wp-prometheus' ),
|
||||
array( $this, 'render_auth_section' ),
|
||||
'wp-prometheus'
|
||||
);
|
||||
|
||||
// Metrics section.
|
||||
add_settings_section(
|
||||
'wp_prometheus_metrics_section',
|
||||
__( 'Default Metrics', 'wp-prometheus' ),
|
||||
array( $this, 'render_metrics_section' ),
|
||||
'wp-prometheus'
|
||||
);
|
||||
|
||||
// Register settings.
|
||||
register_setting( 'wp_prometheus_settings', 'wp_prometheus_auth_token', array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'sanitize_text_field',
|
||||
) );
|
||||
|
||||
register_setting( 'wp_prometheus_settings', 'wp_prometheus_enabled_metrics', array(
|
||||
'type' => 'array',
|
||||
'sanitize_callback' => array( $this, 'sanitize_metrics' ),
|
||||
) );
|
||||
|
||||
// Auth token field.
|
||||
add_settings_field(
|
||||
'wp_prometheus_auth_token',
|
||||
__( 'Auth Token', 'wp-prometheus' ),
|
||||
array( $this, 'render_auth_token_field' ),
|
||||
'wp-prometheus',
|
||||
'wp_prometheus_auth_section'
|
||||
);
|
||||
|
||||
// Enabled metrics field.
|
||||
add_settings_field(
|
||||
'wp_prometheus_enabled_metrics',
|
||||
__( 'Enabled Metrics', 'wp-prometheus' ),
|
||||
array( $this, 'render_enabled_metrics_field' ),
|
||||
'wp-prometheus',
|
||||
'wp_prometheus_metrics_section'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue admin scripts.
|
||||
*
|
||||
* @param string $hook_suffix Current admin page.
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue_scripts( string $hook_suffix ): void {
|
||||
if ( 'settings_page_wp-prometheus' !== $hook_suffix ) {
|
||||
return;
|
||||
}
|
||||
|
||||
wp_enqueue_script(
|
||||
'wp-prometheus-admin',
|
||||
WP_PROMETHEUS_URL . 'assets/js/admin.js',
|
||||
array( 'jquery' ),
|
||||
WP_PROMETHEUS_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
wp_localize_script( 'wp-prometheus-admin', 'wpPrometheus', array(
|
||||
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||
'nonce' => wp_create_nonce( 'wp_prometheus_license_action' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the settings page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_settings_page(): void {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle license settings save.
|
||||
if ( isset( $_POST['wp_prometheus_license_nonce'] ) && wp_verify_nonce( sanitize_key( $_POST['wp_prometheus_license_nonce'] ), 'wp_prometheus_save_license' ) ) {
|
||||
LicenseManager::save_settings( array(
|
||||
'license_key' => isset( $_POST['license_key'] ) ? sanitize_text_field( wp_unslash( $_POST['license_key'] ) ) : '',
|
||||
'server_url' => isset( $_POST['license_server_url'] ) ? esc_url_raw( wp_unslash( $_POST['license_server_url'] ) ) : '',
|
||||
'server_secret' => isset( $_POST['license_server_secret'] ) ? sanitize_text_field( wp_unslash( $_POST['license_server_secret'] ) ) : '',
|
||||
) );
|
||||
echo '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'License settings saved.', 'wp-prometheus' ) . '</p></div>';
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
||||
|
||||
<?php $this->render_license_form(); ?>
|
||||
|
||||
<form method="post" action="options.php">
|
||||
<?php
|
||||
settings_fields( 'wp_prometheus_settings' );
|
||||
do_settings_sections( 'wp-prometheus' );
|
||||
submit_button();
|
||||
?>
|
||||
</form>
|
||||
|
||||
<?php $this->render_endpoint_info(); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render license settings form.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_license_form(): void {
|
||||
$license_key = LicenseManager::get_license_key();
|
||||
$server_url = LicenseManager::get_server_url();
|
||||
$license_status = LicenseManager::get_cached_status();
|
||||
$license_data = LicenseManager::get_cached_data();
|
||||
$last_check = LicenseManager::get_last_check();
|
||||
|
||||
$status_classes = array(
|
||||
'valid' => 'notice-success',
|
||||
'invalid' => 'notice-error',
|
||||
'expired' => 'notice-warning',
|
||||
'revoked' => 'notice-error',
|
||||
'inactive' => 'notice-warning',
|
||||
'unchecked' => 'notice-info',
|
||||
'unconfigured' => 'notice-info',
|
||||
);
|
||||
|
||||
$status_messages = array(
|
||||
'valid' => __( 'License is active and valid.', 'wp-prometheus' ),
|
||||
'invalid' => __( 'License is invalid.', 'wp-prometheus' ),
|
||||
'expired' => __( 'License has expired.', 'wp-prometheus' ),
|
||||
'revoked' => __( 'License has been revoked.', 'wp-prometheus' ),
|
||||
'inactive' => __( 'License is inactive.', 'wp-prometheus' ),
|
||||
'unchecked' => __( 'License has not been validated yet.', 'wp-prometheus' ),
|
||||
'unconfigured' => __( 'License server is not configured.', 'wp-prometheus' ),
|
||||
);
|
||||
|
||||
$status_class = $status_classes[ $license_status ] ?? 'notice-info';
|
||||
$status_message = $status_messages[ $license_status ] ?? __( 'Unknown status.', 'wp-prometheus' );
|
||||
?>
|
||||
<div class="wp-prometheus-license-status notice <?php echo esc_attr( $status_class ); ?>" style="padding: 12px;">
|
||||
<strong><?php echo esc_html( $status_message ); ?></strong>
|
||||
<?php if ( 'valid' === $license_status && ! empty( $license_data['expires_at'] ) ) : ?>
|
||||
<br><span class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Expiration date */
|
||||
esc_html__( 'Expires: %s', 'wp-prometheus' ),
|
||||
esc_html( $license_data['expires_at'] )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( $last_check > 0 ) : ?>
|
||||
<br><span class="description">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Time ago */
|
||||
esc_html__( 'Last checked: %s ago', 'wp-prometheus' ),
|
||||
esc_html( human_time_diff( $last_check, time() ) )
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<form method="post" action="" id="wp-prometheus-license-form">
|
||||
<?php wp_nonce_field( 'wp_prometheus_save_license', 'wp_prometheus_license_nonce' ); ?>
|
||||
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="license_server_url"><?php esc_html_e( 'License Server URL', 'wp-prometheus' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="url" name="license_server_url" id="license_server_url"
|
||||
value="<?php echo esc_attr( $server_url ); ?>"
|
||||
class="regular-text" placeholder="https://example.com">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="license_key"><?php esc_html_e( 'License Key', 'wp-prometheus' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="license_key" id="license_key"
|
||||
value="<?php echo esc_attr( $license_key ); ?>"
|
||||
class="regular-text" placeholder="XXXX-XXXX-XXXX-XXXX">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for="license_server_secret"><?php esc_html_e( 'Server Secret', 'wp-prometheus' ); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="password" name="license_server_secret" id="license_server_secret"
|
||||
value="" class="regular-text" placeholder="<?php echo esc_attr( ! empty( LicenseManager::get_server_secret() ) ? '••••••••••••••••' : '' ); ?>">
|
||||
<p class="description"><?php esc_html_e( 'Leave empty to keep existing.', 'wp-prometheus' ); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p class="submit">
|
||||
<?php submit_button( __( 'Save License Settings', 'wp-prometheus' ), 'primary', 'submit', false ); ?>
|
||||
<button type="button" id="wp-prometheus-validate-license" class="button button-secondary" style="margin-left: 10px;">
|
||||
<?php esc_html_e( 'Validate License', 'wp-prometheus' ); ?>
|
||||
</button>
|
||||
<button type="button" id="wp-prometheus-activate-license" class="button button-secondary" style="margin-left: 10px;">
|
||||
<?php esc_html_e( 'Activate License', 'wp-prometheus' ); ?>
|
||||
</button>
|
||||
<span id="wp-prometheus-license-spinner" class="spinner" style="float: none;"></span>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<div id="wp-prometheus-license-message" style="display: none; margin-top: 10px;"></div>
|
||||
<hr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render license section description.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_license_section(): void {
|
||||
// License section rendered separately in render_license_form().
|
||||
}
|
||||
|
||||
/**
|
||||
* Render auth section description.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_auth_section(): void {
|
||||
echo '<p>' . esc_html__( 'Configure authentication for the /metrics endpoint.', 'wp-prometheus' ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render metrics section description.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_metrics_section(): void {
|
||||
echo '<p>' . esc_html__( 'Select which default metrics to expose.', 'wp-prometheus' ) . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render auth token field.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_auth_token_field(): void {
|
||||
$token = get_option( 'wp_prometheus_auth_token', '' );
|
||||
?>
|
||||
<input type="text" name="wp_prometheus_auth_token" id="wp_prometheus_auth_token"
|
||||
value="<?php echo esc_attr( $token ); ?>" class="regular-text" readonly>
|
||||
<button type="button" id="wp-prometheus-regenerate-token" class="button button-secondary">
|
||||
<?php esc_html_e( 'Regenerate', 'wp-prometheus' ); ?>
|
||||
</button>
|
||||
<p class="description">
|
||||
<?php esc_html_e( 'Use this token to authenticate Prometheus scrape requests.', 'wp-prometheus' ); ?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render enabled metrics field.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function render_enabled_metrics_field(): void {
|
||||
$enabled = get_option( 'wp_prometheus_enabled_metrics', array() );
|
||||
$metrics = array(
|
||||
'wordpress_info' => __( 'WordPress Info (version, PHP version, multisite)', 'wp-prometheus' ),
|
||||
'wordpress_users_total' => __( 'Total Users by Role', 'wp-prometheus' ),
|
||||
'wordpress_posts_total' => __( 'Total Posts by Type and Status', 'wp-prometheus' ),
|
||||
'wordpress_comments_total' => __( 'Total Comments by Status', 'wp-prometheus' ),
|
||||
'wordpress_plugins_total' => __( 'Total Plugins (active/inactive)', 'wp-prometheus' ),
|
||||
);
|
||||
|
||||
foreach ( $metrics as $key => $label ) {
|
||||
?>
|
||||
<label style="display: block; margin-bottom: 5px;">
|
||||
<input type="checkbox" name="wp_prometheus_enabled_metrics[]"
|
||||
value="<?php echo esc_attr( $key ); ?>"
|
||||
<?php checked( in_array( $key, $enabled, true ) ); ?>>
|
||||
<?php echo esc_html( $label ); ?>
|
||||
</label>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render endpoint info.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function render_endpoint_info(): void {
|
||||
$token = get_option( 'wp_prometheus_auth_token', '' );
|
||||
$endpoint_url = home_url( '/metrics/' );
|
||||
?>
|
||||
<hr>
|
||||
<h2><?php esc_html_e( 'Prometheus Configuration', 'wp-prometheus' ); ?></h2>
|
||||
<p><?php esc_html_e( 'Add the following to your prometheus.yml:', 'wp-prometheus' ); ?></p>
|
||||
<pre style="background: #f1f1f1; padding: 15px; overflow-x: auto;">
|
||||
scrape_configs:
|
||||
- job_name: 'wordpress'
|
||||
static_configs:
|
||||
- targets: ['<?php echo esc_html( wp_parse_url( home_url(), PHP_URL_HOST ) ); ?>']
|
||||
metrics_path: '/metrics/'
|
||||
scheme: '<?php echo esc_html( wp_parse_url( home_url(), PHP_URL_SCHEME ) ); ?>'
|
||||
authorization:
|
||||
type: Bearer
|
||||
credentials: '<?php echo esc_html( $token ); ?>'</pre>
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %s: Endpoint URL */
|
||||
esc_html__( 'Metrics endpoint: %s', 'wp-prometheus' ),
|
||||
'<code>' . esc_url( $endpoint_url ) . '</code>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize enabled metrics.
|
||||
*
|
||||
* @param mixed $input Input value.
|
||||
* @return array
|
||||
*/
|
||||
public function sanitize_metrics( $input ): array {
|
||||
if ( ! is_array( $input ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array_map( 'sanitize_text_field', $input );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user