2008-07-14 21:54:50 +08:00
< ? php
//
// ZoneMinder web events view file, $Date$, $Revision$
2008-07-25 17:48:16 +08:00
// Copyright (C) 2001-2008 Philip Coombes
2008-07-14 21:54:50 +08:00
//
// 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
2016-12-26 23:23:16 +08:00
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2008-07-14 21:54:50 +08:00
//
2018-04-03 21:57:22 +08:00
if ( ! canView ( 'Events' ) || ( ! empty ( $_REQUEST [ 'execute' ]) && ! canEdit ( 'Events' )) ) {
2017-06-01 09:34:38 +08:00
$view = 'error' ;
return ;
2008-07-14 21:54:50 +08:00
}
2018-04-03 21:57:22 +08:00
require_once ( 'includes/Event.php' );
2020-04-07 22:05:02 +08:00
require_once ( 'includes/Filter.php' );
2017-01-02 23:35:51 +08:00
2016-04-02 02:07:27 +08:00
$eventsSql = 'SELECT E.*,M.Name AS MonitorName,M.DefaultScale FROM Monitors AS M INNER JOIN Events AS E on (M.Id = E.MonitorId) WHERE' ;
2014-03-22 05:16:56 +08:00
if ( $user [ 'MonitorIds' ] ) {
2019-08-28 21:19:09 +08:00
$user_monitor_ids = ' M.Id in (' . $user [ 'MonitorIds' ] . ')' ;
$eventsSql .= $user_monitor_ids ;
2014-03-22 05:16:56 +08:00
} else {
2017-06-01 09:34:38 +08:00
$eventsSql .= ' 1' ;
2008-07-14 21:54:50 +08:00
}
2020-04-07 22:05:02 +08:00
$filter = isset ( $_REQUEST [ 'filter_id' ]) ? new ZM\Filter ( $_REQUEST [ 'filter_id' ]) : new ZM\Filter ();
if ( isset ( $_REQUEST [ 'filter' ])) {
2020-08-27 23:55:26 +08:00
$filter -> set ( $_REQUEST [ 'filter' ]);
2020-04-07 22:05:02 +08:00
}
2008-07-14 21:54:50 +08:00
2020-04-07 22:05:02 +08:00
parseSort ();
2008-07-14 21:54:50 +08:00
2020-08-18 05:41:50 +08:00
$filterQuery = $filter -> querystring ();
2020-08-17 01:06:37 +08:00
ZM\Logger :: Debug ( " Filter " . print_r ( $filter , true ));
2020-04-07 22:05:02 +08:00
if ( $filter -> sql () ) {
2020-08-18 05:41:50 +08:00
$eventsSql .= ' AND (' . $filter -> sql () . ')' ;
2020-04-07 22:05:02 +08:00
} else {
2020-08-27 23:55:26 +08:00
ZM\Warning ( 'No filters' );
exit ;
2008-07-14 21:54:50 +08:00
}
2020-08-17 01:06:37 +08:00
$eventsSql .= " ORDER BY $sortColumn $sortOrder " ;
2020-08-18 00:56:20 +08:00
if ( $sortColumn != 'E.Id' ) $eventsSql .= ',E.Id ' . $sortOrder ;
2008-07-14 21:54:50 +08:00
2018-02-07 22:07:51 +08:00
$page = isset ( $_REQUEST [ 'page' ]) ? validInt ( $_REQUEST [ 'page' ]) : 0 ;
2020-08-18 00:56:20 +08:00
$limit = isset ( $_REQUEST [ 'limit' ]) ? validInt ( $_REQUEST [ 'limit' ]) : $filter [ 'limit' ];
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 ();
}
2008-09-26 17:47:20 +08:00
2020-08-18 05:41:50 +08:00
$failed = ! $filter -> test_pre_sql_conditions ();
2020-08-18 04:58:37 +08:00
if ( $failed ) {
2020-08-28 05:16:10 +08:00
ZM\Logger :: Debug ( 'Pre conditions failed, not doing sql' );
2020-08-18 04:58:37 +08:00
}
$results = $failed ? null : dbQuery ( $eventsSql );
$nEvents = $results ? $results -> rowCount () : 0 ;
ZM\Logger :: Debug ( " Pre conditions succeeded sql return $nEvents events " );
2008-09-26 17:47:20 +08:00
2020-08-18 00:56:20 +08:00
if ( ! empty ( $limit ) && ( $nEvents > $limit ) ) {
2017-06-01 09:34:38 +08:00
$nEvents = $limit ;
2008-07-14 21:54:50 +08:00
}
$pages = ( int ) ceil ( $nEvents / ZM_WEB_EVENTS_PER_PAGE );
2018-02-07 22:07:51 +08:00
#Logger::Debug("Page $page Limit $limit #vents: $nEvents pages: $pages ");
2016-04-16 04:11:53 +08:00
if ( ! empty ( $page ) ) {
2017-05-06 02:25:25 +08:00
if ( $page < 0 )
$page = 1 ;
2018-02-07 22:07:51 +08:00
else if ( $pages and ( $page > $pages ) )
2017-05-06 02:25:25 +08:00
$page = $pages ;
$limitStart = (( $page - 1 ) * ZM_WEB_EVENTS_PER_PAGE );
2020-08-17 01:06:37 +08:00
if ( empty ( $limit ) ) {
2017-05-06 02:25:25 +08:00
$limitAmount = ZM_WEB_EVENTS_PER_PAGE ;
} else {
$limitLeft = $limit - $limitStart ;
$limitAmount = ( $limitLeft > ZM_WEB_EVENTS_PER_PAGE ) ? ZM_WEB_EVENTS_PER_PAGE : $limitLeft ;
}
2020-08-06 23:57:35 +08:00
$eventsSql .= " LIMIT $limitStart , $limitAmount " ;
2020-08-17 01:06:37 +08:00
} else if ( ! empty ( $limit ) ) {
2020-08-06 23:57:35 +08:00
$eventsSql .= ' LIMIT 0, ' . $limit ;
2008-07-14 21:54:50 +08:00
}
$maxShortcuts = 5 ;
2020-04-07 22:05:02 +08:00
$pagination = getPagination ( $pages , $page , $maxShortcuts , $filter -> query_string () . $sortQuery . $limitQuery );
2008-07-14 21:54:50 +08:00
$focusWindow = true ;
2019-02-22 22:19:07 +08:00
$storage_areas = ZM\Storage :: find ();
2018-04-03 21:57:22 +08:00
$StorageById = array ();
foreach ( $storage_areas as $S ) {
$StorageById [ $S -> Id ()] = $S ;
2017-12-10 00:23:50 +08:00
}
2020-08-18 00:56:20 +08:00
xhtmlHeaders ( __FILE__ , translate ( 'Events' ));
2008-07-14 21:54:50 +08:00
?>
< body >
2020-08-23 02:00:53 +08:00
< ? php echo getNavBarHTML () ?>
< div id = " page " class = " container-fluid p-3 " >
2020-08-17 02:44:18 +08:00
<!-- Toolbar button placement and styling handled by bootstrap - tables -->
2020-08-16 04:27:58 +08:00
< div id = " toolbar " >
2020-08-19 05:57:03 +08:00
< button id = " backBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Back') ?> " disabled >< i class = " fa fa-arrow-left " ></ i ></ button >
2020-08-17 02:44:18 +08:00
< button id = " refreshBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Refresh') ?> " >< i class = " fa fa-refresh " ></ i ></ button >
< button id = " tlineBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('ShowTimeline') ?> " >< i class = " fa fa-history " ></ i ></ button >
< button id = " viewBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('View') ?> " disabled >< i class = " fa fa-binoculars " ></ i ></ button >
< button id = " archiveBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Archive') ?> " disabled >< i class = " fa fa-archive " ></ i ></ button >
< button id = " unarchiveBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Unarchive') ?> " disabled >< i class = " fa fa-file-archive-o " ></ i ></ button >
< button id = " editBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Edit') ?> " disabled >< i class = " fa fa-pencil " ></ i ></ button >
< button id = " exportBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Export') ?> " disabled >< i class = " fa fa-external-link " ></ i ></ button >
< button id = " downloadBtn " class = " btn btn-normal " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('DownloadVideo') ?> " disabled >< i class = " fa fa-download " ></ i ></ button >
< button id = " deleteBtn " class = " btn btn-danger " data - toggle = " tooltip " data - placement = " top " title = " <?php echo translate('Delete') ?> " disabled >< i class = " fa fa-trash " ></ i ></ button >
2008-07-14 21:54:50 +08:00
</ div >
2020-08-16 04:27:58 +08:00
2020-08-17 02:44:18 +08:00
<!-- Table styling handled by bootstrap - tables -->
2020-08-23 02:00:53 +08:00
< div class = " row justify-content-center " >
2020-08-16 04:27:58 +08:00
< table
id = " eventTable "
data - toggle = " table "
data - pagination = " true "
2020-08-18 00:02:25 +08:00
data - show - pagination - switch = " true "
2020-08-19 04:12:07 +08:00
data - page - list = " [10, 25, 50, 100, 200, All] "
2020-08-16 04:27:58 +08:00
data - search = " true "
data - cookie = " true "
2020-08-17 02:44:18 +08:00
data - cookie - id - table = " zmEventsTable "
data - cookie - expire = " 2y "
2020-08-16 04:27:58 +08:00
data - click - to - select = " true "
data - remember - order = " true "
data - show - columns = " true "
2020-08-21 20:11:57 +08:00
data - show - export = " true "
2020-08-16 04:27:58 +08:00
data - uncheckAll = " true "
data - toolbar = " #toolbar "
data - show - fullscreen = " true "
data - click - to - select = " true "
data - maintain - meta - data = " true "
data - mobile - responsive = " true "
2020-08-19 02:13:32 +08:00
data - buttons - class = " btn btn-normal "
2020-08-27 20:46:52 +08:00
data - show - jump - to = " true "
2020-08-18 00:56:20 +08:00
class = " table-sm table-borderless "
style = " display:none; "
>
2020-08-16 04:27:58 +08:00
< thead >
2020-08-17 02:44:18 +08:00
<!-- Row styling is handled by bootstrap - tables -->
2008-07-14 21:54:50 +08:00
< tr >
2020-08-17 07:00:11 +08:00
< th data - sortable = " false " data - field = " toggleCheck " data - checkbox = " true " ></ th >
2020-08-16 04:27:58 +08:00
< th data - sortable = " true " data - field = " Id " >< ? php echo translate ( 'Id' ) ?> </th>
< th data - sortable = " true " data - field = " Name " >< ? php echo translate ( 'Name' ) ?> </th>
< th data - sortable = " true " data - field = " Archived " >< ? php echo translate ( 'Archived' ) ?> </th>
2020-08-17 03:41:50 +08:00
< th data - sortable = " true " data - field = " Emailed " >< ? php echo translate ( 'Emailed' ) ?> </th>
2020-08-16 04:27:58 +08:00
< th data - sortable = " true " data - field = " Monitor " >< ? php echo translate ( 'Monitor' ) ?> </th>
< th data - sortable = " true " data - field = " Cause " >< ? php echo translate ( 'Cause' ) ?> </th>
< th data - sortable = " true " data - field = " AttrStartTime " >< ? php echo translate ( 'AttrStartTime' ) ?> </th>
< th data - sortable = " true " data - field = " AttrEndTime " >< ? php echo translate ( 'AttrEndTime' ) ?> </th>
< th data - sortable = " true " data - field = " Duration " >< ? php echo translate ( 'Duration' ) ?> </th>
< th data - sortable = " true " data - field = " Frames " >< ? php echo translate ( 'Frames' ) ?> </th>
< th data - sortable = " true " data - field = " AlarmBrFrames " >< ? php echo translate ( 'AlarmBrFrames' ) ?> </th>
< th data - sortable = " true " data - field = " TotalBrScore " >< ? php echo translate ( 'TotalBrScore' ) ?> </th>
< th data - sortable = " true " data - field = " AvgBrScore " >< ? php echo translate ( 'AvgBrScore' ) ?> </th>
< th data - sortable = " true " data - field = " MaxBrScore " >< ? php echo translate ( 'MaxBrScore' ) ?> </th>
2017-05-31 01:47:30 +08:00
< ? php
2018-04-03 21:57:22 +08:00
if ( count ( $storage_areas ) > 1 ) {
?>
2020-08-16 04:27:58 +08:00
< th data - sortable = " true " data - field = " Storage " >< ? php echo translate ( 'Storage' ) ?> </th>
2018-04-03 21:57:22 +08:00
< ? php
}
2017-10-19 00:43:51 +08:00
if ( ZM_WEB_EVENT_DISK_SPACE ) {
?>
2020-08-16 04:27:58 +08:00
< th data - sortable = " true " data - field = " DiskSpace " >< ? php echo translate ( 'DiskSpace' ) ?> </th>
2008-07-14 21:54:50 +08:00
< ? php
2017-05-31 01:47:30 +08:00
}
if ( ZM_WEB_LIST_THUMBS ) {
2008-07-14 21:54:50 +08:00
?>
2020-08-16 04:27:58 +08:00
< th data - sortable = " false " data - field = " Thumbnail " >< ? php echo translate ( 'Thumbnail' ) ?> </th>
2008-07-14 21:54:50 +08:00
< ? php
2017-05-31 01:47:30 +08:00
}
2008-07-14 21:54:50 +08:00
?>
</ tr >
2020-08-16 04:27:58 +08:00
</ thead >
< tbody >
2008-07-14 21:54:50 +08:00
< ? php
2020-08-18 04:58:37 +08:00
$count = 0 ;
$disk_space_total = 0 ;
if ( $results ) {
2020-08-28 05:16:10 +08:00
$events = array ();
2020-08-18 04:58:37 +08:00
while ( $event_row = dbFetchNext ( $results ) ) {
$event = new ZM\Event ( $event_row );
2020-08-18 05:41:50 +08:00
if ( ! $filter -> test_post_sql_conditions ( $event ) ) {
2020-08-28 05:16:10 +08:00
$event -> remove_from_cache ();
2020-08-18 05:41:50 +08:00
continue ;
}
2020-08-28 05:16:10 +08:00
$events [] = $event ;
2020-08-31 22:37:35 +08:00
if ( $limit and ( count ( $events ) >= $limit ) ) {
2020-08-28 05:16:10 +08:00
break ;
}
ZM\Logger :: Debug ( " Have " . count ( $events ) . " events, limit $limit " );
}
foreach ( $events as $event ) {
2020-08-18 04:58:37 +08:00
$scale = max ( reScale ( SCALE_BASE , $event -> DefaultScale (), ZM_WEB_DEFAULT_SCALE ), SCALE_BASE );
2019-08-28 21:19:09 +08:00
?>
2020-08-18 00:56:20 +08:00
< tr < ? php echo $event -> Archived () ? ' class="archived"' : '' ?> >
2020-08-16 04:27:58 +08:00
< td data - checkbox = " true " ></ td >
< td >< a href = " ?view=event&eid=<?php echo $event->Id (). $filterQuery . $sortQuery .'&page=1 " > ' . $event -> Id () ?> </a></td>
2020-08-17 03:41:50 +08:00
2020-08-17 03:46:56 +08:00
< td >< a href = " ?view=event&eid=<?php echo $event->Id (). $filterQuery . $sortQuery .'&page=1 " > ' . validHtmlStr ( $event -> Name ()) ?> </a>
2020-08-17 03:41:50 +08:00
< ? php
2020-08-18 00:56:20 +08:00
$archived = $event -> Archived () ? translate ( 'Archived' ) : '' ;
$emailed = $event -> Emailed () ? ' ' . translate ( 'Emailed' ) : '' ;
2020-08-17 04:19:08 +08:00
echo '<br/><div class="small text-nowrap text-muted">' . $archived . $emailed . '</div>' ;
2020-08-17 03:41:50 +08:00
?>
</ td >
< td class = " text-center " >< ? php echo ( $event -> Archived () ) ? 'Yes' : 'No' ?> </td>
< td class = " text-center " >< ? php echo ( $event -> Emailed () ) ? 'Yes' : 'No' ?> </td>
2020-09-15 23:31:14 +08:00
< td >< ? php echo makeLink ( '?view=monitor&mid=' . $event -> MonitorId (), $event -> MonitorName (), canEdit ( 'Monitors' ) ) ?> </td>
2020-09-15 22:50:53 +08:00
< td >< ? php echo makeLink ( '#' , validHtmlStr ( $event -> Cause ()), canEdit ( 'Events' ), 'title="' . htmlspecialchars ( $event -> Notes ()) . '" class="eDetailLink" data-eid=' . $event -> Id () . '"' ) ?>
< ? php
2020-08-17 03:41:50 +08:00
# 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>' ;
}
}
?>
2019-02-11 23:58:34 +08:00
</ td >
2020-08-17 03:41:50 +08:00
2020-08-16 04:27:58 +08:00
< td >< ? php echo strftime ( STRF_FMT_DATETIME_SHORTER , strtotime ( $event -> StartTime ())) ?> </td>
2020-08-18 00:56:20 +08:00
< td >< ? php echo strftime ( STRF_FMT_DATETIME_SHORTER , strtotime ( $event -> EndTime ())) ?> </td>
2020-08-24 21:23:24 +08:00
< td >< ? php echo gmdate ( 'H:i:s' , $event -> Length () ) ?> </td>
2020-08-20 01:04:08 +08:00
< td >< a href = " ?view=frames&eid=<?php echo $event->Id () ?> " >< ? php echo $event -> Frames () ?> </a></td>
< td >< a href = " ?view=frames&eid=<?php echo $event->Id () ?> " >< ? php echo $event -> AlarmFrames () ?> </a></td>
2020-08-16 04:27:58 +08:00
< td >< ? php echo $event -> TotScore () ?> </td>
< td >< ? php echo $event -> AvgScore () ?> </td>
2020-09-15 23:37:05 +08:00
< td >< ? php echo makeLink ( '?view=frame&eid=' . $event -> Id () . '&fid=0' , $event -> MaxScore ()); ?> </td>
2008-07-14 21:54:50 +08:00
< ? php
2018-04-03 21:57:22 +08:00
if ( count ( $storage_areas ) > 1 ) {
?>
2020-08-16 04:27:58 +08:00
< td >
2019-08-29 23:27:06 +08:00
< ? 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 >
2018-04-03 21:57:22 +08:00
< ? php
}
2017-05-31 01:47:30 +08:00
if ( ZM_WEB_EVENT_DISK_SPACE ) {
2017-10-19 00:43:51 +08:00
$disk_space_total += $event -> DiskSpace ();
2017-05-31 01:47:30 +08:00
?>
2020-08-16 04:27:58 +08:00
< td class = " colDiskSpace " >< ? php echo human_filesize ( $event -> DiskSpace ()) ?> </td>
2008-07-14 21:54:50 +08:00
< ? php
2017-05-31 01:47:30 +08:00
}
if ( ZM_WEB_LIST_THUMBS ) {
2020-08-16 04:27:58 +08:00
echo '<td class="colThumbnail zoom">' ;
2019-12-03 04:34:23 +08:00
$imgSrc = $event -> getThumbnailSrc ( array (), '&' );
2018-09-08 04:31:11 +08:00
$streamSrc = $event -> getStreamSrc ( array (
2020-03-30 22:09:53 +08:00
'mode' => 'jpeg' , 'scale' => $scale , 'maxfps' => ZM_WEB_VIDEO_MAXFPS , 'replay' => 'single' , 'rate' => '400' ), '&' );
2017-05-06 02:25:25 +08:00
2019-09-04 22:11:16 +08:00
$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 . '"/>' ;
2018-01-22 10:27:01 +08:00
echo '<a href="?view=event&eid=' . $event -> Id () . $filterQuery . $sortQuery . '&page=1">' . $imgHtml . '</a>' ;
2018-04-15 22:27:08 +08:00
echo '</td>' ;
2017-05-31 01:47:30 +08:00
} // end if ZM_WEB_LIST_THUMBS
2008-07-14 21:54:50 +08:00
?>
</ tr >
< ? php
2020-08-28 05:16:10 +08:00
} # end foreach row
2008-07-14 21:54:50 +08:00
?>
</ tbody >
2017-10-19 00:43:51 +08:00
< ? php
2020-08-18 04:58:37 +08:00
} # end if $results
2017-10-19 00:43:51 +08:00
if ( ZM_WEB_EVENT_DISK_SPACE ) {
?>
2018-09-08 04:31:11 +08:00
< tfoot >
< tr >
2017-10-19 00:43:51 +08:00
< td colspan = " 11 " > Totals :</ td >
2018-04-03 21:57:22 +08:00
< ? php
if ( count ( $storage_areas ) > 1 ) {
?>
2018-09-08 04:31:11 +08:00
< td class = " colStorage " ></ td >
2018-04-03 21:57:22 +08:00
< ? php
}
?>
2018-04-15 22:27:08 +08:00
< td class = " colDiskSpace " >< ? php echo human_filesize ( $disk_space_total ) ?> </td>
2017-10-19 00:43:51 +08:00
< ? php
if ( ZM_WEB_LIST_THUMBS ) {
2018-09-08 04:31:11 +08:00
?>
< td ></ td >
2017-10-19 00:43:51 +08:00
< ? php
}
2018-09-08 04:31:11 +08:00
?>
< td ></ td >
2017-10-19 00:43:51 +08:00
</ tr >
</ tfoot >
< ? php
}
?>
2008-07-14 21:54:50 +08:00
</ table >
2020-08-16 04:27:58 +08:00
</ div >
2008-07-14 21:54:50 +08:00
</ div >
2020-09-03 05:55:23 +08:00
< ? php xhtmlFooter () ?>