Commit Graph
48 Commits
Author SHA1 Message Date
Isaac ConnorandClaude Opus 5 9c06eb6ba2 refactor: connect to the database on first use, not on include
database.php called dbConnect() at file scope, so including it opened a socket,
and on failure rendered views/no_database_connection.php and exit()ed from
inside a library include. Every model in web/includes requires this file, so
merely loading a class did both.

Connect on first use instead. $dbConn becomes tri-state - false for "not
attempted", null for "attempt failed", a PDO for connected - and two accessors
sit on top of it:

  zmDbConn()        opens if needed; on failure renders the error view and
                    stops, which is what the include used to do, just at the
                    point a query is actually attempted.
  zmDbConnOrNull()  opens if needed but returns null instead of ending the
                    request, for callers with a fallback.

dbQuery() is the funnel every fetch helper goes through, so routing it plus
dbEscape(), dbError() and dbInsertId() through the accessors covers the library.
The five callers that reached for the raw global are updated: config.php.in,
Event.php and ajax/console.php need a connection and take zmDbConn(); logger.php
takes zmDbConnOrNull() and falls through to its error_log target, so a logging
call can no longer end the request or open a connection by itself.

ZMSessionHandler captured $dbConn in its constructor. It is constructed while
session.php is being included, before anything has needed the database, so with
a lazy connection that captured false. It now resolves per call and its methods
return "no session" rather than dereferencing a bool.

Two smaller fixes fall out. The error view was included by a relative path that
only resolved when the cwd was web/, so it never worked for requests served out
of web/api/; it is now anchored with __DIR__. And dbDisconnect() set $dbConn to
null, which in the new tri-state means "connecting failed" and would send the
next query to the error page; it sets false so a later query can reconnect.
Nothing calls dbDisconnect() today.

This does NOT make database.php includable without a database. It requires
logger.php, which requires config.php, which reads ZoneMinder's configuration
out of the Config table at include time. Until that cycle is broken the
connection still happens during bootstrap, just from config.php rather than from
here.

Tests: tests/php/test_database_lazy_connect.php, 7 assertions, all pass. It
tokenises database.php and asserts nothing runs at include time, that dbQuery()
goes through the accessor, and that only the connection plumbing touches the
global. Verified it reports the pre-refactor file's `if ( !dbConnect() )` - an
earlier version of the check skipped tokens inside parentheses and so passed on
exactly the code it exists to reject.

Not covered by tests: behaviour when the database is genuinely unreachable, and
the session handler against a live database. Needs manual testing on an
installed tree, including stopping mysql to confirm the error view still renders
for both a web request and an API request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01477mR97vfnK6zczbHgzq6T
2026-08-17 20:52:10 -04:00
Isaac Connor e6befbd4a5 feat: list deleted monitors from the console Status filter
Deleted monitors are excluded from every monitor listing, so once a monitor
is deleted there is no way to find it again from the ui - which matters
because deleting is reversible, the monitor edit form has an undelete
checkbox for exactly that.

Add Deleted as a pseudo status in the Status filter. Selected on its own it
lists only the deleted monitors; selected alongside real statuses it adds
them to that selection rather than intersecting with it, which would always
be empty; not selected, listings stay restricted to live monitors as before.

Deleted is deliberately not matched against Monitor_Status. Whatever row a
deleted monitor left behind is stale - its daemons were stopped when it was
deleted - so filtering on it would drop the monitors we are trying to find.
For the same reason a deleted monitor is reported as Deleted rather than the
status on that row, is drawn with the error dot, is labelled in the list,
and does not get a link to a stream that is not running.

The three queries that hardcoded Deleted=false now share one function, so
the console page, the console ajax endpoint and getFilteredMonitorIds()
cannot disagree about what the filter means. Each passes its own status
column expression, which differ: the ajax endpoint coalesces a WebSite
monitor to Running.

tests/php/test_monitor_status_filter.php covers the sql and the bind value
ordering for all four cases, including a bare string from a cookie written
before the filter became a multi-select. Verified against a live install:
13 deleted and 19 live monitors return 19 with no filter, 13 for Deleted,
and 20 for Deleted plus NotRunning.
2026-08-08 15:41:20 -04:00
IgorA100 41ffa7762f Merge branch 'master' into patch-673172 2026-07-14 18:33:48 +03:00
IgorA100 50d4eaa1cc Specify the "data-stream-channel" attribute. (console.php) 2026-06-25 18:43:39 +03:00
IgorA100 fc6b042d3f In the "SRC" attribute for thumbs, use mode=single instead of mode=jpeg&frames=1 to avoid a long, catastrophic spike in CPU usage when refreshing the Console page. (console.php) 2026-06-09 17:39:03 +03:00
Isaac ConnorandClaude Opus 4.7 19cc1b89b6 fix: only show 'Use ONVIF' badge on console when listener is enabled
web/ajax/console.php was returning ONVIF_Alarm_Text under the
ONVIF_Event_Listener key whenever the column existed (always), so
console.js displayed "Use ONVIF 'MotionAlarm'" for every monitor
regardless of whether the listener was actually enabled.

