Compare commits
28 Commits
e07dac0736
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 23eb896c71 | |||
| 05c4e67266 | |||
| 5bd7dcd9d2 | |||
| 88b145d6b3 | |||
| b21a0f03aa | |||
| 55c20df3b5 | |||
| 0ed97819fe | |||
| 6fa42e8f45 | |||
| 42345c47b9 | |||
| f0f2814d35 | |||
| f913cb1f6d | |||
| 754738eebd | |||
| f52a1a60e3 | |||
| 7bdb9df5f4 | |||
| 310cc2a009 | |||
| a1e856c008 | |||
| bfca0c8fa4 | |||
| e6ff012774 | |||
| b979b0f938 | |||
| 306f368ae2 | |||
| d95e013301 | |||
| 279f717973 | |||
| bfd27d0519 | |||
| 83f7979106 | |||
| 8d6fec4103 | |||
| 64ed76913a | |||
| 6517f0dc39 | |||
| 7dccad1f48 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -15,7 +15,7 @@
|
|||||||
/index.php
|
/index.php
|
||||||
/license.txt
|
/license.txt
|
||||||
/readme.html
|
/readme.html
|
||||||
/wp-*.php
|
#/wp-*.php
|
||||||
/xmlrpc.php
|
/xmlrpc.php
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
@@ -47,3 +47,9 @@ wp-config.php
|
|||||||
# Note: If you wish to whitelist themes,
|
# Note: If you wish to whitelist themes,
|
||||||
# uncomment the next line
|
# uncomment the next line
|
||||||
#/wp-content/themes
|
#/wp-content/themes
|
||||||
|
|
||||||
|
# ---> Node.js
|
||||||
|
/node_modules/
|
||||||
|
/package-lock.json
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -1,3 +1,24 @@
|
|||||||
# wp-api-consumer
|
# WordPress SpaceAPI Consumer
|
||||||
|
|
||||||
Small WprdPress plugin to consume an API
|
# wp-spaceapi-consumer
|
||||||
|
|
||||||
|
Small WordPress plugin to consume an SpaceAPI endpoint and indicate on the WordPress website if the Space is Open or Closed
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### WordPress Editor Block (Gutenberg)
|
||||||
|
|
||||||
|
You can use the `Space Status` block in the WordPress editor to display the status of the SpaceAPI endpoint.
|
||||||
|
|
||||||
|
### Shortcode
|
||||||
|
|
||||||
|
You can use the shortcode `[space_status]` to display the status of the SpaceAPI endpoint on your WordPress site.
|
||||||
|
|
||||||
|
### Widget
|
||||||
|
|
||||||
|
You can also use the widget `SpaceAPI Status` to display the status of the SpaceAPI endpoint in your WordPress sidebar or footer.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|
### 0.4.x
|
||||||
|
- Added WordPress Editor Block (Gutenberg) support
|
||||||
21
blocks-register.php
Normal file
21
blocks-register.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
// Exit if accessed directly.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ssi_register_space_status_block() : void {
|
||||||
|
$asset_path = plugin_dir_path( __FILE__ ) . 'build/space-status';
|
||||||
|
register_block_type( $asset_path, [
|
||||||
|
'render_callback' => 'ssi_render_block',
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
add_action( 'init', 'ssi_register_space_status_block' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server‑side markup for the block.
|
||||||
|
*/
|
||||||
|
function ssi_render_block( array $attributes, string $content ) : string {
|
||||||
|
// Re‑use existing helper & CSS class logic.
|
||||||
|
return ssi_shortcode();
|
||||||
|
}
|
||||||
15
build/space-status/block.json
Normal file
15
build/space-status/block.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"apiVersion": 3,
|
||||||
|
"name": "wp-spaceapi-consumer/space-status",
|
||||||
|
"title": "Space Status",
|
||||||
|
"description": "Show whether the space is open or closed (SpaceAPI consumer).",
|
||||||
|
"category": "widgets",
|
||||||
|
"icon": "building",
|
||||||
|
"textdomain": "wp-spaceapi-consumer",
|
||||||
|
"style": "file:./style.css",
|
||||||
|
"editorStyle": "file:./editor.css",
|
||||||
|
"editorScript": "file:./index.js",
|
||||||
|
"supports": {
|
||||||
|
"html": false
|
||||||
|
}
|
||||||
|
}
|
||||||
1
build/space-status/index.asset.php
Normal file
1
build/space-status/index.asset.php
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?php return array('dependencies' => array('react-jsx-runtime', 'wp-blocks', 'wp-i18n', 'wp-server-side-render'), 'version' => 'e81eff0b8644d0be4dac');
|
||||||
1
build/space-status/index.js
Normal file
1
build/space-status/index.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
(()=>{"use strict";var e={n:r=>{var s=r&&r.__esModule?()=>r.default:()=>r;return e.d(s,{a:s}),s},d:(r,s)=>{for(var t in s)e.o(s,t)&&!e.o(r,t)&&Object.defineProperty(r,t,{enumerable:!0,get:s[t]})},o:(e,r)=>Object.prototype.hasOwnProperty.call(e,r)};window.wp.i18n;const r=window.wp.blocks,s=window.wp.serverSideRender;var t=e.n(s);const o=window.ReactJSXRuntime;(0,r.registerBlockType)("wp-spaceapi-consumer/space-status",{edit:()=>(0,o.jsx)(t(),{block:"wp-spaceapi-consumer/space-status"}),save:()=>null})})();
|
||||||
15
package.json
Normal file
15
package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "wp-spaceapi-consumer",
|
||||||
|
"version": "0.0.0-private",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "wp-scripts build",
|
||||||
|
"start": "wp-scripts start"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@wordpress/scripts": "^30.18.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/space-status/block.json
Normal file
13
src/space-status/block.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"apiVersion": 3,
|
||||||
|
"name": "wp-spaceapi-consumer/space-status",
|
||||||
|
"title": "Space Status",
|
||||||
|
"description": "Show whether the space is open or closed (SpaceAPI consumer).",
|
||||||
|
"category": "widgets",
|
||||||
|
"icon": "building",
|
||||||
|
"textdomain": "wp-spaceapi-consumer",
|
||||||
|
"style": "file:./style.css",
|
||||||
|
"editorStyle": "file:./editor.css",
|
||||||
|
"editorScript": "file:./index.js",
|
||||||
|
"supports": { "html": false }
|
||||||
|
}
|
||||||
7
src/space-status/editor.css
Normal file
7
src/space-status/editor.css
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/* Editor-only: make the pill obvious & easy to select */
|
||||||
|
.wp-block-wp-spaceapi-consumer-space-status {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: 1px dashed var(--wp-admin-theme-color, #007cba);
|
||||||
|
border-radius: 9999px;
|
||||||
|
}
|
||||||
12
src/space-status/index.js
Normal file
12
src/space-status/index.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { __ } from '@wordpress/i18n';
|
||||||
|
import { registerBlockType } from '@wordpress/blocks';
|
||||||
|
import ServerSideRender from '@wordpress/server-side-render';
|
||||||
|
|
||||||
|
registerBlockType( 'wp-spaceapi-consumer/space-status', {
|
||||||
|
edit: () => (
|
||||||
|
<ServerSideRender
|
||||||
|
block="wp-spaceapi-consumer/space-status"
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
save: () => null, // dynamic block — markup comes from PHP
|
||||||
|
} );
|
||||||
1
src/space-status/style.css
Normal file
1
src/space-status/style.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
@import url('../../wp-spaceapi-consumer-style.css');
|
||||||
5
wp-spaceapi-consumer-config.php
Normal file
5
wp-spaceapi-consumer-config.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define( 'SSI_API_URL', 'https://lcdporto.org/api/spaceapi' );
|
||||||
|
define( 'SSI_CACHE_KEY', 'ssi_space_api_status' );
|
||||||
|
define( 'SSI_CACHE_TTL', 10 );
|
||||||
34
wp-spaceapi-consumer-style.css
Normal file
34
wp-spaceapi-consumer-style.css
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/* space-status.css - styles the indicator as a pill-shaped button */
|
||||||
|
|
||||||
|
.space-status-indicator {
|
||||||
|
display:inline-flex;
|
||||||
|
align-items:center;
|
||||||
|
gap:0.4em;
|
||||||
|
padding:0.25em 0.75em;
|
||||||
|
border-radius:1em; /* fully-rounded corners */
|
||||||
|
font-size:0.95em;
|
||||||
|
font-weight:600;
|
||||||
|
line-height:1;
|
||||||
|
border:1px solid transparent;
|
||||||
|
user-select:none;
|
||||||
|
transition:filter .15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open = soft green background + dark green text */
|
||||||
|
.space-status-indicator.open {
|
||||||
|
background:#e7f9ec;
|
||||||
|
color:#1e7a34;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Closed = soft red background + dark red text */
|
||||||
|
.space-status-indicator.closed {
|
||||||
|
background:#fdeeee;
|
||||||
|
color:#c03c3c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (Optional) slight hover effect */
|
||||||
|
.space-status-indicator:hover,
|
||||||
|
.space-status-indicator:focus {
|
||||||
|
filter:brightness(1.05);
|
||||||
|
outline:none;
|
||||||
|
}
|
||||||
176
wp-spaceapi-consumer.php
Normal file
176
wp-spaceapi-consumer.php
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: WordPress SpaceAPI Consumer
|
||||||
|
* Plugin Slug: wp-spaceapi-consumer
|
||||||
|
* Plugin URI: https://gitea.alluna.pt/jfig/wp-spaceapi-consumer
|
||||||
|
* Description: WordPress plugin to consume a SpaceAPI endpoint and indicate if the Space is Open or Closed
|
||||||
|
* Version: 0.4.2
|
||||||
|
* Author: Joao Figueiredo, LCD Porto Team, ChatGPT o3
|
||||||
|
* Author URI: https://lcdporto.org
|
||||||
|
* License: MIT
|
||||||
|
* License URI: https://gitea.alluna.pt/jfig/wp-spaceapi-consumer/src/branch/dev/LICENSE
|
||||||
|
* Text Domain: wp-spaceapi-consumer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit; // Exit if accessed directly.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Constants are expected in wp-spaceapi-consumer-config.php located in the same
|
||||||
|
| directory. If that file is missing, sane defaults are used so the plugin
|
||||||
|
| still works out-of-the-box.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$config_file = plugin_dir_path( __FILE__ ) . 'wp-spaceapi-consumer-config.php';
|
||||||
|
if ( file_exists( $config_file ) ) {
|
||||||
|
require_once $config_file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback defaults (only if not already defined by the config file).
|
||||||
|
! defined( 'SSI_API_URL' ) && define( 'SSI_API_URL', 'https://lcdporto.org/api/spaceapi' );
|
||||||
|
! defined( 'SSI_CACHE_KEY' ) && define( 'SSI_CACHE_KEY', 'ssi_space_api_status' );
|
||||||
|
! defined( 'SSI_CACHE_TTL' ) && define( 'SSI_CACHE_TTL', 10 ); // seconds
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Core - fetch & cache
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves space open status (boolean) with transient caching.
|
||||||
|
*
|
||||||
|
* Supported JSON payloads (any case):
|
||||||
|
* - true / false (bare boolean)
|
||||||
|
* - {"state": {"open": true}} (SpaceAPI standard)
|
||||||
|
*
|
||||||
|
* @return bool True if open, false if closed (or on error).
|
||||||
|
*/
|
||||||
|
function ssi_get_status() : bool {
|
||||||
|
$cached = get_transient( SSI_CACHE_KEY );
|
||||||
|
if ( false !== $cached ) {
|
||||||
|
return (bool) $cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get plugin data for dynamic user agent
|
||||||
|
$plugin_data = get_file_data( __FILE__, array(
|
||||||
|
'Version' => 'Version',
|
||||||
|
'TextDomain' => 'Text Domain'
|
||||||
|
), 'plugin' );
|
||||||
|
|
||||||
|
$response = wp_remote_get( SSI_API_URL, [
|
||||||
|
'timeout' => 3,
|
||||||
|
'user-agent' => $plugin_data['TextDomain'] . '/' . $plugin_data['Version'] . ' (+https://wordpress.org/)',
|
||||||
|
] );
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
set_transient( SSI_CACHE_KEY, false, SSI_CACHE_TTL );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$body = wp_remote_retrieve_body( $response );
|
||||||
|
$decoded = json_decode( $body, true );
|
||||||
|
$status = false; // default to closed
|
||||||
|
|
||||||
|
if ( is_bool( $decoded ) ) {
|
||||||
|
$status = $decoded;
|
||||||
|
} elseif ( is_array( $decoded ) ) {
|
||||||
|
// SpaceAPI standard format - state.open
|
||||||
|
if ( isset( $decoded['state']['open'] ) ) {
|
||||||
|
$status = (bool) $decoded['state']['open'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
set_transient( SSI_CACHE_KEY, $status, SSI_CACHE_TTL );
|
||||||
|
return $status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Shortcode [door_status]
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ssi_shortcode() : string {
|
||||||
|
$open = ssi_get_status();
|
||||||
|
$emoji = $open ? '<div class="space-status-indicator open">🟢 Open</div>' : '<div class="space-status-indicator closed">🔴 Closed</div>';
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<span class="space-status-indicator" aria-label="Space is %s">%s</span>',
|
||||||
|
$open ? 'open' : 'closed',
|
||||||
|
$emoji
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_shortcode( 'space_status', 'ssi_shortcode' );
|
||||||
|
// Keep the old shortcode for backward compatibility
|
||||||
|
add_shortcode( 'door_status', 'ssi_shortcode' );
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Admin Bar indicator
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
function ssi_admin_bar( WP_Admin_Bar $bar ) : void {
|
||||||
|
if ( ! current_user_can( 'read' ) ) {
|
||||||
|
return; // Logged-in users only.
|
||||||
|
}
|
||||||
|
|
||||||
|
$open = ssi_get_status();
|
||||||
|
$emoji = $open ? '🟢' : '🔴';
|
||||||
|
$text = $open ? __( 'Space Open', 'wp-spaceapi-consumer' ) : __( 'Space Closed', 'wp-spaceapi-consumer' );
|
||||||
|
|
||||||
|
$bar->add_node( [
|
||||||
|
'id' => 'space-status-indicator',
|
||||||
|
'title' => "$emoji $text",
|
||||||
|
'href' => '#',
|
||||||
|
'meta' => [ 'title' => $text ],
|
||||||
|
] );
|
||||||
|
}
|
||||||
|
add_action( 'admin_bar_menu', 'ssi_admin_bar', 1000 );
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Front-end inline CSS (kept minimal)
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Front-end + admin-bar styles for the indicator.
|
||||||
|
*/
|
||||||
|
function ssi_enqueue_assets() : void {
|
||||||
|
// register & enqueue the standalone CSS file
|
||||||
|
wp_enqueue_style(
|
||||||
|
'space-status-indicator',
|
||||||
|
plugins_url( 'wp-spaceapi-consumer-style.css', __FILE__ ),
|
||||||
|
[], // no dependencies
|
||||||
|
'1.0.0' // file version
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action( 'wp_enqueue_scripts', 'ssi_enqueue_assets' );
|
||||||
|
add_action( 'admin_enqueue_scripts', 'ssi_enqueue_assets' ); // so the Admin Bar icon also gets styled
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| WP-CLI command (optional)
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( defined( 'WP_CLI' ) && WP_CLI ) {
|
||||||
|
WP_CLI::add_command( 'space-status', function() {
|
||||||
|
WP_CLI::success( ssi_get_status() ? 'Space is open 🟢' : 'Space is closed 🔴' );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gutenberg block support (dynamic Space Status block)
|
||||||
|
if ( function_exists( 'register_block_type' ) ) {
|
||||||
|
require_once plugin_dir_path( __FILE__ ) . 'blocks-register.php';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// End of file
|
||||||
Reference in New Issue
Block a user