Add AlarmedZoned to filters, work on fixing filter behaviour in js. Enable viewing filter results in montagereview

This commit is contained in:
Isaac Connor 2019-12-18 19:06:10 -05:00
parent d21fa5c48a
commit e39a95d761
8 changed files with 97 additions and 27 deletions

View File

@ -1094,6 +1094,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&') {
for ( $i = 0; $i < count($terms); $i++ ) { for ( $i = 0; $i < count($terms); $i++ ) {
$term = $terms[$i]; $term = $terms[$i];
ZM\Logger::Debug("Term: " . print_r($term,true));
if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) { if ( isset($term['cnj']) && array_key_exists($term['cnj'], $validQueryConjunctionTypes) ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']); $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cnj]").'='.urlencode($term['cnj']);
@ -1109,6 +1110,12 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']); $filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][attr]").'='.urlencode($term['attr']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][attr]\" value=\"".htmlspecialchars($term['attr'])."\"/>\n"; $filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][attr]\" value=\"".htmlspecialchars($term['attr'])."\"/>\n";
switch ( $term['attr'] ) { switch ( $term['attr'] ) {
case 'AlarmedZoneId':
if ( $term['op'] != 'IN' ) {
ZM\Warning("AlarmedZoneId only supports the IN operator");
}
$filter['sql'] .= $term['val'];
break;
case 'MonitorName': case 'MonitorName':
$filter['sql'] .= 'M.Name'; $filter['sql'] .= 'M.Name';
break; break;
@ -1226,6 +1233,10 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$valueList = array(); $valueList = array();
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) { foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
switch ( $term['attr'] ) { switch ( $term['attr'] ) {
case 'AlarmedZoneId':
$value = '(SELECT DISTINCT ZoneId FROM Stats WHERE EventId=E.Id)';
break;
case 'MonitorName': case 'MonitorName':
case 'Name': case 'Name':
case 'Cause': case 'Cause':

View File

@ -34,7 +34,7 @@ if ( version_compare(phpversion(), '4.1.0', '<') ) {
} }
// Useful debugging lines for mobile devices // Useful debugging lines for mobile devices
if ( false ) { if ( true ) {
ob_start(); ob_start();
phpinfo(INFO_VARIABLES); phpinfo(INFO_VARIABLES);
$fp = fopen('/tmp/env.html', 'w+'); $fp = fopen('/tmp/env.html', 'w+');
@ -71,7 +71,7 @@ define('ZM_BASE_URL', '');
require_once('includes/functions.php'); require_once('includes/functions.php');
if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) { if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
ZM\Logger::Debug("OPTIONS Method, only doing CORS"); ZM\Logger::Debug('OPTIONS Method, only doing CORS');
# Add Cross domain access headers # Add Cross domain access headers
CORSHeaders(); CORSHeaders();
return; return;

View File

@ -116,6 +116,7 @@ $SLANG = array(
'Area' => 'Area', 'Area' => 'Area',
'AreaUnits' => 'Area (px/%)', 'AreaUnits' => 'Area (px/%)',
'AttrAlarmFrames' => 'Alarm Frames', 'AttrAlarmFrames' => 'Alarm Frames',
'AttrAlarmedZone' => 'Alarmed Zone',
'AttrArchiveStatus' => 'Archive Status', 'AttrArchiveStatus' => 'Archive Status',
'AttrAvgScore' => 'Avg. Score', 'AttrAvgScore' => 'Avg. Score',
'AttrCause' => 'Cause', 'AttrCause' => 'Cause',

View File

@ -1,6 +1,6 @@
<?php <?php
// //
// ZoneMinder web filter view file, $Date$, $Revision$ // ZoneMinder web filter view file
// Copyright (C) 2001-2008 Philip Coombes // Copyright (C) 2001-2008 Philip Coombes
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
@ -25,6 +25,8 @@ if ( !canView('Events') ) {
require_once('includes/Object.php'); require_once('includes/Object.php');
require_once('includes/Storage.php'); require_once('includes/Storage.php');
require_once('includes/Filter.php'); require_once('includes/Filter.php');
require_once('includes/Monitor.php');
require_once('includes/Zone.php');
parseSort(); parseSort();
$filterNames = array(''=>translate('ChooseFilter')); $filterNames = array(''=>translate('ChooseFilter'));
@ -69,6 +71,7 @@ if ( count($terms) ) {
$attrTypes = array( $attrTypes = array(
'AlarmFrames' => translate('AttrAlarmFrames'), 'AlarmFrames' => translate('AttrAlarmFrames'),
'AlarmedZoneId' => translate('AttrAlarmedZone'),
'Archived' => translate('AttrArchiveStatus'), 'Archived' => translate('AttrArchiveStatus'),
'AvgScore' => translate('AttrAvgScore'), 'AvgScore' => translate('AttrAvgScore'),
'Cause' => translate('AttrCause'), 'Cause' => translate('AttrCause'),
@ -78,17 +81,17 @@ $attrTypes = array(
'EndDateTime' => translate('AttrEndDateTime'), 'EndDateTime' => translate('AttrEndDateTime'),
'EndDate' => translate('AttrEndDate'), 'EndDate' => translate('AttrEndDate'),
'EndTime' => translate('AttrEndTime'), 'EndTime' => translate('AttrEndTime'),
'EndWeekday' => translate('AttrEndWeekday'),
'FilterServerId' => translate('AttrFilterServer'), 'FilterServerId' => translate('AttrFilterServer'),
'Frames' => translate('AttrFrames'), 'Frames' => translate('AttrFrames'),
'EndWeekday' => translate('AttrEndWeekday'),
'Id' => translate('AttrId'), 'Id' => translate('AttrId'),
'Length' => translate('AttrDuration'), 'Length' => translate('AttrDuration'),
'Name' => translate('AttrName'),
'Notes' => translate('AttrNotes'),
'MaxScore' => translate('AttrMaxScore'), 'MaxScore' => translate('AttrMaxScore'),
'MonitorId' => translate('AttrMonitorId'), 'MonitorId' => translate('AttrMonitorId'),
'MonitorName' => translate('AttrMonitorName'), 'MonitorName' => translate('AttrMonitorName'),
'MonitorServerId' => translate('AttrMonitorServer'), 'MonitorServerId' => translate('AttrMonitorServer'),
'Name' => translate('AttrName'),
'Notes' => translate('AttrNotes'),
'SecondaryStorageId' => translate('AttrSecondaryStorageArea'), 'SecondaryStorageId' => translate('AttrSecondaryStorageArea'),
'ServerId' => translate('AttrMonitorServer'), 'ServerId' => translate('AttrMonitorServer'),
'StartDateTime' => translate('AttrStartDateTime'), 'StartDateTime' => translate('AttrStartDateTime'),
@ -143,9 +146,18 @@ foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Servers` ORDER BY lower(`Name`)
$servers[$server['Id']] = validHtmlStr($server['Name']); $servers[$server['Id']] = validHtmlStr($server['Name']);
} }
$monitors = array(); $monitors = array();
$monitor_names = array();
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Monitors` ORDER BY lower(`Name`) ASC') as $monitor ) { foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Monitors` ORDER BY lower(`Name`) ASC') as $monitor ) {
if ( visibleMonitor($monitor['Id']) ) { if ( visibleMonitor($monitor['Id']) ) {
$monitors[$monitor['Name']] = validHtmlStr($monitor['Name']); $monitors[$monitor['Id']] = new ZM\Monitor($monitor);
$monitor_names[] = validHtmlStr($monitor['Name']);
}
}
$zones = array();
foreach ( dbFetchAll('SELECT Id, Name, MonitorId FROM Zones ORDER BY lower(`Name`) ASC') as $zone ) {
if ( visibleMonitor($zone['MonitorId']) ) {
$zone['Name'] = validHtmlStr($monitors[$zone['MonitorId']]->Name().': '.$zone['Name']);
$zones[$zone['Id']] = new ZM\Zone($zone);
} }
} }
@ -259,10 +271,15 @@ for ( $i=0; $i < count($terms); $i++ ) {
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $weekdays, $term['val']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][val]", $weekdays, $term['val']); ?></td>
<?php <?php
} elseif ( $term['attr'] == 'MonitorName' ) { } elseif ( $term['attr'] == 'Monitor' ) {
?> ?>
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $monitors, $term['val']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][val]", $monitors, $term['val']); ?></td>
<?php
} elseif ( $term['attr'] == 'MonitorName' ) {
?>
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", array_combine($monitor_names,$monitor_names), $term['val']); ?></td>
<?php <?php
} elseif ( $term['attr'] == 'ServerId' || $term['attr'] == 'MonitorServerId' || $term['attr'] == 'StorageServerId' || $term['attr'] == 'FilterServerId' ) { } elseif ( $term['attr'] == 'ServerId' || $term['attr'] == 'MonitorServerId' || $term['attr'] == 'StorageServerId' || $term['attr'] == 'FilterServerId' ) {
?> ?>
@ -273,6 +290,11 @@ for ( $i=0; $i < count($terms); $i++ ) {
?> ?>
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $storageareas, $term['val']); ?></td> <td><?php echo htmlSelect("filter[Query][terms][$i][val]", $storageareas, $term['val']); ?></td>
<?php
} elseif ( $term['attr'] == 'AlarmedZoneId' ) {
?>
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $zones, $term['val']); ?></td>
<?php <?php
} else { } else {
?> ?>
@ -409,7 +431,7 @@ if ( ZM_OPT_MESSAGE ) {
<hr/> <hr/>
<div id="contentButtons"> <div id="contentButtons">
<button type="submit" data-on-click-this="submitToEvents"><?php echo translate('ListMatches') ?></button> <button type="submit" data-on-click-this="submitToEvents"><?php echo translate('ListMatches') ?></button>
<!--<button type="submit" data-on-click-this="submitToMontageReview"><?php echo translate('ViewMatches') ?></button>--> <button type="button" data-on-click-this="submitToMontageReview"><?php echo translate('ViewMatches') ?></button>
<button type="button" data-on-click-this="submitToExport"><?php echo translate('ExportMatches') ?></button> <button type="button" data-on-click-this="submitToExport"><?php echo translate('ExportMatches') ?></button>
<button type="button" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button> <button type="button" name="executeButton" id="executeButton" data-on-click-this="executeFilter"><?php echo translate('Execute') ?></button>
<?php <?php

View File

@ -30,7 +30,6 @@ function validateForm( form ) {
function updateButtons(element) { function updateButtons(element) {
var form = element.form; var form = element.form;
console.log(element);
if ( element.type == 'checkbox' && element.checked ) { if ( element.type == 'checkbox' && element.checked ) {
form.elements['executeButton'].disabled = false; form.elements['executeButton'].disabled = false;
} else { } else {
@ -105,10 +104,13 @@ function submitToEvents( element ) {
form.action = thisUrl + '?view=events'; form.action = thisUrl + '?view=events';
history.replaceState(null, null, '?view=filter&' + $j(form).serialize()); history.replaceState(null, null, '?view=filter&' + $j(form).serialize());
} }
function submitToMontageReview(element) { function submitToMontageReview(element) {
var form = element.form; var form = element.form;
form.action = thisUrl + '?view=montagereview'; form.action = thisUrl + '?view=montagereview';
history.replaceState(null, null, '?view=filter&' + $j(form).serialize()); console.log($j(form).serialize());
window.location.assign('?view=montagereview&'+$j(form).serialize());
history.replaceState(null, null, '?view=montagereview&live=0&' + $j(form).serialize());
} }
function submitToExport(element) { function submitToExport(element) {
@ -184,7 +186,7 @@ function parseRows(rows) {
var attr = inputTds.eq(2).children().val(); var attr = inputTds.eq(2).children().val();
if ( attr == "Archived") { //Archived types if ( attr == 'Archived' ) { //Archived types
inputTds.eq(3).html('equal to<input type="hidden" name="filter[Query][terms][' + rowNum + '][op]" value="=">'); inputTds.eq(3).html('equal to<input type="hidden" name="filter[Query][terms][' + rowNum + '][op]" value="=">');
var archiveSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]'); var archiveSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
for (var i = 0; i < archiveTypes.length; i++) { for (var i = 0; i < archiveTypes.length; i++) {
@ -192,6 +194,18 @@ function parseRows(rows) {
} }
var archiveVal = inputTds.eq(4).children().val(); var archiveVal = inputTds.eq(4).children().val();
inputTds.eq(4).html(archiveSelect).children().val(archiveVal).chosen({width: "101%"}); inputTds.eq(4).html(archiveSelect).children().val(archiveVal).chosen({width: "101%"});
} else if ( attr == 'AlarmedZoneId' ) {
var zoneSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
for ( monitor_id in monitors ) {
for ( zone_id in zones ) {
var zone = zones[zone_id];
if ( monitor_id == zone.MonitorId ) {
zoneSelect.append('<option value="' + zone_id + '">' + (monitors[zone.MonitorId] ? monitors[zone.MonitorId].Name + ': ' : '') + zone.Name + '</option>');
}
} // end foreach zone
} // end foreach monitor
var zoneVal = inputTds.eq(4).children().val();
inputTds.eq(4).html(zoneSelect).children().val(zoneVal).chosen({width: "101%"});
} else if ( attr.indexOf('Weekday') >= 0 ) { //Weekday selection } else if ( attr.indexOf('Weekday') >= 0 ) { //Weekday selection
var weekdaySelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]'); var weekdaySelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
for (var i = 0; i < weekdays.length; i++) { for (var i = 0; i < weekdays.length; i++) {
@ -222,18 +236,27 @@ function parseRows(rows) {
inputTds.eq(4).html(storageSelect).children().val(storageVal).chosen({width: "101%"}); inputTds.eq(4).html(storageSelect).children().val(storageVal).chosen({width: "101%"});
} else if ( attr == 'MonitorName' ) { //Monitor names } else if ( attr == 'MonitorName' ) { //Monitor names
var monitorSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]'); var monitorSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
for (var key in monitors) { for ( var monitor_id in monitors ) {
monitorSelect.append('<option value="' + key + '">' + monitors[key] + '</option>'); monitorSelect.append('<option value="' + monitors[monitor_id].Name + '">' + monitors[monitor_id].Name + '</option>');
} }
var monitorVal = inputTds.eq(4).children().val(); var monitorVal = inputTds.eq(4).children().val();
inputTds.eq(4).html(monitorSelect).children().val(monitorVal); inputTds.eq(4).html(monitorSelect).children().val(monitorVal);
} else { // Reset to regular text field and operator for everything that isn't special } else { // Reset to regular text field and operator for everything that isn't special
if ( 0 ) {
// We don't actually do anything different in terms of operators. So why do it for text?
var opSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][op]').attr('id', queryPrefix + rowNum + '][op]'); var opSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][op]').attr('id', queryPrefix + rowNum + '][op]');
for (var key in opTypes) {
opSelect.append('<option value="' + key + '">' + opTypes[key] + '</option>');
}
var opVal = inputTds.eq(3).children().val(); var opVal = inputTds.eq(3).children().val();
if ( ! opVal ) {
// Default to equals so that something gets selected
console.log("No value for operator. Defaulting to =");
opVal = '=';
}
for ( var key in opTypes ) {
opSelect.append('<option value="' + key + '"'+(key == opVal ? ' selected="selected"' : '')+'>' + opTypes[key] + '</option>');
}
inputTds.eq(3).html(opSelect).children().val(opVal).chosen({width: "101%"}); inputTds.eq(3).html(opSelect).children().val(opVal).chosen({width: "101%"});
}
var textInput = $j('<input></input>').attr('type', 'text').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]'); var textInput = $j('<input></input>').attr('type', 'text').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
var textVal = inputTds.eq(4).children().val(); var textVal = inputTds.eq(4).children().val();
inputTds.eq(4).html(textInput).children().val(textVal); inputTds.eq(4).html(textInput).children().val(textVal);
@ -253,7 +276,7 @@ function parseRows(rows) {
term[2] = rowNum; term[2] = rowNum;
inputTds.eq(2).children().eq(0).attr('name', 'filter'+stringFilter(term)); inputTds.eq(2).children().eq(0).attr('name', 'filter'+stringFilter(term));
inputTds.eq(2).children().eq(0).attr('id', 'filter'+stringFilter(term)); inputTds.eq(2).children().eq(0).attr('id', 'filter'+stringFilter(term));
}//End for each term/row } // end foreach term/row
history.replaceState(null, null, '?view=filter&' + $j('#contentForm').serialize()); history.replaceState(null, null, '?view=filter&' + $j('#contentForm').serialize());
} }

View File

@ -10,6 +10,7 @@ var states = <?php echo isset($states) ? json_encode($states) : '' ?>;
var servers = <?php echo isset($servers) ? json_encode($servers) : '' ?>; var servers = <?php echo isset($servers) ? json_encode($servers) : '' ?>;
var storageareas = <?php echo isset($storageareas) ? json_encode($storageareas) : '' ?>; var storageareas = <?php echo isset($storageareas) ? json_encode($storageareas) : '' ?>;
var monitors = <?php echo isset($monitors) ? json_encode($monitors) : '' ?>; var monitors = <?php echo isset($monitors) ? json_encode($monitors) : '' ?>;
var zones = <?php echo isset($zones) ? json_encode($zones) : '' ?>;
var errorBrackets = '<?php echo translate('ErrorBrackets') ?>'; var errorBrackets = '<?php echo translate('ErrorBrackets') ?>';
var errorValue = '<?php echo translate('ErrorValidValue') ?>'; var errorValue = '<?php echo translate('ErrorValidValue') ?>';

View File

@ -464,6 +464,7 @@ function initPage() {
// Start the fps and status updates. give a random delay so that we don't assault the server // Start the fps and status updates. give a random delay so that we don't assault the server
var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout ); var delay = Math.round( (Math.random()+0.5)*statusRefreshTimeout );
console.log("delay: " + delay);
monitors[i].start(delay); monitors[i].start(delay);
var interval = monitors[i].refresh; var interval = monitors[i].refresh;

View File

@ -62,6 +62,17 @@ ob_end_clean();
$filter = array(); $filter = array();
if ( isset($_REQUEST['filter']) ) { if ( isset($_REQUEST['filter']) ) {
$filter = $_REQUEST['filter']; $filter = $_REQUEST['filter'];
# Try to guess min/max time from filter
foreach ( $filter['Query'] as $term ) {
if ( $term['attr'] == 'StartDateTime' ) {
if ( $term['op'] == '<=' or $term['op'] == '<' ) {
$maxTime = $term['val'];
} else if ( $term['op'] == '>=' or $term['op'] == '>' ) {
$minTime = $term['val'];
}
}
}
} else { } else {
if ( isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && (count($displayMonitors) != 0) ) { if ( isset($_REQUEST['minTime']) && isset($_REQUEST['maxTime']) && (count($displayMonitors) != 0) ) {