Gate the alarm text on the actual ONVIF_Event_Listener boolean,
returning 0 otherwise so the JS falsy check works as intended.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 18:30:26 -04:00
copilot-swe-agent[bot]andconnortechnology b2d7d6065c fix: use getSkinFile() for _monitor_filters.php include path in console.php
Agent-Logs-Url: https://github.com/ZoneMinder/zoneminder/sessions/ec7e935d-1966-49f1-b782-669b625cd648

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-05-15 22:30:11 +00:00
copilot-swe-agent[bot]andconnortechnology b4a2146afd fix: use getFilterSelection() and validCardinal() per reviewer feedback
- Remove getFilterFromRequestOrCookie(); require _monitor_filters.php and
  call getFilterSelection() directly instead (addresses duplicate logic)
- Replace filter_var(FILTER_VALIDATE_INT) with validCardinal() for
  consistency with existing codebase utility functions
- Guard MonitorName and Source against getFilterSelection() returning an
  array when the cookie value happens to be valid JSON

refs #4745

Agent-Logs-Url: https://github.com/ZoneMinder/zoneminder/sessions/3d5e3926-51cc-4da8-8707-eb82c7d5db29

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-05-15 12:00:56 +00:00
copilot-swe-agent[bot]andconnortechnology 4e64ea6b6b fix: use filter_var FILTER_VALIDATE_INT for stricter ID validation in queryRequest
Agent-Logs-Url: https://github.com/ZoneMinder/zoneminder/sessions/4f4372ca-129e-4845-93a2-75ee9c7ecede

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-05-14 23:38:15 +00:00
copilot-swe-agent[bot]andconnortechnology cbee86f397 fix: GroupId filter persists after browser refresh on Console view
- Add getFilterFromRequestOrCookie() helper that reads filter values from
  $_REQUEST first, then falls back to zmFilter_* cookies, mirroring the
  getFilterSelection() behavior on the PHP page-render side
- All monitor filters now use this helper so they persist after F5/navigation
- Replace plain SQL subquery for GroupId with Group::get_group_sql() which
  correctly includes monitors in child groups, consistent with the PHP side
- Add integer validation for ID-based filters (GroupId, ServerId, StorageId,
  MonitorId) to guard against tampered cookie values
- Add require_once for Group.php in queryRequest()

fixes #4745

Agent-Logs-Url: https://github.com/ZoneMinder/zoneminder/sessions/4f4372ca-129e-4845-93a2-75ee9c7ecede

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-05-14 23:37:14 +00:00
IgorA100 0ac2359c77 Update console.php 2026-04-27 19:12:10 +03:00
Isaac ConnorandClaude Opus 4.6 82677cd91e feat: replace console CSV export with JSON monitor export
Remove the bootstrap-table HTML export which included raw span tags
in output. Replace with a proper JSON export containing all monitor
fields, zones, and group names suitable for re-import. Use a
temporary anchor element for download to avoid blanking the page.
Also move Source column status class from span to td via
bootstrap-table _class attribute.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 11:06:44 -04:00
Isaac ConnorandClaude Opus 4.6 61b025b85f fix: calculate optimal thumbnail overlay scale from monitor dimensions
Add data-monitor-width and data-monitor-height attributes to thumbnail
img elements in console.php, events.php, watch.php, and monitor.php.
Use these to calculate the scale parameter as a ratio of overlay size to
monitor native resolution, clamped to 5-100%, instead of hardcoding
scale=75 (overlay) and scale=32 (fallback).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 12:16:56 -05:00
Isaac ConnorandClaude Opus 4.5 eae89025ee refactor: rename RTSP2WebStream to StreamChannel
Rename applies to Go2RTC, Janus, and RTSP2Web streaming options.
Update enum values from Primary/Secondary to Restream/CameraDirectPrimary/CameraDirectSecondary.

