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