345 lines
15 KiB
PHP
345 lines
15 KiB
PHP
<?php
|
|
//
|
|
// ZoneMinder web events view file, $Date$, $Revision$
|
|
// Copyright (C) 2001-2008 Philip Coombes
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
//
|
|
|
|
if ( !canView('Events') || (!empty($_REQUEST['execute']) && !canEdit('Events')) ) {
|
|
$view = 'error';
|
|
return;
|
|
}
|
|
|
|
require_once('includes/Event.php');
|
|
|
|
$countSql = 'SELECT count(E.Id) AS EventCount FROM Monitors AS M INNER JOIN Events AS E ON (M.Id = E.MonitorId) WHERE';
|
|
$eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE';
|
|
if ( $user['MonitorIds'] ) {
|
|
$user_monitor_ids = ' M.Id in ('.$user['MonitorIds'].')';
|
|
$countSql .= $user_monitor_ids;
|
|
$eventsSql .= $user_monitor_ids;
|
|
} else {
|
|
$countSql .= ' 1';
|
|
$eventsSql .= ' 1';
|
|
}
|
|
|
|
parseSort();
|
|
parseFilter($_REQUEST['filter']);
|
|
$filterQuery = $_REQUEST['filter']['query'];
|
|
|
|
if ( $_REQUEST['filter']['sql'] ) {
|
|
$countSql .= $_REQUEST['filter']['sql'];
|
|
$eventsSql .= $_REQUEST['filter']['sql'];
|
|
}
|
|
$eventsSql .= " ORDER BY $sortColumn $sortOrder,Id $sortOrder";
|
|
|
|
$page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 0;
|
|
$limit = isset($_REQUEST['limit']) ? validInt($_REQUEST['limit']) : 0;
|
|
|
|
$nEvents = dbFetchOne($countSql, 'EventCount');
|
|
if ( !empty($limit) && $nEvents > $limit ) {
|
|
$nEvents = $limit;
|
|
}
|
|
$pages = (int)ceil($nEvents/ZM_WEB_EVENTS_PER_PAGE);
|
|
#Logger::Debug("Page $page Limit $limit #vents: $nEvents pages: $pages ");
|
|
if ( !empty($page) ) {
|
|
if ( $page < 0 )
|
|
$page = 1;
|
|
else if ( $pages and ( $page > $pages ) )
|
|
$page = $pages;
|
|
|
|
$limitStart = (($page-1)*ZM_WEB_EVENTS_PER_PAGE);
|
|
if ( empty( $limit ) ) {
|
|
$limitAmount = ZM_WEB_EVENTS_PER_PAGE;
|
|
} else {
|
|
$limitLeft = $limit - $limitStart;
|
|
$limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft;
|
|
}
|
|
$eventsSql .= " LIMIT $limitStart, $limitAmount";
|
|
} elseif ( !empty($limit) ) {
|
|
$eventsSql .= ' LIMIT 0, '.$limit;
|
|
}
|
|
|
|
$maxShortcuts = 5;
|
|
$pagination = getPagination($pages, $page, $maxShortcuts, $filterQuery.$sortQuery.$limitQuery);
|
|
|
|
$focusWindow = true;
|
|
|
|
if ( $_POST ) {
|
|
// I think this is basically so that a refresh doesn't repost
|
|
ZM\Logger::Debug('Redirecting to ' . $_SERVER['REQUEST_URI']);
|
|
header('Location: ?view=' . $view.htmlspecialchars_decode($filterQuery).htmlspecialchars_decode($sortQuery).$limitQuery.'&page='.$page);
|
|
exit();
|
|
}
|
|
|
|
$storage_areas = ZM\Storage::find();
|
|
$StorageById = array();
|
|
foreach ( $storage_areas as $S ) {
|
|
$StorageById[$S->Id()] = $S;
|
|
}
|
|
|
|
xhtmlHeaders(__FILE__, translate('Events') );
|
|
|
|
?>
|
|
<body>
|
|
<div id="page">
|
|
<?php echo getNavBarHTML() ?>
|
|
<div id="header">
|
|
<div id="info">
|
|
<h2><?php echo sprintf($CLANG['EventCount'], $nEvents, zmVlang($VLANG['Event'], $nEvents)) ?></h2>
|
|
<a id="refreshLink" href="#"><?php echo translate('Refresh') ?></a>
|
|
</div>
|
|
<div id="pagination">
|
|
<?php
|
|
if ( $pagination ) {
|
|
?>
|
|
<h2 class="pagination hidden-xs"><?php echo $pagination ?></h2>
|
|
<?php
|
|
}
|
|
?>
|
|
<?php
|
|
if ( $pages > 1 ) {
|
|
if ( !empty($page) ) {
|
|
?>
|
|
<a href="?view=<?php echo $view ?>&page=0<?php echo $filterQuery ?><?php echo $sortQuery.$limitQuery ?>"><?php echo translate('ViewAll') ?></a>
|
|
<?php
|
|
} else {
|
|
?>
|
|
<a href="?view=<?php echo $view ?>&page=1<?php echo $filterQuery ?><?php echo $sortQuery.$limitQuery ?>"><?php echo translate('ViewPaged') ?></a>
|
|
<?php
|
|
}
|
|
}
|
|
?>
|
|
</div>
|
|
<div id="controls">
|
|
<a href="#" id="backLink"><?php echo translate('Back') ?></a>
|
|
<a id="timelineLink" href="?view=timeline<?php echo $filterQuery ?>"><?php echo translate('ShowTimeline') ?></a>
|
|
</div>
|
|
</div>
|
|
<div id="content">
|
|
<form name="contentForm" id="contentForm" method="post" action="">
|
|
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
|
<input type="hidden" name="action" value=""/>
|
|
<input type="hidden" name="page" value="<?php echo $page ?>"/>
|
|
<?php echo $_REQUEST['filter']['fields'] ?>
|
|
<input type="hidden" name="sort_field" value="<?php echo validHtmlStr($_REQUEST['sort_field']) ?>"/>
|
|
<input type="hidden" name="sort_asc" value="<?php echo validHtmlStr($_REQUEST['sort_asc']) ?>"/>
|
|
<input type="hidden" name="limit" value="<?php echo $limit ?>"/>
|
|
<div class="table-responsive-sm">
|
|
<table id="contentTable" class="major">
|
|
<tbody>
|
|
<?php
|
|
$count = 0;
|
|
$disk_space_total = 0;
|
|
|
|
$results = dbQuery($eventsSql);
|
|
while ( $event_row = dbFetchNext($results) ) {
|
|
$event = new ZM\Event($event_row);
|
|
if ( $event_row['Archived'] )
|
|
$archived = true;
|
|
else
|
|
$unarchived = true;
|
|
|
|
if ( ($count++%ZM_WEB_EVENTS_PER_PAGE) == 0 ) {
|
|
?>
|
|
<tr>
|
|
<th class="colId"><a href="<?php echo sortHeader('Id') ?>"><?php echo translate('Id') ?><?php echo sortTag('Id') ?></a></th>
|
|
<th class="colName px-1"><a href="<?php echo sortHeader('Name') ?>"><?php echo translate('Name') ?><?php echo sortTag('Name') ?></a></th>
|
|
<th class="colMonitor px-1"><a href="<?php echo sortHeader('MonitorName') ?>"><?php echo translate('Monitor') ?><?php echo sortTag('MonitorName') ?></a></th>
|
|
<th class="colCause px-1"><a href="<?php echo sortHeader('Cause') ?>"><?php echo translate('Cause') ?><?php echo sortTag('Cause') ?></a></th>
|
|
<th class="colStartTime px-1"><a href="<?php echo sortHeader('StartTime') ?>"><?php echo translate('AttrStartTime') ?><?php echo sortTag('StartTime') ?></a></th>
|
|
<th class="colEndTime px-1"><a href="<?php echo sortHeader('EndTime') ?>"><?php echo translate('AttrEndTime') ?><?php echo sortTag('EndTime') ?></a></th>
|
|
<th class="colDuration px-1"><a href="<?php echo sortHeader('Length') ?>"><?php echo translate('Duration') ?><?php echo sortTag('Length') ?></a></th>
|
|
<th class="colFrames px-1"><a href="<?php echo sortHeader('Frames') ?>"><?php echo translate('Frames') ?><?php echo sortTag('Frames') ?></a></th>
|
|
<th class="colAlarmFrames px-1"><a href="<?php echo sortHeader('AlarmFrames') ?>"><?php echo translate('AlarmBrFrames') ?><?php echo sortTag('AlarmFrames') ?></a></th>
|
|
<th class="colTotScore px-1"><a href="<?php echo sortHeader('TotScore') ?>"><?php echo translate('TotalBrScore') ?><?php echo sortTag('TotScore') ?></a></th>
|
|
<th class="colAvgScore px-1"><a href="<?php echo sortHeader('AvgScore') ?>"><?php echo translate('AvgBrScore') ?><?php echo sortTag('AvgScore') ?></a></th>
|
|
<th class="colMaxScore px-1"><a href="<?php echo sortHeader('MaxScore') ?>"><?php echo translate('MaxBrScore') ?><?php echo sortTag('MaxScore') ?></a></th>
|
|
<?php
|
|
if ( count($storage_areas) > 1 ) {
|
|
?>
|
|
<th class="colStorage px-1"><?php echo translate('Storage') ?></th>
|
|
<?php
|
|
}
|
|
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
|
?>
|
|
<th class="colDiskSpace px-1"><a href="<?php echo sortHeader('DiskSpace') ?>"><?php echo translate('DiskSpace') ?><?php echo sortTag('DiskSpace') ?></a></th>
|
|
<?php
|
|
}
|
|
if ( ZM_WEB_LIST_THUMBS ) {
|
|
?>
|
|
<th class="colThumbnail px-1"><?php echo translate('Thumbnail') ?></th>
|
|
<?php
|
|
}
|
|
?>
|
|
<th class="colMark px-1"><input type="checkbox" name="toggleCheck" value="1" data-checkbox-name="eids[]" data-on-click-this="updateFormCheckboxesByName"/></th>
|
|
</tr>
|
|
<?php
|
|
}
|
|
$scale = max( reScale( SCALE_BASE, $event->DefaultScale(), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
|
|
?>
|
|
<tr<?php if ($event->Archived()) echo ' class="archived"' ?>>
|
|
<td class="colId"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.$event->Id().($event->Archived()?'*':'') ?></a></td>
|
|
<td class="colName px-1"><a href="?view=event&eid=<?php echo $event->Id().$filterQuery.$sortQuery.'&page=1">'.validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a><br/>
|
|
<?php
|
|
if ( $event->Emailed() )
|
|
echo 'Emailed ';
|
|
?>
|
|
</td>
|
|
<td class="colMonitorName px-1"><?php echo makePopupLink( '?view=monitor&mid='.$event->MonitorId(), 'zmMonitor'.$event->MonitorId(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
|
|
<td class="colCause px-1"><?php echo makePopupLink( '?view=eventdetail&eid='.$event->Id(), 'zmEventDetail', 'eventdetail', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="'.htmlspecialchars($event->Notes()).'"' ) ?>
|
|
<?php
|
|
# display notes as small text
|
|
if ( $event->Notes() ) {
|
|
# if notes include detection objects, then link it to objdetect.jpg
|
|
if ( strpos($event->Notes(), 'detected:') !== false ) {
|
|
# make a link
|
|
echo makePopupLink( '?view=image&eid='.$event->Id().'&fid=objdetect', 'zmImage',
|
|
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)),
|
|
'<div class="small text-nowrap text-muted"><u>'.$event->Notes().'</u></div>');
|
|
} else if ( $event->Notes() != 'Forced Web: ' ) {
|
|
echo '<br/><div class="small text-nowrap text-muted">'.$event->Notes().'</div>';
|
|
}
|
|
}
|
|
?>
|
|
</td>
|
|
<td class="colTime text-wrap px-1"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) ?></td>
|
|
<td class="colTime text-wrap px-1"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) ?></td>
|
|
<td class="colDuration px-1"><?php echo gmdate("H:i:s", $event->Length() ) ?></td>
|
|
<td class="colFrames px-1"><?php echo makePopupLink( '?view=frames&eid='.$event->Id(), 'zmFrames',
|
|
( ZM_WEB_LIST_THUMBS ? array('frames', ZM_WEB_LIST_THUMB_WIDTH, ZM_WEB_LIST_THUMB_HEIGHT) : 'frames'),
|
|
$event->Frames() ) ?></td>
|
|
<td class="colAlarmFrames px-1"><?php echo makePopupLink( '?view=frames&eid='.$event->Id(), 'zmFrames',
|
|
( ZM_WEB_LIST_THUMBS ? array('frames', ZM_WEB_LIST_THUMB_WIDTH, ZM_WEB_LIST_THUMB_HEIGHT) : 'frames'),
|
|
$event->AlarmFrames() ) ?></td>
|
|
<td class="colTotScore px-1"><?php echo $event->TotScore() ?></td>
|
|
<td class="colAvgScore px-1"><?php echo $event->AvgScore() ?></td>
|
|
<td class="colMaxScore px-1"><?php echo makePopupLink(
|
|
'?view=frame&eid='.$event->Id().'&fid=0', 'zmImage',
|
|
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)), $event->MaxScore()
|
|
); ?></td>
|
|
<?php
|
|
if ( count($storage_areas) > 1 ) {
|
|
?>
|
|
<td class="colStorage px-1">
|
|
<?php
|
|
if ( $event->StorageId() ) {
|
|
echo isset($StorageById[$event->StorageId()]) ? $StorageById[$event->StorageId()]->Name() : 'Unknown Storage Id: '.$event->StorageId();
|
|
} else {
|
|
echo 'Default';
|
|
}
|
|
if ( $event->SecondaryStorageId() ) {
|
|
echo '<br/>'.(isset($StorageById[$event->SecondaryStorageId()]) ? $StorageById[$event->SecondaryStorageId()]->Name() : 'Unknown Storage Id '.$event->SecondaryStorageId());
|
|
}
|
|
?>
|
|
</td>
|
|
|
|
<?php
|
|
}
|
|
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
|
$disk_space_total += $event->DiskSpace();
|
|
?>
|
|
<td class="colDiskSpace px-1"><?php echo human_filesize($event->DiskSpace()) ?></td>
|
|
<?php
|
|
}
|
|
if ( ZM_WEB_LIST_THUMBS ) {
|
|
echo '<td class="colThumbnail px-1">';
|
|
$imgSrc = $event->getThumbnailSrc(array(),'&');
|
|
$streamSrc = $event->getStreamSrc(array(
|
|
'mode'=>'jpeg', 'scale'=>$scale, 'maxfps'=>ZM_WEB_VIDEO_MAXFPS, 'replay'=>'single', 'rate'=>'400'), '&');
|
|
|
|
$imgHtml = '<img id="thumbnail'.$event->Id().'" src="'.$imgSrc.'" alt="'. validHtmlStr('Event '.$event->Id()) .'" style="width:'. validInt($event->ThumbnailWidth()) .'px;height:'. validInt($event->ThumbnailHeight()).'px;" stream_src="'.$streamSrc.'" still_src="'.$imgSrc.'"/>';
|
|
echo '<a href="?view=event&eid='. $event->Id().$filterQuery.$sortQuery.'&page=1">'.$imgHtml.'</a>';
|
|
echo '</td>';
|
|
} // end if ZM_WEB_LIST_THUMBS
|
|
?>
|
|
<td class="colMark px-1"><input type="checkbox" name="eids[]" value="<?php echo $event->Id() ?>"/></td>
|
|
</tr>
|
|
<?php
|
|
}
|
|
?>
|
|
</tbody>
|
|
<?php
|
|
if ( ZM_WEB_EVENT_DISK_SPACE ) {
|
|
?>
|
|
<tfoot>
|
|
<tr>
|
|
<td colspan="11">Totals:</td>
|
|
<?php
|
|
if ( count($storage_areas)>1 ) {
|
|
?>
|
|
<td class="colStorage"></td>
|
|
<?php
|
|
}
|
|
?>
|
|
<td class="colDiskSpace"><?php echo human_filesize($disk_space_total) ?></td>
|
|
<?php
|
|
if ( ZM_WEB_LIST_THUMBS ) {
|
|
?>
|
|
<td></td>
|
|
<?php
|
|
}
|
|
?>
|
|
<td></td>
|
|
</tr>
|
|
</tfoot>
|
|
<?php
|
|
}
|
|
?>
|
|
</table>
|
|
</div>
|
|
<?php
|
|
if ( $pagination ) {
|
|
?>
|
|
<h3 class="pagination"><?php echo $pagination ?></h3>
|
|
<?php
|
|
}
|
|
?>
|
|
<div id="contentButtons">
|
|
<button type="button" name="viewBtn" value="View" data-on-click-this="viewEvents" disabled="disabled">
|
|
<?php echo translate('View') ?>
|
|
</button>
|
|
<button type="button" name="archiveBtn" value="Archive" data-on-click-this="archiveEvents" disabled="disabled">
|
|
<?php echo translate('Archive') ?>
|
|
</button>
|
|
<button type="button" name="unarchiveBtn" value="Unarchive" data-on-click-this="unarchiveEvents" disabled="disabled">
|
|
<?php echo translate('Unarchive') ?>
|
|
</button>
|
|
<button type="button" name="editBtn" value="Edit" data-on-click-this="editEvents" disabled="disabled">
|
|
<?php echo translate('Edit') ?>
|
|
</button>
|
|
<button type="button" name="exportBtn" value="Export" data-on-click-this="exportEvents" disabled="disabled">
|
|
<?php echo translate('Export') ?>
|
|
</button>
|
|
<button type="button" name="downloadBtn" value="DownloadVideo" data-on-click-this="downloadVideo" disabled="disabled">
|
|
<?php echo translate('DownloadVideo') ?>
|
|
</button>
|
|
<button type="button" name="deleteBtn" value="Delete" data-on-click-this="deleteEvents" disabled="disabled">
|
|
<?php echo translate('Delete') ?>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script nonce="<?php echo $cspNonce;?>">
|
|
// These are defined in the .js.php but need to be updated down here.
|
|
// This might be better done by selecting through the dom for the archived class
|
|
archivedEvents = <?php echo !empty($archived)?'true':'false' ?>;
|
|
unarchivedEvents = <?php echo !empty($unarchived)?'true':'false' ?>;
|
|
</script>
|
|
</body>
|
|
</html>
|