- Add db migration zm_update-1.37.79.sql to rename column and migrate data
- Update C++ enum StreamChannelOption and member stream_channel
- Update PHP getStreamChannelOptions() method
- Update all JavaScript references
- Auto-select CameraDirectPrimary when Restream option becomes disabled

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 19:37:08 -05:00
Isaac Connor cbbdeb2910 Merge branch 'master' of github.com:ZoneMinder/zoneminder 2026-01-30 11:41:09 -05:00
Isaac Connor 41d3a25964 Use a smarted calculation to determine an optimal streaming scale. 2026-01-30 11:40:33 -05:00
BHMSD-bdailey 0b2d14d552 Fix Issue when a current recording is occurring and a thumbnail is attempted to be made. 2026-01-29 21:56:40 -05:00
Ben DaileyandClaude Opus 4.5 fd5bd63808 feat: add status bar to thumbnail overlay with LIVE indicator and wall clock time
- Add status bar below video with LIVE indicator for live streams
- Show pulsing red dot animation for live streams
- Display wall clock time that updates as recorded video plays
- Add event start time data attribute to console and events pages
- Hide status bar when no content to display

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 21:09:57 -05:00
Ben DaileyandClaude Opus 4.5 d51790531a feat: add live streaming support to console thumbnail hover overlay
- Support go2rtc, RTSP2Web, and Janus streaming in thumbnail popups
- Separate still thumbnail logic from hover overlay streaming
- Still thumbnails use event snapshot when not decoding
- Hover overlay prioritizes live streaming over recorded video
- Refactor thumbnail JS into focused helper functions
- Fix video-stream.js path for dynamic import

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 20:50:50 -05:00
Ben DaileyandClaude Opus 4.5 3f69df433b Merge branch 'master' into ChangeThumbnails
Resolved conflict in web/ajax/console.php:
- Incorporated master's improved $streamSrc computation (modifies $options in place)
- Kept our streaming priority logic (go2rtc > rtsp2web > janus > event fallback)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 20:03:36 -05:00
Ben DaileyandClaude Opus 4.5 7c2dd47c75 fix: prioritize external streaming over event fallback in console thumbnails
Go2rtc, rtsp2web, and janus work independently of ZM's decode/analyze
processes. Check for these external streaming methods before checking
Analysing/Decoding state to ensure live streaming is used when available.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 17:44:52 -05:00
Isaac Connor b373f44476 Ensure that we have mode=jpeg in the stream-src. Also remove frames option so that it actually streams. Hopefully fixes thumbnails not working 2026-01-28 10:40:08 -05:00
Ben DaileyandClaude Opus 4.5 ee229d4257 feat: add event thumbnail fallback and go2rtc support for console hover overlay
When a monitor is not analyzing or decoding, the console thumbnail now
shows the most recent event's snapshot instead of attempting a live
stream. The hover overlay plays the event replay (with mp4 support if
available).

