'ha-lights', * 'label' => __( 'Home Assistant: Lights', 'home-assistant' ), * 'description' => __( 'Toggle smart lights from the palette.', 'home-assistant' ), * 'icon' => 'dashicons-lightbulb', * 'hint' => '[room]', * 'script' => 'home-assistant-commands', * ) ); * ``` * * Implicitly registers the `script` handle via * `openstation_register_command_script()` when provided, so plugins using * this API don't need to call both functions. * * @param array $args { * @type string $slug Slash-command slug (without leading `/`). Required. * @type string $label Human-readable label. Required. * @type string $description Subtitle shown in the palette. Default empty. * @type string $icon Dashicons class. Default `dashicons-arrow-right-alt`. * @type string $hint Argument hint rendered next to the slug. Default empty. * @type string $script WP script handle providing the `run` function. * Registered via `openstation_register_command_script()` * when present. Default empty (advisory registration only). * } * @return true|WP_Error `true` on success; `WP_Error` on validation failure. */ function openstation_register_command( $args = array() ) { $defaults = array( 'slug' => '', 'label' => '', 'description' => '', 'icon' => 'dashicons-arrow-right-alt', 'hint' => '', 'script' => '', ); $args = wp_parse_args( $args, $defaults ); $slug = (string) $args['slug']; if ( '' === $slug ) { return openstation_registration_error( 'openstation_missing_slug', __( 'Command registration requires a non-empty `slug`.', 'desktop-mode' ) ); } if ( '' === (string) $args['label'] ) { return openstation_registration_error( 'openstation_missing_label', __( 'Command registration requires a non-empty `label`.', 'desktop-mode' ), array( 'slug' => $slug ) ); } $entry = array( 'slug' => $slug, 'label' => (string) $args['label'], 'description' => (string) $args['description'], 'icon' => (string) $args['icon'], 'hint' => (string) $args['hint'], 'script' => (string) $args['script'], ); openstation_desktop_command_registry( $slug, $entry ); if ( '' !== $entry['script'] ) { openstation_register_command_script( $entry['script'] ); } /** * Fires after a desktop command is successfully registered. * * @param string $slug The command slug. * @param array $entry The stored registry entry. */ do_action( 'openstation_command_registered', $slug, $entry ); return true; } /** * Internal module-level registry for command script handles declared * via {@see openstation_register_command_script()}. Accessed by both the * registration API (write) and the payload builder (read). * * @internal * * @param string $handle Script handle to read or write. * @param bool|null $value Pass `true` to register; `null` to read only. * @return array|bool When called with no args returns the full store. */ function openstation_desktop_command_script_registry( $handle = '', $value = null ) { static $store = array(); if ( '__flush__' === (string) $handle ) { $store = array(); return array(); } if ( '' === (string) $handle ) { return $store; } if ( null !== $value ) { $store[ (string) $handle ] = (bool) $value; } return isset( $store[ (string) $handle ] ) ? $store[ (string) $handle ] : false; } /** * Flush the command-script registry. Tests call this in `set_up` so * a previous test's stale handle doesn't leak into the next test's * payload-build assertions. No production caller. */ function openstation_flush_desktop_command_script_registry() { openstation_desktop_command_script_registry( '__flush__' ); } /** * Internal module-level registry for commands declared via * {@see openstation_register_command()}. * * @internal * * @param string $slug Slug to read or write. * @param array|null $entry Entry to store, or `null` to read. * @return array|null */ function openstation_desktop_command_registry( $slug = '', $entry = null ) { static $store = array(); if ( '' === (string) $slug ) { return $store; } if ( null !== $entry ) { $store[ (string) $slug ] = $entry; } return isset( $store[ (string) $slug ] ) ? $store[ (string) $slug ] : null; } /** * Build the script-handle payload fed to the shell. Resolves each * registered handle to a full payload via {@see openstation_resolve_script_payload()}; * handles that aren't currently enqueued (plugin not active this request) * resolve to an empty URL and are dropped. The harvested `extra` data * (localize / inline / translations) ships alongside the URL so the * shell's lazy `