Skip to content
McStay Designs

Wordpress tech Development

McStay Designs

Wordpress tech Development

  • Network benchmark
  • Get a Quote
  • Free code Projects
  • Free plugins
  • About
  • Network benchmark
  • Get a Quote
  • Free code Projects
  • Free plugins
  • About
McStay Designs

Wordpress tech Development

McStay Designs

Wordpress tech Development

  • Network benchmark
  • Get a Quote
  • Free code Projects
  • Free plugins
  • About
  • Network benchmark
  • Get a Quote
  • Free code Projects
  • Free plugins
  • About
Home/Free code Projects/Automated New England Amber Alert Banner
Free code Projects

Automated New England Amber Alert Banner

By mkmcst
September 3, 2026 6 Min Read
0

/**
 * Plugin Name: Automated New England Amber Alert Banner
 * Description: Automatically polls official RSS feeds and emergency bulletins across New England, displaying a high-priority sticky broadcast banner on active alerts.
 * Version: 2.0.0
 * Author: Michael McStay Designs
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

class NE_Automated_Amber_Alert {

    private $transient_key = 'ne_amber_feed_cache';
    private $cache_duration = 300; // Cache check every 5 minutes

    public function __construct() {
        add_action( 'wp_head', [ $this, 'render_banner_styles' ] );
        add_action( 'wp_footer', [ $this, 'render_banner_html' ] );
        add_action( 'admin_menu', [ $this, 'register_admin_menu' ] );
        add_action( 'admin_init', [ $this, 'register_settings' ] );
    }

    /**
     * Register Settings in WordPress Admin
     */
    public function register_settings() {
        register_setting( 'ne_auto_amber_group', 'ne_amber_auto_mode' );
        register_setting( 'ne_auto_amber_group', 'ne_amber_manual_override' );
        register_setting( 'ne_auto_amber_group', 'ne_amber_manual_headline' );
        register_setting( 'ne_auto_amber_group', 'ne_amber_manual_details' );
        register_setting( 'ne_auto_amber_group', 'ne_amber_manual_state' );
        register_setting( 'ne_auto_amber_group', 'ne_amber_manual_link' );
    }

    /**
     * Add Settings Page to Dashboard
     */
    public function register_admin_menu() {
        add_options_page(
            'Auto Amber Alerts',
            'Auto Amber Alerts',
            'manage_options',
            'ne-auto-amber',
            [ $this, 'render_admin_page' ]
        );
    }

    /**
     * Admin Dashboard UI
     */
    public function render_admin_page() {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }

        $feed_data = $this->fetch_new_england_alerts();
        ?>
        <div class="wrap">
            <h1>New England Automated Amber Alert Feed & Controls</h1>
            
            <div class="card" style="max-width: 100%; margin-top: 20px; padding: 15px; background: #fff; border-left: 4px solid <?php echo !empty($feed_data) ? '#b30000' : '#46b450'; ?>;">
                <h3>Live Feed Status: <?php echo !empty($feed_data) ? 'ACTIVE ALERT DETECTED' : 'No Active Alerts Found in Regional Feed'; ?></h3>
                <?php if (!empty($feed_data)) : ?>
                    <p><strong>Headline:</strong> <?php echo esc_html($feed_data['headline']); ?></p>
                    <p><strong>State:</strong> <?php echo esc_html($feed_data['state']); ?></p>
                    <p><strong>Details:</strong> <?php echo esc_html($feed_data['details']); ?></p>
                <?php else: ?>
                    <p>Monitoring RSS feeds for Massachusetts, Rhode Island, Connecticut, New Hampshire, Vermont, and Maine...</p>
                <?php endif; ?>
            </div>

            <form method="post" action="options.php" style="margin-top: 20px;">
                <?php settings_fields( 'ne_auto_amber_group' ); ?>
                <?php do_settings_sections( 'ne_auto_amber_group' ); ?>
                
                <table class="form-table">
                    <tr valign="top">
                        <th scope="row">Operation Mode</th>
                        <td>
                            <label>
                                <input type="checkbox" name="ne_amber_auto_mode" value="1" <?php checked( 1, get_option( 'ne_amber_auto_mode', 1 ), true ); ?> />
                                Enable Fully Automated RSS Feed Polling
                            </label>
                            <p class="description">When enabled, the banner triggers automatically when state/federal feeds push a missing child / amber alert for New England.</p>
                        </td>
                    </tr>
                    
                    <tr valign="top">
                        <th scope="row">Manual Override / Emergency Broadcast</th>
                        <td>
                            <label>
                                <input type="checkbox" name="ne_amber_manual_override" value="1" <?php checked( 1, get_option( 'ne_amber_manual_override' ), true ); ?> />
                                Force Manual Alert Override (Bypasses RSS feed)
                            </label>
                        </td>
                    </tr>

                    <tr valign="top">
                        <th scope="row">Manual Target State</th>
                        <td>
                            <select name="ne_amber_manual_state">
                                <?php 
                                $current_state = get_option( 'ne_amber_manual_state', 'All New England' ); 
                                $states = [ 'All New England', 'Massachusetts', 'Connecticut', 'Rhode Island', 'New Hampshire', 'Vermont', 'Maine' ];
                                foreach ( $states as $st ) {
                                    echo '<option value="' . esc_attr( $st ) . '" ' . selected( $current_state, $st, false ) . '>' . esc_html( $st ) . '</option>';
                                }
                                ?>
                            </select>
                        </td>
                    </tr>
                     
                    <tr valign="top">
                        <th scope="row">Manual Headline</th>
                        <td>
                            <input type="text" name="ne_amber_manual_headline" value="<?php echo esc_attr( get_option( 'ne_amber_manual_headline', 'EMERGENCY AMBER ALERT' ) ); ?>" style="width: 100%;" />
                        </td>
                    </tr>
                     
                    <tr valign="top">
                        <th scope="row">Manual Details</th>
                        <td>
                            <textarea name="ne_amber_manual_details" rows="3" style="width: 100%;"><?php echo esc_textarea( get_option( 'ne_amber_manual_details', '' ) ); ?></textarea>
                        </td>
                    </tr>

                    <tr valign="top">
                        <th scope="row">Official Link</th>
                        <td>
                            <input type="text" name="ne_amber_manual_link" value="<?php echo esc_attr( get_option( 'ne_amber_manual_link', '' ) ); ?>" style="width: 100%;" placeholder="https://..." />
                        </td>
                    </tr>
                </table>
                <?php submit_button(); ?>
            </form>
        </div>
        <?php
    }

    /**
     * Fetch and Parse Public RSS/XML Alert Data for New England
     */
    private function fetch_new_england_alerts() {
        // Check transient cache first
        $cached = get_transient( $this->transient_key );
        if ( false !== $cached ) {
            return $cached;
        }

        // Public RSS endpoints aggregating missing person / emergency data
        $feed_urls = [
            'https://www.missingkids.org/content/dam/missingkids/getinvolved/rss/amber-alert.xml', // National fallback / official feed
        ];

        $alert_data = [];

        foreach ( $feed_urls as $url ) {
            $rss = fetch_feed( $url );
            if ( is_wp_error( $rss ) ) {
                continue;
            }

            $max_items = $rss->get_item_quantity( 5 );
            $rss_items = $rss->get_items( 0, $max_items );

            foreach ( $rss_items as $item ) {
                $title       = $item->get_title();
                $description = strip_tags( $item->get_description() );
                $content     = $title . ' ' . $description;
                
                // Scan content for New England states or keywords
                $ne_states = [ 'Massachusetts', 'MA', 'Connecticut', 'CT', 'Rhode Island', 'RI', 'New Hampshire', 'NH', 'Vermont', 'VT', 'Maine', 'ME' ];
                $matched_state = '';

                foreach ( $ne_states as $st ) {
                    if ( stripos( $content, $st ) !== false ) {
                        $matched_state = $st;
                        break;
                    }
                }

                // If an active alert matches New England region
                if ( ! empty( $matched_state ) || stripos( $content, 'AMBER ALERT' ) !== false ) {
                    $alert_data = [
                        'headline' => 'EMERGENCY AMBER ALERT: ' . sanitize_text_field( $title ),
                        'details'  => sanitize_text_field( wp_trim_words( $description, 35, '...' ) ),
                        'state'    => 'New England Region',
                        'link'     => esc_url( $item->get_permalink() )
                    ];
                    break 2;
                }
            }
        }

        // Save to transient cache to prevent server slowdowns
        set_transient( $this->transient_key, $alert_data, $this->cache_duration );

        return $alert_data;
    }

    /**
     * Get Current Active Alert Payload (Manual or Automated)
     */
    public function get_active_alert() {
        // Check manual override first
        if ( get_option( 'ne_amber_manual_override' ) ) {
            return [
                'active'   => true,
                'headline' => get_option( 'ne_amber_manual_headline', 'EMERGENCY AMBER ALERT' ),
                'details'  => get_option( 'ne_amber_manual_details', '' ),
                'state'    => get_option( 'ne_amber_manual_state', 'All New England' ),
                'link'     => get_option( 'ne_amber_manual_link', '' ),
            ];
        }

        // Check automated feed mode
        if ( get_option( 'ne_amber_auto_mode', 1 ) ) {
            $feed_alert = $this->fetch_new_england_alerts();
            if ( ! empty( $feed_alert ) ) {
                $feed_alert['active'] = true;
                return $feed_alert;
            }
        }

        return [ 'active' => false ];
    }

    /**
     * Render Emergency Styles
     */
    public function render_banner_styles() {
        $alert = $this->get_active_alert();
        if ( empty( $alert['active'] ) ) {
            return;
        }
        ?>
        <style>
            #ne-amber-emergency-banner {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                background-color: #b30000;
                color: #ffffff;
                z-index: 999999;
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
                box-shadow: 0 4px 12px rgba(0,0,0,0.5);
                border-bottom: 3px solid #ffcc00;
                box-sizing: border-box;
                animation: ne-flash-border 1.5s infinite;
            }
            @keyframes ne-flash-border {
                0% { border-bottom-color: #ffcc00; }
                50% { border-bottom-color: #b30000; }
                100% { border-bottom-color: #ffcc00; }
            }
            .ne-amber-container {
                max-width: 1200px;
                margin: 0 auto;
                padding: 12px 20px;
                display: flex;
                flex-wrap: wrap;
                align-items: center;
                justify-content: space-between;
            }
            .ne-amber-content {
                display: flex;
                align-items: center;
                gap: 15px;
                flex: 1;
            }
            .ne-amber-badge {
                background: #ffcc00;
                color: #111111;
                font-weight: 800;
                padding: 4px 10px;
                font-size: 12px;
                letter-spacing: 1px;
                text-transform: uppercase;
                border-radius: 3px;
            }
            .ne-amber-text h4 {
                margin: 0 0 2px 0;
                font-size: 15px;
                color: #ffffff;
                font-weight: 700;
            }
            .ne-amber-text p {
                margin: 0;
                font-size: 13px;
                color: #fce8e6;
                line-height: 1.4;
            }
            .ne-amber-text a {
                color: #ffcc00;
                text-decoration: underline;
                margin-left: 8px;
                font-weight: 600;
            }
            .ne-amber-actions {
                display: flex;
                align-items: center;
                gap: 10px;
            }
            .ne-amber-dismiss {
                background: transparent;
                border: 1px solid #ffffff;
                color: #ffffff;
                padding: 6px 12px;
                font-size: 12px;
                cursor: pointer;
                border-radius: 3px;
                font-weight: 600;
                transition: background 0.2s;
            }
            .ne-amber-dismiss:hover {
                background: rgba(255,255,255,0.2);
            }
            body.has-ne-amber-banner {
                padding-top: 55px !important;
            }
            @media(max-width: 768px) {
                .ne-amber-container {
                    flex-direction: column;
                    align-items: flex-start;
                    gap: 10px;
                }
                .ne-amber-actions {
                    width: 100%;
                    justify-content: flex-end;
                }
                body.has-ne-amber-banner {
                    padding-top: 95px !important;
                }
            }
        </style>
        <?php
    }

    /**
     * Render Banner HTML & Dismissal Script
     */
    public function render_banner_html() {
        $alert = $this->get_active_alert();
        if ( empty( $alert['active'] ) ) {
            return;
        }

        if ( isset( $_COOKIE['ne_amber_dismissed'] ) && $_COOKIE['ne_amber_dismissed'] === '1' ) {
            return;
        }
        ?>
        <div id="ne-amber-emergency-banner" role="region" aria-label="Emergency Amber Alert">
            <div class="ne-amber-container">
                <div class="ne-amber-content">
                    <span class="ne-amber-badge"><?php echo esc_html( $alert['state'] ); ?></span>
                    <div class="ne-amber-text">
                        <h4><?php echo esc_html( $alert['headline'] ); ?></h4>
                        <p>
                            <?php echo esc_html( $alert['details'] ); ?>
                            <?php if ( ! empty( $alert['link'] ) ) : ?>
                                <a href="<?php echo esc_url( $alert['link'] ); ?>" target="_blank" rel="noopener">Official Bulletin &raquo;</a>
                            <?php endif; ?>
                        </p>
                    </div>
                </div>
                <div class="ne-amber-actions">
                    <button class="ne-amber-dismiss" id="ne-dismiss-btn">Dismiss</button>
                </div>
            </div>
        </div>

        <script>
            document.addEventListener('DOMContentLoaded', function() {
                document.body.classList.add('has-ne-amber-banner');
                
                const dismissBtn = document.getElementById('ne-dismiss-btn');
                if (dismissBtn) {
                    dismissBtn.addEventListener('click', function() {
                        const banner = document.getElementById('ne-amber-emergency-banner');
                        if (banner) {
                            banner.style.display = 'none';
                            document.body.classList.remove('has-ne-amber-banner');
                            
                            const d = new Date();
                            d.setTime(d.getTime() + (4 * 60 * 60 * 1000));
                            document.cookie = "ne_amber_dismissed=1; expires=" + d.toUTCString() + "; path=/";
                        }
                    });
                }
            });
        </script>
        <?php
    }
}

new NE_Automated_Amber_Alert();
Author

mkmcst

test test test

Follow Me
Other Articles
Previous

Secure Snippet Manager Pro

Next

bot tacker

No Comment! Be the first one.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Legal

  • Terms of Service
  • Privacy Policy
Copyright 2026 — McStay Designs. All rights reserved.McStay Media
🚀 Upgrade Your Site: 20% Off Custom WordPress Plugins, Security Cleanup & Performance Tuning!Get a Free Quote →