For active monitors with go2rtc enabled, the hover overlay now uses
go2rtc WebRTC streaming via the video-stream custom element, with a
3-second fallback to MJPEG if the connection fails.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-28 10:39:34 -05:00
Isaac Connor 5162df68dd Make tfoot elements clickable the way they were before 2026-01-28 10:02:58 -05:00
Isaac Connor 2260243a9c Don't check for overall canViewMonitors because if we are limiting the monitors that a user can view, Monitors=None 2026-01-27 07:55:32 -05:00
Isaac Connor e1c41a980c Actually include Manufacturer and Model in results 2026-01-20 22:18:55 -05:00
Isaac Connor 41ce8a2541 Add Manufacturer and Model to console 2026-01-17 12:32:47 -05:00
copilot-swe-agent[bot]andconnortechnology dd657bb5d2 fix: Use 'Monitor' attribute instead of 'MonitorId' in filter
This matches the existing filter attribute naming convention used throughout ZoneMinder.

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-09 14:30:55 +00:00
copilot-swe-agent[bot]andconnortechnology c97e2b4090 feat: Add StartDateTime filters to console event count links
- Modified web/ajax/console.php to generate filter querystrings for each event period (Hour, Day, Week, Month, Archived, Total)
- Modified web/skins/classic/views/js/console.js to use filter querystrings in event links
- Links now include proper date filters matching old console.php implementation

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-09 14:29:48 +00:00
copilot-swe-agent[bot]andconnortechnology a0f9194280 Add Sequence field to AJAX response data for proper sorting
- Added Sequence field to row data in ajax/console.php
- Sequence is now available for bootstrap-table to sort by (already configured as default)
- Sequence column remains hidden (not defined in table headers)
- Ensures table sorts by monitor sequence order by default

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 18:05:44 +00:00
copilot-swe-agent[bot]andconnortechnology ba316a9c83 Make ajax/console.php stateless by using REQUEST instead of SESSION
- Removed session access and manipulation code
- Changed from session_filters to request_filters using $_REQUEST directly
- Removed zm_session_start() and session_write_close() calls
- AJAX handler now stateless, getting all filter values from request parameters

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 17:45:03 +00:00
copilot-swe-agent[bot]andconnortechnology 5a7b18620e Add missing MonitorId filter implementation in AJAX console handler
- Added MonitorId to session_filters array
- Implemented MonitorId filtering logic to filter monitors by selected IDs
- Handles both single value and array of monitor IDs

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 17:10:42 +00:00
copilot-swe-agent[bot]andconnortechnology 579e9a1d6c Add params.data initialization and improve type handling
- Initialize params.data to empty object if undefined to prevent errors
- Improve validation logic to consistently handle arrays vs strings
- Make type checking more explicit and readable

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 16:48:03 +00:00
copilot-swe-agent[bot]andconnortechnology 400b44b823 Improve array field handling and value validation
- Fixed array field detection in ajaxRequest using endsWith('[]')
- Improved multi-value field detection in monitorFilterOnChange
- Fixed empty value check to properly handle '0' as valid value
- Added proper initialization of array fields in params.data

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 16:46:17 +00:00
copilot-swe-agent[bot]andconnortechnology 7bcbde9639 Fix cookie naming consistency and simplify empty check
- Fixed cookie naming to use consistent names without array brackets
- Updated JavaScript to separate field names from cookie names
- Simplified empty value check in AJAX handler using empty()
- Consolidated cookie restoration logic in _monitor_filters.php

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 16:43:58 +00:00
copilot-swe-agent[bot]andconnortechnology cd0f1b9b07 Add cookie fallback for filter persistence and fix empty array check
- Added cookie restoration in _monitor_filters.php as fallback when session is empty
- Fixed empty array comparison in AJAX console handler

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 16:38:58 +00:00
copilot-swe-agent[bot]andconnortechnology 62e86716af Fix monitor filter AJAX and Group dropdown onChange handler
- Updated Group::get_group_dropdown() to accept view parameter and use monitorFilterOnChange for console view
- Updated ajaxRequest in console.js to include filter form data in params.data
- Added session update logic in AJAX console handler to persist filter selections
- Added cookie storage in monitorFilterOnChange for client-side persistence

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 16:36:53 +00:00
copilot-swe-agent[bot]andconnortechnology 61137ac78c Add bandwidth units to Function column display
Merged commit 52ea542 from SteveGilvarry/ZoneMinder.

Bandwidth was showing as a raw number without units, making it
difficult to interpret. Now formats bandwidth with appropriate
units (B/s, kB/s, MB/s, GB/s) using human_filesize() function
with 1024 as the conversion step.

Server-side formatting is consistent with event disk space
formatting and reduces client-side processing.

Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 14:50:02 +00:00
copilot-swe-agent[bot]andconnortechnology 185651b659 Add dynamic footer totals generation via AJAX
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-07 00:33:03 +00:00
copilot-swe-agent[bot]andconnortechnology 9f67994025 Fix filtering and remove unnecessary ZM_WEB_LIST_THUMBS variable
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2026-01-06 22:56:05 +00:00
copilot-swe-agent[bot]andconnortechnology 81bcdb4567 Address code review feedback: improve efficiency and fix event bindings
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2025-12-26 17:31:52 +00:00
copilot-swe-agent[bot]andconnortechnology f02d74c4ed Fix session handling and monitor ID extraction in bootstrap-table implementation
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2025-12-26 17:29:21 +00:00
copilot-swe-agent[bot]andconnortechnology 9528502ea7 Implement bootstrap-table with AJAX for console view
Co-authored-by: connortechnology <925519+connortechnology@users.noreply.github.com>
2025-12-26 17:26:30 +00:00
Alejandro Criado-Pérez 6fd119157a Text corrections 2023-08-27 02:00:59 +02:00
Isaac Connor 969baa3891 Convert user from an array to a User object 2023-04-23 12:57:29 -04:00
Isaac Connor dd0ce50c17 quotes and improve the output of the ajaxError to say what the action was and who the user was 2020-02-06 13:21:30 -05:00
Isaac Connor 8dd8888975 Php namespace (#2537)
* experiment with namespaces on the Server class

* experiment with namespaces on the Server class

* Implement the ZM namespace on objects

* Implement the ZM namespace on objects

* Implement the ZM namespace on objects
2019-02-22 09:19:07 -05:00
Isaac Connor b9736ad2f2 merge from sa the ajax file to apply the sorting. 2017-05-25 14:08:04 -04:00