From d4c817328c994edc241b798a663a6e08b80d5a65 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 25 Aug 2022 16:46:46 -0400 Subject: [PATCH 01/14] Drop severity of log looking for @ because auth gets removed from Path --- web/skins/classic/views/js/monitor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/monitor.js b/web/skins/classic/views/js/monitor.js index 7c15ac8cd..2cf1c464c 100644 --- a/web/skins/classic/views/js/monitor.js +++ b/web/skins/classic/views/js/monitor.js @@ -368,7 +368,7 @@ function change_Path(event) { // check the formatting of the url var authSeparatorPos = pathInput.value.indexOf( '@', protoPrefixPos+3 ); if ( authSeparatorPos == -1 ) { - console.warn('ignoring URL incorrectly formatted, missing "@"'); + console.log('ignoring URL without "@"'); return; } From 3c2db0d53dd4117dc8b347475ab9d255f600a583 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Thu, 25 Aug 2022 16:53:15 -0400 Subject: [PATCH 02/14] Remove boot strap class styling and re-implement it in css so as to use semantic html --- web/skins/classic/css/base/views/monitor.css | 17 +- web/skins/classic/views/monitor.php | 250 +++++++++---------- 2 files changed, 129 insertions(+), 138 deletions(-) diff --git a/web/skins/classic/css/base/views/monitor.css b/web/skins/classic/css/base/views/monitor.css index 160ff8f5d..a427c9c5e 100644 --- a/web/skins/classic/css/base/views/monitor.css +++ b/web/skins/classic/css/base/views/monitor.css @@ -69,17 +69,8 @@ tr td input[type="checkbox"], tr td input[type="radio"] { margin: 6px 0; } -.tab-content, -.tab-content .active { -width: 100%; -} -.tab-content .active table { -width: 100%; -table-layout: fixed; -} -.tab-content .active table tr { - height: 32px; -} -.tab-content .active table td.text-right { -width: 245px; + +.tab-pane td:first-child { + padding-right: 1rem; + text-align: right; } diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 05bba588e..2d53d57f1 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -449,7 +449,7 @@ switch ($name) { $available_monitor_ids = array_diff(range(min($monitor_ids),max($monitor_ids)), $monitor_ids); ?> - +
Id() and count($monitors) ?> - + - + - + - + - + 'None', 'auto'=>'Auto'); foreach ($Servers as $Server) { @@ -526,16 +526,16 @@ switch ($name) { } # end if count($Servers) ?> - + Type()); ?> - + - + - + - + - + visibility - + - + - + translate('Enabled'), '0'=>translate('Disabled')), $monitor->ONVIF_Event_Listener()); ?> - + translate('Enabled'), '0'=>translate('Disabled')), $monitor->use_Amcrest_API()); ?> - + Capturing()); @@ -621,11 +621,11 @@ switch ($name) { if ( ZM_HAS_V4L2 && $monitor->Type() == 'Local' ) { ?> - + - + 'Video For Linux version 2', @@ -641,21 +641,21 @@ echo htmlSelect('newMonitor[Method]', $localMethods, if ( ZM_HAS_V4L2 && $monitor->Method() == 'v4l2' ) { ?> - + Channel()); ?> - + Format()); ?> - + Palette()); ?> - + V4LMultiBuffer() == '1' ? 'checked="checked"' : '' ) ?>/> V4LMultiBuffer() == '0' ? 'checked="checked"' : '' ) ?>/> @@ -664,7 +664,7 @@ echo htmlSelect('newMonitor[Method]', $localMethods, - + Type() == 'VNC' ) { ?> - + - + - + - + visibility @@ -695,20 +695,20 @@ include('_monitor_source_nvsocket.php'); Type() == 'Remote' ) { ?> - + - + visibility - + Protocol(), "updateMethods( this );if(this.value=='rtsp'){\$('RTSPDescribe').setStyle('display','table-row');}else{\$('RTSPDescribe').hide();}" ); ?> - + Protocol() || $monitor->Protocol() == 'http' ) { @@ -720,7 +720,7 @@ include('_monitor_source_nvsocket.php'); - + @@ -728,16 +728,16 @@ include('_monitor_source_nvsocket.php'); } else if ( $monitor->Type() == 'File' ) { ?> - + Type() == 'cURL' ) { ?> - - + + - + visibility @@ -747,7 +747,7 @@ include('_monitor_source_nvsocket.php'); } elseif ( $monitor->Type() == 'WebSite' ) { ?> - + @@ -755,42 +755,42 @@ include('_monitor_source_nvsocket.php'); - () + () - + Type() == 'Ffmpeg' || $monitor->Type() == 'Libvlc' ) { ?> - + - + - + visibility - + Method()) ?> - Type())) ?> + Type())) ?> - + Decoding()); @@ -810,17 +810,17 @@ include('_monitor_source_nvsocket.php'); if ( $monitor->Type() == 'Ffmpeg' ) { ?> - + - + - + @@ -830,11 +830,11 @@ include('_monitor_source_nvsocket.php'); if ( $monitor->Type() != 'NVSocket' && $monitor->Type() != 'WebSite' ) { ?> - + Colours()) ?> - () + () @@ -881,11 +881,11 @@ include('_monitor_source_nvsocket.php'); - + - + Orientation());?> Type() == 'Local' ) { ?> - + Deinterlacing())?> Type() != 'WebSite' ) { ?> - + Deinterlacing())?> Type() == 'Remote' ) { ?> Protocol()!= 'rtsp' ) { echo ' style="display:none;"'; } ?>> - + RTSPDescribe() ) { ?> checked="checked"/> Type() == 'Remote' ?> - + - + - + SecondPath() ? '' : ' style="display:none;"' ?>> - + AnalysisSource()); @@ -968,7 +968,7 @@ include('_monitor_source_nvsocket.php'); - + AnalysisImage()); @@ -976,36 +976,36 @@ include('_monitor_source_nvsocket.php'); - + - + RefBlendPerc()); ?> - + AlarmRefBlendPerc()); ?> - + - + - +
@@ -1055,7 +1055,7 @@ include('_monitor_source_nvsocket.php'); { ?> - + SecondPath() ? '' : ' style="display:none;"' ?>> - + RecordingSource()); @@ -1082,7 +1082,7 @@ include('_monitor_source_nvsocket.php'); - + 'Default'); @@ -1094,7 +1094,7 @@ include('_monitor_source_nvsocket.php'); - + - + translate('Disabled'), @@ -1172,13 +1172,13 @@ echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor - + - + Type() == 'Ffmpeg' ) { ?> RecordAudio() ) { ?> checked="checked"/> @@ -1188,11 +1188,11 @@ echo htmlSelect('newMonitor[OutputContainer]', $videowriter_containers, $monitor - + - + - + JanusEnabled() ? ' checked="checked"' : '' ?>/> - + JanusAudioEnabled() ? ' checked="checked"' : '' ?>/> - + - + Janus_Use_RTSP_Restream() ? ' checked="checked"' : '' ?>/> - + DefaultRate()); ?> - + DefaultScale()); ?> - + translate('Auto'), @@ -1264,19 +1264,19 @@ $codecs = array( { ?> - + - + - + - + LabelSize()) ?> - + - + - + - + - + - + - + - + - + Controllable() ) { ?> checked="checked"/> - + 'lower(Name)')); @@ -1345,31 +1345,31 @@ $codecs = array( - + - + - + ModectDuringPTZ() ) { ?> checked="checked"/> - + - + TrackMotion() ) { ?> checked="checked"/> - + - + translate('None'), @@ -1379,7 +1379,7 @@ $codecs = array( echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnLocation()); ?> - + ReturnL case 'x10' : { ?> - - - + + + ReturnL { ?> - + - + - + - + - + - + - + - + - +      - +      @@ -1465,19 +1465,19 @@ echo htmlSelect('newMonitor[ReturnLocation]', $return_options, $monitor->ReturnL - + Exif() ? ' checked="checked"' : '' ?>/> - + RTSPServer() ? ' checked="checked"' : '' ?>/> - + - + ReturnL case 'location': ?> - + - + - + From 2bb0db96d89868e93f1e582f4b7e1b6e66fbbaf1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 09:31:10 -0400 Subject: [PATCH 03/14] When adjusting start_time, set end_time as well. --- src/zm_event.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zm_event.cpp b/src/zm_event.cpp index 4d288b1d7..a2c75220f 100644 --- a/src/zm_event.cpp +++ b/src/zm_event.cpp @@ -76,7 +76,7 @@ Event::Event( if (start_time.time_since_epoch() == Seconds(0)) { Warning("Event has zero time, setting to now"); - start_time = now; + end_time = start_time = now; } else if (start_time > now) { char buffer[26]; char buffer_now[26]; @@ -92,7 +92,7 @@ Event::Event( Error("StartDateTime in the future. Difference: %" PRIi64 " s\nstarttime: %s\nnow: %s", static_cast(std::chrono::duration_cast(now - start_time).count()), buffer, buffer_now); - start_time = now; + end_time = start_time = now; } unsigned int state_id = 0; From 97e19b78bdab51f37d316b8bd7105faebbc27c36 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 09:31:41 -0400 Subject: [PATCH 04/14] Fixup debug logging in ::Decode. It documents the wrong case --- src/zm_monitor.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/zm_monitor.cpp b/src/zm_monitor.cpp index 6d3b2db94..106dce871 100644 --- a/src/zm_monitor.cpp +++ b/src/zm_monitor.cpp @@ -2662,11 +2662,13 @@ bool Monitor::Decode() { } // end if have convert_context } // end if need transfer to image } else { - Debug(1, "No packet.size(%d) or packet->in_frame(%p). Not decoding", packet->packet->size, packet->in_frame.get()); + Debug(1, "Ret from decode %d, zm_terminate %d", ret, zm_terminate); } } else { Debug(1, "Not Decoding ? %s", Decoding_Strings[decoding].c_str()); } // end if doing decoding + } else { + Debug(1, "No packet.size(%d) or packet->in_frame(%p). Not decoding", packet->packet->size, packet->in_frame.get()); } // end if need_decoding if (packet->image) { From 7ab61ddce27f9634658daf4869d485a56d4a08f8 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 09:37:37 -0400 Subject: [PATCH 05/14] Use uppercase standardized names for MOSQUITTO and MOSTQUITTOPP --- CMakeLists.txt | 4 ++-- cmake/Modules/{FindMosquitto.cmake => FindMOSQUITTO.cmake} | 0 .../Modules/{FindMosquittopp.cmake => FindMOSQUITTOPP.cmake} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename cmake/Modules/{FindMosquitto.cmake => FindMOSQUITTO.cmake} (100%) rename cmake/Modules/{FindMosquittopp.cmake => FindMOSQUITTOPP.cmake} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 523cbdfe8..cd9fb0588 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,7 +440,7 @@ if(NOT ZM_NO_PRCE) endif() if(NOT ZM_NO_MQTT) - find_package(Mosquitto) + find_package(MOSQUITTO) if(MOSQUITTO_FOUND) include_directories(${MOSQUITTO_INCLUDE_DIRS}) list(APPEND ZM_BIN_LIBS "${MOSQUITTO_LIBRARIES}") @@ -449,7 +449,7 @@ if(NOT ZM_NO_MQTT) set(optlibsnotfound "${optlibsnotfound} Mosquitto") endif (MOSQUITTO_FOUND) - find_package(Mosquittopp) + find_package(MOSQUITTOPP) if(MOSQUITTOPP_FOUND) include_directories(${MOSQUITTOPP_INCLUDE_DIRS}) list(APPEND ZM_BIN_LIBS "${MOSQUITTOPP_LIBRARIES}") diff --git a/cmake/Modules/FindMosquitto.cmake b/cmake/Modules/FindMOSQUITTO.cmake similarity index 100% rename from cmake/Modules/FindMosquitto.cmake rename to cmake/Modules/FindMOSQUITTO.cmake diff --git a/cmake/Modules/FindMosquittopp.cmake b/cmake/Modules/FindMOSQUITTOPP.cmake similarity index 100% rename from cmake/Modules/FindMosquittopp.cmake rename to cmake/Modules/FindMOSQUITTOPP.cmake From 35c55a79e02f9adc67e034b71c796add511eb223 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 09:54:05 -0400 Subject: [PATCH 06/14] Use correct format, fix build warnings --- src/zm_logger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zm_logger.cpp b/src/zm_logger.cpp index 963fe5cdc..220721e82 100644 --- a/src/zm_logger.cpp +++ b/src/zm_logger.cpp @@ -387,7 +387,7 @@ void Logger::openFile() { if (mLogFile.size()) { if ( (mLogFileFP = fopen(mLogFile.c_str(), "a")) == nullptr ) { mFileLevel = NOLOG; - Error("fopen() for %s %d, error = %s", mLogFile.c_str(), mLogFile.size(), strerror(errno)); + Error("fopen() for %s %zu, error = %s", mLogFile.c_str(), mLogFile.size(), strerror(errno)); } } else { puts("Called Logger::openFile() without a filename"); From 855dd6ac930b1b4ca71985ee6cbe79c87f30f5cb Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 14:12:25 -0400 Subject: [PATCH 07/14] Use HTTP_X_FORWARDED_HOST or HTTP_X_FORWARDED_SERVER if present to get correct hostname to use when behind a reverse proxy. --- web/includes/Server.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/web/includes/Server.php b/web/includes/Server.php index f976a4236..e1e303627 100644 --- a/web/includes/Server.php +++ b/web/includes/Server.php @@ -39,7 +39,12 @@ class Server extends ZM_Object { } else if ( $this->Id() ) { return $this->{'Name'}; } - if (isset($_SERVER['HTTP_HOST'])) { + + if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { + return $_SERVER['HTTP_X_FORWARDED_HOST']; + } else if (isset($_SERVER['HTTP_X_FORWARDED_SERVER'])) { + return $_SERVER['HTTP_X_FORWARDED_SERVER']; + } else if (isset($_SERVER['HTTP_HOST'])) { # This theoretically will match ipv6 addresses as well if ( preg_match( '/^(\[[[:xdigit:]:]+\]|[^:]+)(:[[:digit:]]+)?$/', $_SERVER['HTTP_HOST'], $matches ) ) { return $matches[1]; From 48377334fe0fa7feaad8e6eb0e6bfe3bb7ce9523 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 14:12:51 -0400 Subject: [PATCH 08/14] Gracefully handle when FrameRate is empty --- web/js/MonitorStream.js | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index c61c3e55d..ef421b876 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -548,25 +548,27 @@ function MonitorStream(monitorData) { const captureFPSValue = $j('#captureFPSValue'+this.id); const analysisFPSValue = $j('#analysisFPSValue'+this.id); - const fpses = respObj.monitor.FrameRate.split(","); - fpses.forEach(function(fps) { - const name_values = fps.split(':'); - const name = name_values[0].trim(); - const value = name_values[1].trim().toLocaleString(undefined, {minimumFractionDigits: 1, maximumFractionDigits: 1}); + if (respObj.monitor.FrameRate) { + const fpses = respObj.monitor.FrameRate.split(","); + fpses.forEach(function(fps) { + const name_values = fps.split(':'); + const name = name_values[0].trim(); + const value = name_values[1].trim().toLocaleString(undefined, {minimumFractionDigits: 1, maximumFractionDigits: 1}); - if (name == 'analysis') { - this.status.analysisfps = value; - if (analysisFPSValue.length && (analysisFPSValue.text() != value)) { - analysisFPSValue.text(value); + if (name == 'analysis') { + this.status.analysisfps = value; + if (analysisFPSValue.length && (analysisFPSValue.text() != value)) { + analysisFPSValue.text(value); + } + } else if (name == 'capture') { + if (captureFPSValue.length && (captureFPSValue.text() != value)) { + captureFPSValue.text(value); + } + } else { + console.log("Unknown fps name " + name); } - } else if (name == 'capture') { - if (captureFPSValue.length && (captureFPSValue.text() != value)) { - captureFPSValue.text(value); - } - } else { - console.log("Unknown fps name " + name); - } - }); + }); + } if (canEdit.Monitors) { if (monitorStatus.enabled) { From d465966069f4243db5722185a6ae9a7e2be2b701 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 26 Aug 2022 14:33:46 -0400 Subject: [PATCH 09/14] Add a back to frames button from view --- web/skins/classic/views/frame.php | 1 + web/skins/classic/views/js/frame.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/web/skins/classic/views/frame.php b/web/skins/classic/views/frame.php index 3331c2354..b6dd5d4ee 100644 --- a/web/skins/classic/views/frame.php +++ b/web/skins/classic/views/frame.php @@ -91,6 +91,7 @@ xhtmlHeaders(__FILE__, translate('Frame').' - '.$Event->Id().' - '.$Frame->Frame
+ diff --git a/web/skins/classic/views/js/frame.js b/web/skins/classic/views/js/frame.js index 6786412f9..5417be926 100644 --- a/web/skins/classic/views/js/frame.js +++ b/web/skins/classic/views/js/frame.js @@ -152,6 +152,12 @@ function initPage() { } else { onStatsResize($j('#base_width').val() * scale / SCALE_BASE); } + + // Manage the FRAMES Button + bindButton('#framesBtn', 'click', null, function onFramesClick(evt) { + evt.preventDefault(); + window.location.assign('?view=frames&eid='+eid); + }); } // Kick everything off From f9f53dd0d2ba9e66284e7f3f8a13093a0d26d1d2 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Mon, 29 Aug 2022 14:10:47 -0400 Subject: [PATCH 10/14] When there are less than 3 storage areas, just list them in the header instead of making it a dropdown --- web/skins/classic/includes/functions.php | 31 +++++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 66e1dda62..241fead9b 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -419,8 +419,7 @@ function getStorageHTML() { $result = ''; if ( !canView('System') ) return $result; - $func = function($S) { - $class = ''; + $func = function($S, $class='') { if ( $S->disk_usage_percent() > 98 ) { $class = 'text-danger'; } else if ( $S->disk_usage_percent() > 90 ) { @@ -428,7 +427,7 @@ function getStorageHTML() { } $title = human_filesize($S->disk_used_space()) . ' of ' . human_filesize($S->disk_total_space()). ( ( $S->disk_used_space() != $S->event_disk_space() ) ? ' ' .human_filesize($S->event_disk_space()) . ' used by events' : '' ); - return ''.validHtmlStr($S->Name()) . ': ' . $S->disk_usage_percent().'%' . ''; + return ''.validHtmlStr($S->Name()) . ': ' . $S->disk_usage_percent().'%' . ''; }; $storage_areas = ZM\Storage::find(array('Enabled'=>true)); @@ -448,15 +447,23 @@ function getStorageHTML() { $class = 'text-warning'; } - $result .= ''.PHP_EOL; + if (count($storage_areas) <= 2) { + $result .= ''.PHP_EOL; + } else { + $result .= ''.PHP_EOL; + } return $result; } From d6fea1c74024ab59137b8474d2b4024d168aeb67 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Aug 2022 10:39:24 -0400 Subject: [PATCH 11/14] Don't specify return type as old php doesn't support it. maybe Fixes #3579 --- web/includes/functions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 749506570..fa0628dee 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -2345,17 +2345,17 @@ function get_subnets($interface) { return $subnets; } -function extract_auth_values_from_url($url): array { +function extract_auth_values_from_url($url) { $protocolPrefixPos = strpos($url, '://'); - if( $protocolPrefixPos === false ) + if ($protocolPrefixPos === false) return array(); $authSeparatorPos = strpos($url, '@', $protocolPrefixPos+3); - if( $authSeparatorPos === false ) + if ($authSeparatorPos === false) return array(); $fieldsSeparatorPos = strpos($url, ':', $protocolPrefixPos+3); - if( $fieldsSeparatorPos === false || $authSeparatorPos < $fieldsSeparatorPos ) + if ($fieldsSeparatorPos === false || $authSeparatorPos < $fieldsSeparatorPos) return array(); $username = substr( $url, $protocolPrefixPos+3, $fieldsSeparatorPos-($protocolPrefixPos+3) ); From b571c818875b1d0c936eef3c42ff7ec8bbcbc9fd Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Tue, 30 Aug 2022 17:42:35 -0400 Subject: [PATCH 12/14] Turn off autocomplete on the monitor form so that browsers don't offer to save the values --- web/skins/classic/views/monitor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/monitor.php b/web/skins/classic/views/monitor.php index 2d53d57f1..be21e0b5f 100644 --- a/web/skins/classic/views/monitor.php +++ b/web/skins/classic/views/monitor.php @@ -428,7 +428,7 @@ if (canEdit('Monitors')) {
-
+ From 683acbbc1dedae846d6a0c274be22831b4674644 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Aug 2022 10:05:52 -0400 Subject: [PATCH 13/14] Clear Manufacturer and Model so that they don't list as changes --- web/includes/actions/monitor.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web/includes/actions/monitor.php b/web/includes/actions/monitor.php index f22221bcb..04ea5e0ef 100644 --- a/web/includes/actions/monitor.php +++ b/web/includes/actions/monitor.php @@ -62,6 +62,7 @@ if ($action == 'save') { } } $newMonitor['ManufacturerId'] = $newManufacturer->Id(); + unset($newMonitor['Manufacturer']); } if (!$newMonitor['ModelId'] and ($newMonitor['Model'] != '')) { @@ -77,6 +78,7 @@ if ($action == 'save') { } } $newMonitor['ModelId'] = $newModel->Id(); + unset($newMonitor['Model']); } $monitor = new ZM\Monitor($mid); From 382b58698627c63774a9dbf73f45e6cc83b90534 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Wed, 31 Aug 2022 10:08:30 -0400 Subject: [PATCH 14/14] Fix typo on dateTimeFormater=>dateTimeFormatter. Fixes #3580. Make conversion to integer on Length explicit to remove warning on php8. --- web/skins/classic/views/export.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/export.php b/web/skins/classic/views/export.php index aa13058bd..7b3dac8ea 100644 --- a/web/skins/classic/views/export.php +++ b/web/skins/classic/views/export.php @@ -155,8 +155,8 @@ while ( $event_row = dbFetchNext($results) ) { MonitorId(), $event->MonitorName(), canEdit('Monitors')) ?> Cause()), canView('Events'), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid="'.$event->Id().'"') ?> format(strtotime($event->StartDateTime())) . -( $event->EndDateTime() ? ' until ' . $dateTimeFormater->format(strtotime($event->EndDateTime())) : '' ) ?> - Length()) ?> +( $event->EndDateTime() ? ' until ' . $dateTimeFormatter->format(strtotime($event->EndDateTime())) : '' ) ?> + Length())) ?> Id(), $event->Frames()) ?> Id(), $event->AlarmFrames()) ?> TotScore() ?>