diff --git a/door-status-config.php b/door-status-config.php
new file mode 100644
index 0000000..9f470d2
--- /dev/null
+++ b/door-status-config.php
@@ -0,0 +1,3 @@
+define( 'DSI_API_URL', 'https://nodered.jfig.net/api/v1/door-open' );
+define( 'DSI_CACHE_KEY', 'dsi_door_open_status' );
+define( 'DSI_CACHE_TTL', 10 );
\ No newline at end of file
diff --git a/wp-api-consumer.php b/wp-api-consumer.php
index 05ec157..10d6486 100644
--- a/wp-api-consumer.php
+++ b/wp-api-consumer.php
@@ -1,48 +1,162 @@
, caches the status for a few seconds, and shows a real‑time door open/closed indicator (🟢/🔴) via [door_status] shortcode and the Admin Bar.
+ * Version: 1.1.0
+ * Author: Joao Figueiredo (ChatGPT helper)
+ * Author URI: https://jfig.net
+ * License: GPL v2 or later
+ * License URI: https://www.gnu.org/licenses/gpl-2.0.html
+ * Text Domain: door-status-indicator
*/
-defined( 'ABSPATH' ) || exit;
-
-/**
- * Fetch the Boolean once every 10 s (adjust TTL to taste).
- */
-function ds_get_state() {
- $state = get_transient( 'ds_state' );
-
- if ( false === $state ) {
- $r = wp_remote_get( 'https://nodered.jfig.net/api/v1/door-open', [ 'timeout' => 4 ] ); // 4 s hard stop
- $state = is_wp_error( $r ) ? '' : trim( wp_remote_retrieve_body( $r ) );
- set_transient( 'ds_state', $state, 10 );
- }
- return $state;
+if ( ! defined( 'ABSPATH' ) ) {
+ exit; // Exit if accessed directly.
}
-/**
- * Returns a coloured dot (🟢 / 🔴) or ⚪ if the API is unreachable.
- */
-function ds_render() {
- $s = strtolower( ds_get_state() );
- if ( 'true' === $s ) return '🟢';
- if ( 'false' === $s ) return '🔴';
- return '⚪';
+/*
+|--------------------------------------------------------------------------
+| Configuration
+|--------------------------------------------------------------------------
+| Place environment‑specific constants inside door-status-config.php.
+| They will be loaded automatically. If the file is missing we fall back to
+| bundled defaults so the plugin keeps working out‑of‑the‑box.
+*/
+
+$config_file = plugin_dir_path( __FILE__ ) . 'door-status-config.php';
+if ( file_exists( $config_file ) ) {
+ require_once $config_file;
+} else {
+ // Fallback defaults – safe to adjust directly here if you prefer.
+ define( 'DSI_API_URL', 'https://nodered.jfig.net/api/v1/door-open' );
+ define( 'DSI_CACHE_KEY', 'dsi_door_open_status' );
+ define( 'DSI_CACHE_TTL', 10 );
}
-add_shortcode( 'door_state', 'ds_render' ); // [door_state]
+
+/*
+|--------------------------------------------------------------------------
+| Core – fetch & cache
+|--------------------------------------------------------------------------
+*/
/**
- * Automatically append the indicator to a menu (optional).
- * Replace 'primary' with your theme’s menu slug if different.
+ * Retrieves the door‑open status (boolean) with transient caching.
+ *
+ * @return bool True if open, false if closed.
*/
-function ds_menu_item( $items, $args ) {
- if ( 'primary' === $args->theme_location ) {
- $items .= '
';
- }
- return $items;
-}
-add_filter( 'wp_nav_menu_items', 'ds_menu_item', 10, 2 );
+function dsi_get_status() : bool {
+ $cached = get_transient( DSI_CACHE_KEY );
+ if ( false !== $cached ) {
+ return (bool) $cached;
+ }
+ $response = wp_remote_get( DSI_API_URL, [
+ 'timeout' => 3,
+ 'user-agent' => 'DoorStatusIndicator/1.1 (+https://wordpress.org/)',
+ ] );
+
+ if ( is_wp_error( $response ) ) {
+ // On error, assume closed and set a short transient to avoid hammering.
+ set_transient( DSI_CACHE_KEY, false, DSI_CACHE_TTL );
+ return false;
+ }
+
+ $body = wp_remote_retrieve_body( $response );
+ $decoded = json_decode( $body, true );
+ $status = false;
+
+ if ( is_bool( $decoded ) ) {
+ $status = $decoded;
+ } elseif ( is_array( $decoded ) && isset( $decoded['open'] ) ) {
+ $status = (bool) $decoded['open'];
+ }
+
+ set_transient( DSI_CACHE_KEY, $status, DSI_CACHE_TTL );
+ return $status;
+}
+
+/*
+|--------------------------------------------------------------------------
+| Shortcode [door_status]
+|--------------------------------------------------------------------------
+*/
+
+/**
+ * Outputs a 🟢 or 🔴 indicator reflecting current door status.
+ * Usage: [door_status]
+ *
+ * @return string HTML span with coloured emoji.
+ */
+function dsi_shortcode() : string {
+ $open = dsi_get_status();
+ $emoji = $open ? '🟢' : '🔴';
+
+ return sprintf(
+ '%s',
+ $open ? 'open' : 'closed',
+ $emoji
+ );
+}
+add_shortcode( 'door_status', 'dsi_shortcode' );
+
+/*
+|--------------------------------------------------------------------------
+| Admin Bar indicator
+|--------------------------------------------------------------------------
+*/
+
+/**
+ * Adds a live indicator to the WordPress Admin Bar (front‑ and back‑end).
+ *
+ * @param WP_Admin_Bar $wp_admin_bar The admin bar instance.
+ */
+function dsi_admin_bar( WP_Admin_Bar $wp_admin_bar ) : void {
+ if ( ! current_user_can( 'read' ) ) {
+ return; // Only show to logged‑in users who can read.
+ }
+
+ $open = dsi_get_status();
+ $emoji = $open ? '🟢' : '🔴';
+ $text = $open ? __( 'Door Open', 'door-status-indicator' ) : __( 'Door Closed', 'door-status-indicator' );
+
+ $wp_admin_bar->add_node( [
+ 'id' => 'door-status-indicator',
+ 'title' => sprintf( '%s %s', $emoji, $text ),
+ 'href' => '#',
+ 'meta' => [
+ 'title' => $text,
+ ],
+ ] );
+}
+add_action( 'admin_bar_menu', 'dsi_admin_bar', 1000 );
+
+/*
+|--------------------------------------------------------------------------
+| Front‑end inline CSS
+|--------------------------------------------------------------------------
+*/
+
+function dsi_enqueue_assets() : void {
+ if ( is_admin() ) {
+ return;
+ }
+ $css = '.door-status-indicator{font-size:1.2em;line-height:1}';
+ wp_add_inline_style( 'wp-block-library', $css );
+}
+add_action( 'wp_enqueue_scripts', 'dsi_enqueue_assets' );
+
+/*
+|--------------------------------------------------------------------------
+| WP‑CLI command (optional)
+|--------------------------------------------------------------------------
+*/
+
+if ( defined( 'WP_CLI' ) && WP_CLI ) {
+ WP_CLI::add_command( 'door-status', function() {
+ $status = dsi_get_status() ? 'open 🟢' : 'closed 🔴';
+ WP_CLI::success( "Door is $status" );
+ } );
+}
+
+// End of file