add_node( array( 'id' => 'baindesign-foobot', 'title' => esc_html( sprintf( '%s: %s%s', BD0019__ADMIN_BAR_DEVICE, number_format( $data['datapointTmp'], 1 ), $data['unitTmp'] ) ), 'href' => admin_url( 'options-general.php?page=aq-data-foobot' ), ) ); $rows = array( __( 'Temperature', 'aq-data-foobot' ) => number_format( $data['datapointTmp'], 1 ) . $data['unitTmp'], __( 'PM', 'aq-data-foobot' ) => round( $data['datapointPm'], 0 ) . ' µg/m3', __( 'CO2', 'aq-data-foobot' ) => round( $data['datapointCo2'], 0 ) . ' ' . $data['unitCo2'], __( 'VOC', 'aq-data-foobot' ) => round( $data['datapointVoc'], 0 ) . ' ' . $data['unitVoc'], __( 'Humidity', 'aq-data-foobot' ) => round( $data['datapointHum'], 1 ) . ' ' . $data['unitHum'], __( 'All', 'aq-data-foobot' ) => round( $data['datapointAllpollu'], 0 ) . ' ' . $data['unitAllpollu'], ); $details = '
'; foreach ( $rows as $label => $value ) { $details .= '
' . esc_html( $label ) . ': ' . esc_html( $value ) . '
'; } if ( ! empty( $data['timestamp'] ) ) { $details .= '
' . esc_html( sprintf( /* translators: %s: date/time the reading was received */ __( 'Updated %s', 'aq-data-foobot' ), bd324_get_local_datetime( $data['timestamp'] ) ) ) . '
'; } $details .= '
'; $wp_admin_bar->add_node( array( 'id' => 'baindesign-foobot-details', 'parent' => 'baindesign-foobot', 'title' => '', 'meta' => array( 'html' => $details ), ) ); } function baindesign_foobot_add_admin_menu() { add_options_page( 'Air Quality Data from Foobot', 'Foobot API', 'manage_options', 'aq-data-foobot', 'baindesign_foobot_options_page' ); } function baindesign_settings_link( $links ) { // Build and escape the URL. $url = esc_url( add_query_arg( 'page', 'aq-data-foobot', get_admin_url() . 'options-general.php' ) ); // Create the link. $settings_link = "" . __( 'Settings' ) . ''; // Adds the link to the end of the array. array_push( $links, $settings_link ); return $links; } add_filter( 'plugin_action_links_aq-data-foobot/aq-data-foobot.php', 'baindesign_settings_link' ); function baindesign_foobot_sanitize_settings( $input ) { $output = array(); $existing = get_option( BD0019__API_OPTIONS_NAME, array() ); // An empty submitted key means "keep the current key" (the field is // left blank/hidden in the UI so the stored key isn't shown on screen). if ( ! empty( $input[ BD0019__API_KEY_FIELD ] ) ) { $output[ BD0019__API_KEY_FIELD ] = sanitize_textarea_field( $input[ BD0019__API_KEY_FIELD ] ); } elseif ( ! empty( $existing[ BD0019__API_KEY_FIELD ] ) ) { $output[ BD0019__API_KEY_FIELD ] = $existing[ BD0019__API_KEY_FIELD ]; } if ( isset( $input[ BD0019__API_USER_FIELD ] ) ) { $output[ BD0019__API_USER_FIELD ] = sanitize_text_field( $input[ BD0019__API_USER_FIELD ] ); } $output[ BD0019__ADMIN_BAR_ENABLED_FIELD ] = ! empty( $input[ BD0019__ADMIN_BAR_ENABLED_FIELD ] ) ? 1 : 0; if ( isset( $input[ BD0019__ADMIN_BAR_DEVICE_FIELD ] ) ) { $output[ BD0019__ADMIN_BAR_DEVICE_FIELD ] = sanitize_text_field( $input[ BD0019__ADMIN_BAR_DEVICE_FIELD ] ); } return $output; } function baindesign_foobot_settings_init() { // Register register_setting( 'baindesignFoobot', // New options group BD0019__API_OPTIONS_NAME, array( 'type' => 'array', 'sanitize_callback' => 'baindesign_foobot_sanitize_settings', 'default' => array(), ) ); add_settings_section( 'baindesign-foobot-api-creds', // Section ID __( 'Foobot API Credentials', 'aq-data-foobot' ), // Section header 'baindesign_foobot_settings_section_callback', // Callback 'baindesignFoobot' // Add section to // options group ); // API Key add_settings_field( BD0019__API_KEY_FIELD, // ID __( 'API Key', 'aq-data-foobot' ), // Label BD0019__API_KEY_FIELD . '_field_render', // Function to display // inputs 'baindesignFoobot', // Page to display on 'baindesign-foobot-api-creds' // Section ID ); // API username add_settings_field( BD0019__API_USER_FIELD, // ID __( 'API User', 'aq-data-foobot' ), // Label BD0019__API_USER_FIELD . '_field_render', // Function to // display inputs 'baindesignFoobot', // Page to display on 'baindesign-foobot-api-creds' // Section ID ); add_settings_section( 'baindesign-foobot-admin-bar', // Section ID __( 'Admin Bar', 'aq-data-foobot' ), // Section header 'baindesign_foobot_admin_bar_section_callback', // Callback 'baindesignFoobot' // Add section to // options group ); // Show in admin bar add_settings_field( BD0019__ADMIN_BAR_ENABLED_FIELD, __( 'Show in Admin Bar', 'aq-data-foobot' ), BD0019__ADMIN_BAR_ENABLED_FIELD . '_field_render', 'baindesignFoobot', 'baindesign-foobot-admin-bar' ); // Which device to show add_settings_field( BD0019__ADMIN_BAR_DEVICE_FIELD, __( 'Device', 'aq-data-foobot' ), BD0019__ADMIN_BAR_DEVICE_FIELD . '_field_render', 'baindesignFoobot', 'baindesign-foobot-admin-bar' ); } function baindesign_foobot_api_user_field_render() { ?> ' value=''>

api.foobot.io.', 'aq-data-foobot' ); } function baindesign_foobot_admin_bar_section_callback() { esc_html_e( 'Optionally show a device\'s latest reading in the WordPress admin bar.', 'aq-data-foobot' ); } function baindesign_foobot_admin_bar_enabled_field_render() { ?> false, 'message' => __( 'Please save your API key and API user above before testing the connection.', 'aq-data-foobot' ), ); } $result = bd_foobot_call_api_devices(); if ( is_array( $result ) && isset( $result['state'] ) ) { return array( 'success' => false, 'message' => sprintf( /* translators: %d: HTTP status code returned by the Foobot API */ __( 'Connection failed: the Foobot API returned an error (status %d). Double-check your API key and API user email.', 'aq-data-foobot' ), (int) $result['state'] ), ); } if ( is_array( $result ) ) { return array( 'success' => true, 'message' => sprintf( /* translators: %d: number of devices found */ _n( 'Connection successful: found %d device.', 'Connection successful: found %d devices.', count( $result ), 'aq-data-foobot' ), count( $result ) ), ); } return array( 'success' => false, 'message' => __( 'Connection failed: no response from the Foobot API.', 'aq-data-foobot' ), ); } /** * Get a human-readable "last data received" string, or a fallback message. */ function baindesign_foobot_get_last_received_text() { $data = bd_foobot_fetch_latest_sensor_data(); if ( empty( $data['timestamp'] ) ) { return __( 'No data received yet.', 'aq-data-foobot' ); } return sprintf( /* translators: %s: date/time the most recent sensor reading was received */ __( 'Last data received: %s', 'aq-data-foobot' ), bd324_get_local_datetime( $data['timestamp'] ) ); } /** * Render the list of devices found on the account */ function baindesign_foobot_render_devices_list() { if ( ! BD0019__API_KEY || ! BD0019__API_USER ) { echo '

' . esc_html__( 'Save your API credentials above to see the devices found on your Foobot account.', 'aq-data-foobot' ) . '

'; return; } $devices = bd_foobot_fetch_db_devices(); if ( empty( $devices ) ) { echo '

' . esc_html__( 'No devices found on this Foobot account.', 'aq-data-foobot' ) . '

'; return; } ?>
[foobot-show-data device=""]