2020-08-31 22:37:22 +08:00
< ? php
2020-10-19 20:50:11 +08:00
$message = '' ;
$data = array ();
//
// INITIALIZE AND CHECK SANITY
//
2020-12-08 23:33:25 +08:00
if ( ! canView ( 'Events' ) ) $message = 'Insufficient permissions for user ' . $user [ 'Username' ];
2020-10-19 20:50:11 +08:00
if ( empty ( $_REQUEST [ 'task' ]) ) {
$message = 'Must specify a task' ;
} else {
$task = $_REQUEST [ 'task' ];
}
2020-08-31 22:37:22 +08:00
if ( empty ( $_REQUEST [ 'eids' ]) ) {
2020-11-06 01:20:49 +08:00
if ( isset ( $_REQUEST [ 'task' ]) && $_REQUEST [ 'task' ] != 'query' ) $message = 'No event id(s) supplied' ;
2020-10-19 20:50:11 +08:00
} else {
$eids = $_REQUEST [ 'eids' ];
}
if ( $message ) {
ajaxError ( $message );
return ;
}
2020-11-06 01:20:49 +08:00
require_once ( 'includes/Filter.php' );
2020-10-24 05:55:43 +08:00
$filter = isset ( $_REQUEST [ 'filter' ]) ? ZM\Filter :: parse ( $_REQUEST [ 'filter' ]) : new ZM\Filter ();
if ( $user [ 'MonitorIds' ] ) {
$filter = $filter -> addTerm ( array ( 'cnj' => 'and' , 'attr' => 'MonitorId' , 'op' => 'IN' , 'val' => $user [ 'MonitorIds' ]));
}
2020-10-19 20:50:11 +08:00
// Search contains a user entered string to search on
$search = isset ( $_REQUEST [ 'search' ]) ? $_REQUEST [ 'search' ] : '' ;
// Advanced search contains an array of "column name" => "search text" pairs
// Bootstrap table sends json_ecoded array, which we must decode
2020-10-24 04:44:50 +08:00
$advsearch = isset ( $_REQUEST [ 'advsearch' ]) ? json_decode ( $_REQUEST [ 'advsearch' ], JSON_OBJECT_AS_ARRAY ) : array ();
2020-10-19 20:50:11 +08:00
2021-06-15 22:33:42 +08:00
// Order specifies the sort direction, either asc or desc
$order = ( isset ( $_REQUEST [ 'order' ]) and ( strtolower ( $_REQUEST [ 'order' ]) == 'asc' )) ? 'ASC' : 'DESC' ;
2020-10-19 20:50:11 +08:00
// Sort specifies the name of the column to sort on
2020-11-05 02:58:03 +08:00
$sort = 'StartDateTime' ;
2021-06-15 22:33:42 +08:00
if ( isset ( $_REQUEST [ 'sort' ])) {
2020-10-23 02:27:47 +08:00
$sort = $_REQUEST [ 'sort' ];
2021-06-15 22:33:42 +08:00
if ( $sort == 'EndDateTime' ) {
if ( $order == 'ASC' ) {
$sort = 'EndDateTime IS NULL, EndDateTime' ;
} else {
$sort = 'EndDateTime IS NOT NULL, EndDateTime' ;
}
}
2020-08-31 22:37:22 +08:00
}
2020-10-19 20:50:11 +08:00
// Offset specifies the starting row to return, used for pagination
$offset = 0 ;
if ( isset ( $_REQUEST [ 'offset' ]) ) {
if ( ( ! is_int ( $_REQUEST [ 'offset' ]) and ! ctype_digit ( $_REQUEST [ 'offset' ]) ) ) {
ZM\Error ( 'Invalid value for offset: ' . $_REQUEST [ 'offset' ]);
} else {
$offset = $_REQUEST [ 'offset' ];
}
}
// Limit specifies the number of rows to return
2020-11-15 00:27:33 +08:00
// Set the default to 0 for events view, to prevent an issue with ALL pagination
$limit = 0 ;
2020-10-19 20:50:11 +08:00
if ( isset ( $_REQUEST [ 'limit' ]) ) {
if ( ( ! is_int ( $_REQUEST [ 'limit' ]) and ! ctype_digit ( $_REQUEST [ 'limit' ]) ) ) {
ZM\Error ( 'Invalid value for limit: ' . $_REQUEST [ 'limit' ]);
} else {
$limit = $_REQUEST [ 'limit' ];
}
}
//
// MAIN LOOP
//
switch ( $task ) {
case 'archive' :
2020-12-08 23:33:25 +08:00
foreach ( $eids as $eid ) archiveRequest ( $task , $eid );
break ;
2020-10-19 20:50:11 +08:00
case 'unarchive' :
2020-12-08 23:33:25 +08:00
# The idea is that anyone can archive, but only people with Event Edit permission can unarchive..
if ( ! canEdit ( 'Events' ) ) {
ajaxError ( 'Insufficient permissions for user ' . $user [ 'Username' ]);
return ;
}
2020-10-19 20:50:11 +08:00
foreach ( $eids as $eid ) archiveRequest ( $task , $eid );
break ;
case 'delete' :
2020-12-08 23:33:25 +08:00
if ( ! canEdit ( 'Events' ) ) {
ajaxError ( 'Insufficient permissions for user ' . $user [ 'Username' ]);
return ;
}
2020-10-19 20:50:11 +08:00
foreach ( $eids as $eid ) $data [] = deleteRequest ( $eid );
break ;
case 'query' :
2020-10-24 05:55:43 +08:00
$data = queryRequest ( $filter , $search , $advsearch , $sort , $offset , $order , $limit );
2020-10-19 20:50:11 +08:00
break ;
default :
ZM\Fatal ( " Unrecognised task ' $task ' " );
} // end switch task
ajaxResponse ( $data );
2020-08-31 22:37:22 +08:00
2020-10-19 20:50:11 +08:00
//
// FUNCTION DEFINITIONS
//
function archiveRequest ( $task , $eid ) {
$archiveVal = ( $task == 'archive' ) ? 1 : 0 ;
dbQuery (
'UPDATE Events SET Archived = ? WHERE Id = ?' ,
array ( $archiveVal , $eid )
);
}
function deleteRequest ( $eid ) {
2020-08-31 22:37:22 +08:00
$message = array ();
2020-10-19 20:50:11 +08:00
$event = new ZM\Event ( $eid );
if ( ! $event -> Id () ) {
$message [] = array ( $eid => 'Event not found.' );
} else if ( $event -> Archived () ) {
$message [] = array ( $eid => 'Event is archived, cannot delete it.' );
} else {
$event -> delete ();
}
return $message ;
}
2020-10-24 05:55:43 +08:00
function queryRequest ( $filter , $search , $advsearch , $sort , $offset , $order , $limit ) {
2020-11-06 01:20:49 +08:00
2020-10-26 21:58:47 +08:00
$data = array (
'total' => 0 ,
'totalNotFiltered' => 0 ,
'rows' => array (),
2020-11-06 01:20:49 +08:00
'updated' => preg_match ( '/%/' , DATE_FMT_CONSOLE_LONG ) ? strftime ( DATE_FMT_CONSOLE_LONG ) : date ( DATE_FMT_CONSOLE_LONG )
2020-10-26 21:58:47 +08:00
);
$failed = ! $filter -> test_pre_sql_conditions ();
if ( $failed ) {
ZM\Debug ( 'Pre conditions failed, not doing sql' );
return $data ;
}
2020-10-19 20:50:11 +08:00
// Put server pagination code here
// The table we want our data from
$table = 'Events' ;
2020-08-31 22:37:22 +08:00
2020-10-23 23:21:32 +08:00
// The names of the dB columns in the events table we are interested in
2020-11-05 02:58:03 +08:00
$columns = array ( 'Id' , 'MonitorId' , 'StorageId' , 'Name' , 'Cause' , 'StartDateTime' , 'EndDateTime' , 'Length' , 'Frames' , 'AlarmFrames' , 'TotScore' , 'AvgScore' , 'MaxScore' , 'Archived' , 'Emailed' , 'Notes' , 'DiskSpace' );
2020-10-19 20:50:11 +08:00
2020-10-23 02:27:47 +08:00
// The names of columns shown in the event view that are NOT dB columns in the database
2020-10-19 20:50:11 +08:00
$col_alt = array ( 'Monitor' , 'Storage' );
2020-10-23 02:27:47 +08:00
if ( ! in_array ( $sort , array_merge ( $columns , $col_alt )) ) {
2020-10-27 01:06:05 +08:00
ZM\Error ( 'Invalid sort field: ' . $sort );
$sort = 'Id' ;
2020-10-23 02:27:47 +08:00
}
2020-11-06 01:20:49 +08:00
$values = array ();
2020-10-19 20:50:11 +08:00
$likes = array ();
2020-11-06 01:20:49 +08:00
$where = $filter -> sql () ? ' WHERE (' . $filter -> sql () . ')' : '' ;
2020-10-19 20:50:11 +08:00
2020-10-26 22:03:12 +08:00
$sort = $sort == 'Monitor' ? 'M.Name' : 'E.' . $sort ;
2020-10-25 23:28:22 +08:00
$col_str = 'E.*, M.Name AS Monitor' ;
2020-11-06 01:20:49 +08:00
$sql = 'SELECT ' . $col_str . ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id' . $where . ' ORDER BY ' . $sort . ' ' . $order ;
2020-10-19 20:50:11 +08:00
$storage_areas = ZM\Storage :: find ();
$StorageById = array ();
foreach ( $storage_areas as $S ) {
$StorageById [ $S -> Id ()] = $S ;
}
2020-11-06 01:20:49 +08:00
$unfiltered_rows = array ();
$event_ids = array ();
2021-01-17 02:17:31 +08:00
ZM\Debug ( 'Calling the following sql query: ' . $sql );
$query = dbQuery ( $sql , $values );
if ( $query ) {
while ( $row = dbFetchNext ( $query ) ) {
$event = new ZM\Event ( $row );
2020-10-26 21:58:47 +08:00
$event -> remove_from_cache ();
2021-01-17 02:17:31 +08:00
if ( ! $filter -> test_post_sql_conditions ( $event ) ) {
continue ;
}
$event_ids [] = $event -> Id ();
$unfiltered_rows [] = $row ;
} # end foreach row
2020-11-06 01:20:49 +08:00
}
2020-11-13 21:24:17 +08:00
ZM\Debug ( 'Have ' . count ( $unfiltered_rows ) . ' events matching base filter.' );
2020-11-06 01:20:49 +08:00
$filtered_rows = null ;
if ( count ( $advsearch ) or $search != '' ) {
$search_filter = new ZM\Filter ();
$search_filter = $search_filter -> addTerm ( array ( 'cnj' => 'and' , 'attr' => 'Id' , 'op' => 'IN' , 'val' => $event_ids ));
// There are two search bars in the log view, normal and advanced
// Making an exuctive decision to ignore the normal search, when advanced search is in use
// Alternatively we could try to do both
if ( count ( $advsearch ) ) {
$terms = array ();
foreach ( $advsearch as $col => $text ) {
$terms [] = array ( 'cnj' => 'and' , 'attr' => $col , 'op' => 'LIKE' , 'val' => $text );
} # end foreach col in advsearch
$terms [ 0 ][ 'obr' ] = 1 ;
$terms [ count ( $terms ) - 1 ][ 'cbr' ] = 1 ;
$search_filter -> addTerms ( $terms );
} else if ( $search != '' ) {
$search = '%' . $search . '%' ;
$terms = array ();
foreach ( $columns as $col ) {
$terms [] = array ( 'cnj' => 'or' , 'attr' => $col , 'op' => 'LIKE' , 'val' => $search );
}
$terms [ 0 ][ 'obr' ] = 1 ;
$terms [ 0 ][ 'cnj' ] = 'and' ;
$terms [ count ( $terms ) - 1 ][ 'cbr' ] = 1 ;
$search_filter = $search_filter -> addTerms ( $terms , array ( 'obr' => 1 , 'cbr' => 1 , 'op' => 'OR' ));
} # end if search
$sql = 'SELECT ' . $col_str . ' FROM `Events` AS E INNER JOIN Monitors AS M ON E.MonitorId = M.Id WHERE ' . $search_filter -> sql () . ' ORDER BY ' . $sort . ' ' . $order ;
2021-01-17 02:17:31 +08:00
ZM\Debug ( 'Calling the following sql query: ' . $sql );
2020-11-06 01:20:49 +08:00
$filtered_rows = dbFetchAll ( $sql );
ZM\Debug ( 'Have ' . count ( $filtered_rows ) . ' events matching search filter.' );
} else {
$filtered_rows = $unfiltered_rows ;
} # end if search_filter->terms() > 1
$returned_rows = array ();
foreach ( array_slice ( $filtered_rows , $offset , $limit ) as $row ) {
$event = new ZM\Event ( $row );
2020-10-21 01:59:30 +08:00
$scale = intval ( 5 * 100 * ZM_WEB_LIST_THUMB_WIDTH / $event -> Width ());
2020-12-09 00:26:43 +08:00
$imgSrc = $event -> getThumbnailSrc ( array (), '&' );
2020-10-21 01:13:12 +08:00
$streamSrc = $event -> getStreamSrc ( array (
2020-10-29 21:39:48 +08:00
'mode' => 'jpeg' , 'scale' => $scale , 'maxfps' => ZM_WEB_VIDEO_MAXFPS , 'replay' => 'single' , 'rate' => '400' ), '&' );
2020-10-21 01:13:12 +08:00
2020-10-19 20:50:11 +08:00
// Modify the row data as needed
2020-12-09 00:26:43 +08:00
$row [ 'imgHtml' ] = '<img id="thumbnail' . $event -> Id () . '" src="' . $imgSrc . '" alt="Event ' . $event -> Id () . '" width="' . validInt ( $event -> ThumbnailWidth ()) . '" height="' . validInt ( $event -> ThumbnailHeight ()) . '" stream_src="' . $streamSrc . '" still_src="' . $imgSrc . '"/>' ;
2020-10-20 03:18:21 +08:00
$row [ 'Name' ] = validHtmlStr ( $row [ 'Name' ]);
$row [ 'Archived' ] = $row [ 'Archived' ] ? translate ( 'Yes' ) : translate ( 'No' );
$row [ 'Emailed' ] = $row [ 'Emailed' ] ? translate ( 'Yes' ) : translate ( 'No' );
$row [ 'Cause' ] = validHtmlStr ( $row [ 'Cause' ]);
2020-11-05 02:58:03 +08:00
$row [ 'StartDateTime' ] = strftime ( STRF_FMT_DATETIME_SHORTER , strtotime ( $row [ 'StartDateTime' ]));
$row [ 'EndDateTime' ] = $row [ 'EndDateTime' ] ? strftime ( STRF_FMT_DATETIME_SHORTER , strtotime ( $row [ 'EndDateTime' ])) : null ;
2020-10-20 01:25:13 +08:00
$row [ 'Length' ] = gmdate ( 'H:i:s' , $row [ 'Length' ] );
$row [ 'Storage' ] = ( $row [ 'StorageId' ] and isset ( $StorageById [ $row [ 'StorageId' ]]) ) ? $StorageById [ $row [ 'StorageId' ]] -> Name () : 'Default' ;
2020-10-30 03:08:14 +08:00
$row [ 'Notes' ] = nl2br ( htmlspecialchars ( $row [ 'Notes' ]));
2020-10-24 20:50:59 +08:00
$row [ 'DiskSpace' ] = human_filesize ( $event -> DiskSpace ());
2020-11-06 01:20:49 +08:00
$returned_rows [] = $row ;
} # end foreach row matching search
$data [ 'rows' ] = $returned_rows ;
2020-10-19 20:50:11 +08:00
2020-11-01 00:26:29 +08:00
# totalNotFiltered must equal total, except when either search bar has been used
2020-11-13 21:24:17 +08:00
$data [ 'totalNotFiltered' ] = count ( $unfiltered_rows );
2020-11-01 00:26:29 +08:00
if ( $search != '' || count ( $advsearch ) ) {
2020-11-06 01:20:49 +08:00
$data [ 'total' ] = count ( $filtered_rows );
2020-11-01 00:26:29 +08:00
} else {
2020-11-13 21:24:17 +08:00
$data [ 'total' ] = $data [ 'totalNotFiltered' ];
2020-11-01 00:26:29 +08:00
}
2020-11-03 04:33:40 +08:00
2020-10-19 20:50:11 +08:00
return $data ;
}
2020-08-31 22:37:22 +08:00
?>