Skip to content

Commit

Permalink
Simplify Schedule Criteria (#2861)
Browse files Browse the repository at this point in the history
  • Loading branch information
nadzpogi authored Jan 17, 2025
1 parent 2381de8 commit c276e75
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 52 deletions.
112 changes: 60 additions & 52 deletions lib/Connector/CapConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,19 @@
use Psr\Container\ContainerInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Xibo\Connector\ConnectorInterface;
use Xibo\Connector\ConnectorTrait;
use Xibo\Event\ScheduleCriteriaRequestEvent;
use Xibo\Event\ScheduleCriteriaRequestInterface;
use Xibo\Event\WidgetDataRequestEvent;
use Xibo\Factory\DisplayFactory;
use Xibo\Support\Exception\ConfigurationException;
use Xibo\Support\Exception\GeneralException;
use Xibo\Support\Sanitizer\SanitizerInterface;
use Xibo\Widget\Provider\DataProviderInterface;
use Xibo\XMR\ScheduleCriteriaUpdateAction;

/**
* A connector to process Common Alert Protocol (CAP) Data
*/
class CapConnector implements ConnectorInterface
class CapConnector implements ConnectorInterface, EmergencyAlertInterface
{
use ConnectorTrait;

Expand Down Expand Up @@ -134,26 +131,54 @@ public function onDataRequest(WidgetDataRequestEvent $event): void
return;
}

// Process and initialize CAP data
$this->processCapData($event->getDataProvider());
// Set cache expiry date to 3 minutes from now
$cacheExpire = Carbon::now()->addMinutes(3);

// Initialize update interval
$updateIntervalMinute = $event->getDataProvider()->getProperty('updateInterval');
// Fetch the CAP XML content from the given URL
$xmlContent = $this->fetchCapAlertFromUrl($event->getDataProvider(), $cacheExpire);

// Convert the $updateIntervalMinute to seconds
$updateInterval = $updateIntervalMinute * 60;
if ($xmlContent) {
// Initialize DOMDocument and load the XML content
$this->capXML = new DOMDocument();
$this->capXML->loadXML($xmlContent);

// If we've got data, then set our cache period.
$event->getDataProvider()->setCacheTtl($updateInterval);
$event->getDataProvider()->setIsHandled();
// Process and initialize CAP data
$this->processCapData($event->getDataProvider());

// Initialize update interval
$updateIntervalMinute = $event->getDataProvider()->getProperty('updateInterval');

// Convert the $updateIntervalMinute to seconds
$updateInterval = $updateIntervalMinute * 60;

// If we've got data, then set our cache period.
$event->getDataProvider()->setCacheTtl($updateInterval);
$event->getDataProvider()->setIsHandled();

$capStatus = $this->getCapXmlData('status');
$category = $this->getCapXmlData('category');
} else {
$capStatus = 'No Alerts';
$category = '';
}

// initialize status for schedule criteria push message
if ($capStatus == 'Actual') {
$status = self::ACTUAL_ALERT;
} elseif ($capStatus == 'No Alerts') {
$status = self::NO_ALERT;
} else {
$status = self::TEST_ALERT;
}

$this->getLogger()->debug('Schedule criteria push message: status = ' . $status
. ', category = ' . $category);

// Set schedule criteria update
$action = new ScheduleCriteriaUpdateAction();
$action->setCriteriaUpdates([
'isEmergencyAlertActive' => 1,
'status' => $this->getCapXmlData('status'),
'msgType' => $this->getCapXmlData('msgType'),
'scope' => $this->getCapXmlData('scope')
'emergency_alert_status' => $status,
'emergency_alert_category' => $category,
]);

// Initialize the display
Expand All @@ -173,7 +198,6 @@ public function onDataRequest(WidgetDataRequestEvent $event): void
/**
* Get and process the CAP data
*
* @throws GuzzleException
* @throws Exception
*/
private function processCapData(DataProviderInterface $dataProvider): void
Expand All @@ -192,16 +216,6 @@ private function processCapData(DataProviderInterface $dataProvider): void
$config['certainty'] = $dataProvider->getProperty('certainty');
$config['isAreaSpecific'] = $dataProvider->getProperty('isAreaSpecific');

// Set cache expiry date to 3 minutes from now
$cacheExpire = Carbon::now()->addMinutes(3);

// Fetch the CAP XML content from the given URL
$xmlContent = $this->fetchCapAlertFromUrl($dataProvider, $cacheExpire);

// Initialize DOMDocument and load the XML content
$this->capXML = new DOMDocument();
$this->capXML->loadXML($xmlContent);

// Retrieve specific values from the CAP XML for filtering
$status = $this->getCapXmlData('status');
$msgType = $this->getCapXmlData('msgType');
Expand Down Expand Up @@ -301,10 +315,10 @@ private function processCapData(DataProviderInterface $dataProvider): void
* @param DataProviderInterface $dataProvider
* @param Carbon $cacheExpiresAt
*
* @return string
* @return string|null
* @throws GuzzleException
*/
private function fetchCapAlertFromUrl(DataProviderInterface $dataProvider, Carbon $cacheExpiresAt): string
private function fetchCapAlertFromUrl(DataProviderInterface $dataProvider, Carbon $cacheExpiresAt): string|null
{
$emergencyAlertUrl = $dataProvider->getProperty('emergencyAlertUri');

Expand Down Expand Up @@ -517,32 +531,26 @@ public function onScheduleCriteriaRequest(ScheduleCriteriaRequestInterface $even
{
// Initialize Emergency Alerts schedule criteria parameters
$event->addType('emergency_alerts', __('Emergency Alerts'))
->addMetric('isEmergencyAlertActive', __('Is emergency alert active?'))
->addValues('dropdown', [
'1' => __('Yes'),
'0' => __('No'),
])
->addMetric('emergency_alert_status', __('Status'))
->addValues('dropdown', [
'Actual' => __('Actual'),
'Exercise' => __('Exercise'),
'System' => __('System'),
'Test' => __('Test'),
'Draft' => __('Draft')
])
->addMetric('msgType', __('Message Type'))
->addValues('dropdown', [
'Alert' => __('Alert'),
'Update' => __('Update'),
'Cancel' => __('Cancel'),
'Ack' => __('Ack'),
'Error' => __('Error')
self::ACTUAL_ALERT => __('Actual Alerts'),
self::TEST_ALERT => __('Test Alerts'),
self::NO_ALERT => __('No Alerts')
])
->addMetric('scope', __('Scope'))
->addMetric('emergency_alert_category', __('Category'))
->addValues('dropdown', [
'Public' => __('Public'),
'Restricted' => __('Restricted'),
'Private' => __('Private')
'Geo' => __('Geo'),
'Met' => __('Met'),
'Safety' => __('Safety'),
'Security' => __('Security'),
'Rescue' => __('Rescue'),
'Fire' => __('Fire'),
'Health' => __('Health'),
'Env' => __('Env'),
'Transport' => __('Transport'),
'Infra' => __('Infra'),
'CBRNE' => __('CBRNE'),
'Other' => __('Other'),
]);
}
}
45 changes: 45 additions & 0 deletions lib/Connector/EmergencyAlertInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/*
* Copyright (C) 2025 Xibo Signage Ltd
*
* Xibo - Digital Signage - http://www.xibo.org.uk
*
* This file is part of Xibo.
*
* Xibo is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* Xibo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Xibo. If not, see <http://www.gnu.org/licenses/>.
*/

namespace Xibo\Connector;

/**
* Connector Interface for Emergency Alerts
*/
interface EmergencyAlertInterface
{
/**
* Represents the status when there is at least one alert of type "Actual".
*/
public const ACTUAL_ALERT = 'actual_alerts';

/**
* Represents the status when there are no alerts of any type.
*/
public const NO_ALERT = 'no_alerts';

/**
* Represents the status when there is at least one test alert
* (e.g., Exercise, System, Test, Draft).
*/
public const TEST_ALERT = 'test_alerts';
}

0 comments on commit c276e75

Please sign in to comment.