';
echo '
';
echo '';
echo wp_kses( self::weather_heading_svg(), self::weather_heading_svg_allowed_html() );
echo '';
echo '';
echo esc_html__( '4WP Weather', '4wp-weather' );
echo '';
echo '
';
echo '';
echo '';
}
/**
* Allowed tags for the static admin heading SVG.
*
* @return array>
*/
private static function weather_heading_svg_allowed_html(): array {
return array(
'svg' => array(
'xmlns' => true,
'viewbox' => true,
'width' => true,
'height' => true,
'fill' => true,
'focusable' => true,
'aria-hidden' => true,
),
'path' => array(
'd' => true,
'fill' => true,
'stroke' => true,
'stroke-width' => true,
'stroke-linecap' => true,
'stroke-linejoin' => true,
),
);
}
/**
* Inline weather icon for the settings screen heading (stroke uses currentColor for admin theme).
*
* @return string SVG markup.
*/
private static function weather_heading_svg(): string {
return '';
}
/**
* Scripts and styles only on our screen.
*
* @param string $hook_suffix Current admin page.
*/
public function enqueue_admin_assets( string $hook_suffix ): void {
if ( 'toplevel_page_forwp-weather' !== $hook_suffix ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$asset_file = FORWP_WEATHER_PATH . 'build/admin/index.asset.php';
if ( ! is_readable( $asset_file ) ) {
return;
}
$asset = include $asset_file;
wp_enqueue_style( 'wp-components' );
$style_path = FORWP_WEATHER_PATH . 'build/admin/style-index.css';
if ( is_readable( $style_path ) ) {
wp_enqueue_style(
'forwp-weather-admin',
FORWP_WEATHER_URL . 'build/admin/style-index.css',
array( 'wp-components' ),
$asset['version']
);
}
wp_enqueue_script(
'forwp-weather-admin',
FORWP_WEATHER_URL . 'build/admin/index.js',
$asset['dependencies'],
$asset['version'],
true
);
wp_set_script_translations( 'forwp-weather-admin', '4wp-weather', FORWP_WEATHER_PATH . 'languages' );
wp_localize_script(
'forwp-weather-admin',
'forwpWeatherAdmin',
array(
'restRoot' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
)
);
}
/**
* Sanitize API key input.
*
* @param mixed $value Raw value.
*/
public function sanitize_api_key( $value ): string {
$value = is_string( $value ) ? $value : '';
return sanitize_text_field( trim( $value ) );
}
/**
* Stored API key for the active credential provider.
*
* @return string
*/
public function get_api_key(): string {
$key = get_option( self::OPTION_KEY, '' );
return is_string( $key ) ? $key : '';
}
/**
* Slug of the provider that receives the stored API key.
*
* @return string
*/
public function get_credential_provider(): string {
$slug = get_option( self::CREDENTIAL_PROVIDER_OPTION, '' );
$slug = is_string( $slug ) ? sanitize_key( $slug ) : '';
if ( '' === $slug || ! in_array( $slug, Provider_Registry::implemented_slugs(), true ) ) {
return \ForWP\Weather\Providers\OpenWeatherMap_Provider::SLUG;
}
return $slug;
}
/**
* Saved preview latitude for admin live preview (optional).
*/
public function get_preview_latitude_saved(): string {
$raw = get_option( self::PREVIEW_LAT_OPTION, '' );
if ( is_numeric( $raw ) ) {
return (string) $raw;
}
return '';
}
/**
* Saved preview longitude for admin live preview (optional).
*/
public function get_preview_longitude_saved(): string {
$raw = get_option( self::PREVIEW_LON_OPTION, '' );
if ( is_numeric( $raw ) ) {
return (string) $raw;
}
return '';
}
/**
* Coordinates used for admin preview (saved pair or filter default).
*
* @return array{lat: float, lon: float}
*/
public function get_preview_coordinates(): array {
$lat_raw = get_option( self::PREVIEW_LAT_OPTION, '' );
$lon_raw = get_option( self::PREVIEW_LON_OPTION, '' );
$lat = is_numeric( $lat_raw ) ? (float) $lat_raw : null;
$lon = is_numeric( $lon_raw ) ? (float) $lon_raw : null;
if ( null !== $lat && null !== $lon ) {
return array(
'lat' => $lat,
'lon' => $lon,
);
}
/**
* Filter default map coordinates when no preview lat/lon are saved.
*
* @param array{lat: float, lon: float} $coords Default coordinates (decimal degrees).
*/
$default = apply_filters(
'forwp_weather_default_preview_coordinates',
array(
'lat' => 51.5074,
'lon' => -0.1278,
)
);
if ( ! is_array( $default ) ) {
return array(
'lat' => 51.5074,
'lon' => -0.1278,
);
}
$fallback_lat = isset( $default['lat'] ) && is_numeric( $default['lat'] ) ? (float) $default['lat'] : 51.5074;
$fallback_lon = isset( $default['lon'] ) && is_numeric( $default['lon'] ) ? (float) $default['lon'] : -0.1278;
return array(
'lat' => $fallback_lat,
'lon' => $fallback_lon,
);
}
/**
* Cooldown seconds for visitor location changes (front end). Clamped 0 … DAY_IN_SECONDS.
*/
public function get_location_change_cooldown_seconds(): int {
$raw = get_option( self::LOCATION_CHANGE_COOLDOWN_OPTION, 60 );
$n = is_numeric( $raw ) ? (int) $raw : 60;
if ( $n < 0 ) {
return 0;
}
if ( $n > (int) DAY_IN_SECONDS ) {
return (int) DAY_IN_SECONDS;
}
return $n;
}
/**
* Whether to show a weather summary in the admin bar for administrators.
*/
public function get_show_admin_bar_weather(): bool {
return (bool) get_option( self::SHOW_ADMIN_BAR_WEATHER_OPTION, false );
}
/**
* Whether to output JSON-LD on the public site (per successful block fetch), not in wp-admin.
*/
public function get_output_json_ld(): bool {
return (bool) get_option( self::OUTPUT_JSON_LD_OPTION, false );
}
}