Merge branch 'master' of github.com:zoneminder/ZoneMinder

This commit is contained in:
Isaac Connor 2020-09-28 09:36:15 -04:00
commit 08273221a3
113 changed files with 2859 additions and 1853 deletions

View File

@ -1,6 +1,6 @@
language: cpp
sudo: required
dist: xenial
dist: bionic
git:
depth: 9999999
notifications:

View File

@ -70,18 +70,19 @@ Docker is a system to run applications inside isolated containers. ZoneMinder, a
Dockerfile contained in this repository. However, there is still work needed to ensure that the main ZM features work
properly and are documented.
## Contribution Model and Development
## Contribution Model and Development
* Source hosted at [GitHub](https://github.com/ZoneMinder/ZoneMinder/)
* Report issues/questions/feature requests on [GitHub Issues](https://github.com/ZoneMinder/ZoneMinder/issues)
* Report issues at [GitHub Issues](https://github.com/ZoneMinder/ZoneMinder/issues)
* Questions/feature requests in [Slack](https://zoneminder-chat.slack.com/) or [forums](https://forums.zoneminder.com)
Pull requests are very welcome! If you would like to contribute, please follow
the following steps. While step 3 is optional, it is preferred.
1. Fork the repo
2. Open an issue at our [GitHub Issues Tracker](https://github.com/ZoneMinder/ZoneMinder/issues).
Describe the bug that you've found, or the feature which you're asking for.
Jot down the issue number (e.g. 456)
Follow the issue template to describe the bug or security issue you found. Please note feature
requests or questions should be posted in our user forum or Slack channel.
3. Create your feature branch (`git checkout -b 456-my-new-feature`)
4. Commit your changes (`git commit -am 'Added some feature'`)
It is preferred that you 'commit early and often' instead of bunching all

View File

@ -13,6 +13,8 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s;
EXECUTE stmt;
UPDATE `Events` SET `SaveJPEGs`=(SELECT `SaveJPEGs` FROM `Monitors` WHERE Monitors.Id = MonitorId) WHERE `SaveJPEGs` IS NULL;
SET @s = (SELECT IF(
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
AND table_name = 'Storage'

View File

@ -5,6 +5,7 @@
Description=ZoneMinder CCTV recording and security system
After=network.target mariadb.service
Requires=mariadb.service
BindsTo=mariadb.service
[Service]
Type=forking

View File

@ -206,8 +206,6 @@ mv -f CakePHP-Enum-Behavior-%{ceb_version} ./web/api/app/Plugin/CakePHP-Enum-Beh
./utils/zmeditconfigdata.sh ZM_OPT_CAMBOZOLA yes
./utils/zmeditconfigdata.sh ZM_OPT_CONTROL yes
./utils/zmeditconfigdata.sh ZM_CHECK_FOR_UPDATES no
./utils/zmeditconfigdata.sh ZM_DYN_SHOW_DONATE_REMINDER no
./utils/zmeditconfigdata.sh ZM_OPT_FAST_DELETE no
%build
# Disable LTO due to top level asm

View File

@ -0,0 +1,91 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: zoneminder
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $network $remote_fs $syslog
# Should-Start: mysql
# Should-Stop: mysql
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Control ZoneMinder as a Service
# Description: ZoneMinder CCTV recording and surveillance system
### END INIT INFO
# chkconfig: 2345 20 20
# Source function library.
. /lib/lsb/init-functions
prog=ZoneMinder
ZM_PATH_BIN="/usr/bin"
RUNDIR="/run/zm"
TMPDIR="/tmp/zm"
command="$ZM_PATH_BIN/zmpkg.pl"
start() {
echo -n "Starting $prog: "
export TZ=:/etc/localtime
mkdir -p "$RUNDIR" && chown www-data:www-data "$RUNDIR"
mkdir -p "$TMPDIR" && chown www-data:www-data "$TMPDIR"
$command start
RETVAL=$?
[ $RETVAL = 0 ] && echo success
[ $RETVAL != 0 ] && echo failure
echo
[ $RETVAL = 0 ] && touch /var/lock/zm
return $RETVAL
}
stop() {
echo -n "Stopping $prog: "
#
# Why is this status check being done?
# as $command stop returns 1 if zoneminder
# is stopped, which will result in
# this returning 1, which will stuff
# dpkg when it tries to stop zoneminder before
# uninstalling . . .
#
result=`$command status`
if [ ! "$result" = "running" ]; then
echo "Zoneminder already stopped"
echo
RETVAL=0
else
$command stop
RETVAL=$?
[ $RETVAL = 0 ] && echo success
[ $RETVAL != 0 ] && echo failure
echo
[ $RETVAL = 0 ] && rm -f /var/lock/zm
fi
}
status() {
result=`$command status`
if [ "$result" = "running" ]; then
echo "ZoneMinder is running"
RETVAL=0
else
echo "ZoneMinder is stopped"
RETVAL=1
fi
}
case "$1" in
'start')
start
;;
'stop')
stop
;;
'restart' | 'force-reload')
stop
start
;;
'status')
status
;;
*)
echo "Usage: $0 { start | stop | restart | status }"
RETVAL=1
;;
esac
exit $RETVAL

View File

@ -2,13 +2,47 @@
set +e
create_db () {
echo "Checking for db"
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
# test if database if already present...
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
echo "Creating zm db"
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
if [ $? -ne 0 ]; then
echo "Error creating db."
exit 1;
fi
else
echo "Db exists."
fi
USER_EXISTS="$(mysql --defaults-file=/etc/mysql/debian.cnf -sse "SELECT EXISTS(SELECT 1 FROM mysql.user WHERE user = '$ZM_DB_USER')")"
if [ $USER_EXISTS -ne 1 ]; then
echo "Creating zm user $ZM_DB_USER"
# This creates the user.
echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi
}
update_db () {
echo "Updating permissions"
echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
zmupdate.pl --nointeractive
zmupdate.pl --nointeractive -f
# Add any new PTZ control configurations to the database (will not overwrite)
zmcamtool.pl --import >/dev/null 2>&1
echo "Done Updating"
}
if [ "$1" = "configure" ]; then
. /etc/zm/zm.conf
for CONFFILE in /etc/zm/conf.d/*.conf; do
. "$CONFFILE"
done
# The logs can contain passwords, etc... so by setting group root, only www-data can read them, not people in the www-data group
chown www-data:root /var/log/zm
chown www-data:www-data /var/lib/zm
@ -20,16 +54,24 @@ if [ "$1" = "configure" ]; then
a2enmod cgi
fi
SYSTEMD=0
if [ -e "/run/systemd/system" ]; then
SYSTEMD=1
echo "detected systemd"
# Ensure zoneminder is stopped
deb-systemd-invoke stop zoneminder.service || exit $?
else
# Ensure zoneminder is stopped
invoke-rc.d zoneminder stop || true
fi
if [ "$ZM_DB_HOST" = "localhost" ]; then
if [ -e "/lib/systemd/system/mysql.service" ] || [ -e "/lib/systemd/system/mariadb.service" ] || [ -e "/etc/init.d/mysql" ]; then
# Ensure zoneminder is stopped
deb-systemd-invoke stop zoneminder.service || exit $?
if [ $SYSTEMD -eq 1 ] && ([ -e "/lib/systemd/system/mysql.service" ] || [ -e "/lib/systemd/system/mariadb.service" ]); then
#
# Get mysql started if it isn't running
#
if [ -e "/lib/systemd/system/mariadb.service" ]; then
DBSERVICE="mariadb.service"
else
@ -42,48 +84,48 @@ if [ "$1" = "configure" ]; then
echo "run sudo systemctl restart $DBSERVICE then run sudo dpkg-reconfigure zoneminder."
exit 1
fi
if ! systemctl is-active --quiet mysql.service mariadb.service; then
# Due to /etc/init.d service autogeneration, mysql.service always returns the status of mariadb.service
# However, mariadb.service will not return the status of mysql.service.
deb-systemd-invoke start $DBSERVICE
fi
# Make sure systemctl status exit code is 0; i.e. the DB is running
if systemctl is-active --quiet "$DBSERVICE"; then
mysqladmin --defaults-file=/etc/mysql/debian.cnf -f reload
# test if database if already present...
if ! $(echo quit | mysql --defaults-file=/etc/mysql/debian.cnf zm > /dev/null 2> /dev/null) ; then
echo "Creating zm db"
cat /usr/share/zoneminder/db/zm_create.sql | mysql --defaults-file=/etc/mysql/debian.cnf
if [ $? -ne 0 ]; then
echo "Error creating db."
exit 1;
fi
# This creates the user.
echo "CREATE USER '${ZM_DB_USER}'@${ZM_DB_HOST} IDENTIFIED BY '${ZM_DB_PASS}';" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
fi
echo "Updating permissions"
echo "GRANT LOCK tables,alter,drop,select,insert,update,delete,create,index,alter routine,create routine,trigger,execute ON ${ZM_DB_NAME}.* TO '${ZM_DB_USER}'@${ZM_DB_HOST};" | mysql --defaults-file=/etc/mysql/debian.cnf mysql
zmupdate.pl --nointeractive
zmupdate.pl --nointeractive -f
# Add any new PTZ control configurations to the database (will not overwrite)
zmcamtool.pl --import >/dev/null 2>&1
echo "Done Updating; starting ZoneMinder."
create_db
update_db
else
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi
elif [ -e "/etc/init.d/mysql" ]; then
#
# Get mysql started if it isn't
#
if ! $(/etc/init.d/mysql status >/dev/null 2>&1); then
service mysql start
fi
if $(/etc/init.d/mysql status >/dev/null 2>&1); then
create_db
update_db
else
echo 'NOTE: MySQL/MariaDB not running; please start mysql and run dpkg-reconfigure zoneminder when it is running.'
fi
else
echo 'MySQL/MariaDB not found; assuming remote server.'
fi
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
fi
deb-systemd-invoke restart zoneminder.service
else
echo "Not doing database upgrade due to remote db server ($ZM_DB_HOST)."
fi
if [ $SYSTEMD -eq 1 ]; then
deb-systemd-invoke restart zoneminder.service
#else
#service zoneminder start || true
fi
#DEBHELPER#

View File

@ -51,7 +51,7 @@ This screen is called the "console" screen in ZoneMinder and shows a summary of
* **A**: The options menu lets you configure many aspects of ZoneMinder. Refer to :doc:`options`.
* **B**: This brings up a color coded log window that shows various system and component level logs. This window is useful if you are trying to diagnose issues. Refer to :doc:`logging`.
* **C**: ZoneMinder allows you to group monitors gor logical separation. This option lets you create new groups, associate monitors to them and edit/delete existing groups.
* **C**: ZoneMinder allows you to group monitors for logical separation. This option lets you create new groups, associate monitors to them and edit/delete existing groups.
* **D**: Filters are a powerful mechanism to perform actions when certain conditions are met. ZoneMinder comes with some preset filters that keep a tab of disk space and others. Many users create their own filters for more advanced actions like sending emails when certain events occur and more. Refer to :doc:`filterevents`.
* **E**: The Cycle option allows you to rotate between live views of each cofigured monitor.
* **F**: The Montage option shows a collage of your monitors. You can customize them including moving them around.

View File

@ -2621,7 +2621,7 @@ our @options = (
},
{
name => 'ZM_WEB_EVENT_SORT_FIELD',
default => 'DateTime',
default => 'StartDateTime',
description => 'Default field the event lists are sorted by',
help => q`
Events in lists can be initially ordered in any way you want.
@ -2633,7 +2633,7 @@ our @options = (
`,
type => {
db_type =>'string',
hint =>'Id|Name|Cause|MonitorName|DateTime|Length|Frames|AlarmFrames|TotScore|AvgScore|MaxScore',
hint =>'Id|Name|Cause|DiskSpace|MonitorName|StartDateTime|Length|Frames|AlarmFrames|TotScore|AvgScore|MaxScore',
pattern =>qr|.|,
format =>q( $1 )
},

View File

@ -146,15 +146,15 @@ sub zmDbGetMonitors {
if ( $function ) {
if ( $function == DB_MON_CAPT ) {
$sql .= " where `Function` >= 'Monitor'";
$sql .= " WHERE `Function` >= 'Monitor'";
} elsif ( $function == DB_MON_ACTIVE ) {
$sql .= " where `Function` > 'Monitor'";
$sql .= " WHERE `Function` > 'Monitor'";
} elsif ( $function == DB_MON_MOTION ) {
$sql .= " where `Function` = 'Modect' or Function = 'Mocord'";
$sql .= " WHERE `Function` = 'Modect' OR `Function` = 'Mocord'";
} elsif ( $function == DB_MON_RECORD ) {
$sql .= " where `Function` = 'Record' or Function = 'Mocord'";
$sql .= " WHERE `Function` = 'Record' OR `Function` = 'Mocord'";
} elsif ( $function == DB_MON_PASSIVE ) {
$sql .= " where `Function` = 'Nodect'";
$sql .= " WHERE `Function` = 'Nodect'";
}
}
my $sth = $dbh->prepare_cached( $sql );

View File

@ -83,7 +83,7 @@ if ( $options{command} ) {
my $server_up;
while ( $tries and ! ( $server_up = connect(CLIENT, $saddr) ) ) {
Debug("Failed to connect to zmcontrol server at $sock_file");
runCommand("zmdc.pl start zmcontrol.pl --id=$id");
runCommand("zmdc.pl start zmcontrol.pl --id $id");
sleep 1;
$tries -= 1;
}
@ -142,9 +142,9 @@ if ( $options{command} ) {
.strftime('%y/%m/%d %H:%M:%S', localtime())
);
$0 = $0." --id=$id";
$0 = $0.' --id '.$id;
my $control = "ZoneMinder::Control::$protocol"->new($id);
my $control = ('ZoneMinder::Control::'.$protocol)->new($id);
my $control_key = $control->getKey();
$control->loadMonitor();

View File

@ -280,8 +280,8 @@ Event::~Event() {
// Should not be static because we might be multi-threaded
char sql[ZM_SQL_LGE_BUFSIZ];
snprintf(sql, sizeof(sql),
"UPDATE Events SET Name='%s%" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
snprintf(sql, sizeof(sql),
"UPDATE Events SET Name='%s%" PRIu64 "', EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64 " AND Name='New Event'",
monitor->EventPrefix(), id, end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames,
@ -294,6 +294,22 @@ Event::~Event() {
sleep(1);
db_mutex.lock();
}
if ( !mysql_affected_rows(&dbconn) ) {
// Name might have been changed during recording, so just do the update without changing the name.
snprintf(sql, sizeof(sql),
"UPDATE Events SET EndTime = from_unixtime(%ld), Length = %s%ld.%02ld, Frames = %d, AlarmFrames = %d, TotScore = %d, AvgScore = %d, MaxScore = %d WHERE Id = %" PRIu64,
end_time.tv_sec,
delta_time.positive?"":"-", delta_time.sec, delta_time.fsec,
frames, alarm_frames,
tot_score, (int)(alarm_frames?(tot_score/alarm_frames):0), max_score,
id);
while ( mysql_query(&dbconn, sql) && !zm_terminate ) {
db_mutex.unlock();
Error("Can't update event: %s reason: %s", sql, mysql_error(&dbconn));
sleep(1);
db_mutex.lock();
}
} // end if no changed rows due to Name change during recording
db_mutex.unlock();
} // Event::~Event()

View File

@ -88,7 +88,7 @@ public:
} Orientation;
typedef enum {
UNKNOWN,
UNKNOWN=-1,
IDLE,
PREALARM,
ALARM,

View File

@ -247,7 +247,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
if ( config.record_diag_images_fifo ) {
FifoDebug(5, "{\"zone\":%d,\"type\":\"ALRM\",\"pixels\":%d,\"avg_diff\":%d}",
id,alarm_pixels, pixel_diff);
id, alarm_pixels, pixel_diff);
}
if ( alarm_pixels ) {
@ -264,11 +264,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
return false;
}
if ( max_alarm_pixels != 0 )
score = (100*alarm_pixels)/max_alarm_pixels;
else
score = (100*alarm_pixels)/polygon.Area();
score = (100*alarm_pixels)/(max_alarm_pixels?max_alarm_pixels:polygon.Area());
if ( score < 1 )
score = 1; /* Fix for score of 0 when frame meets thresholds but alarmed area is not big enough */
Debug(5, "Current score is %d", score);
@ -358,8 +354,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
if ( check_method >= BLOBS ) {
Debug(5, "Checking for blob pixels");
typedef struct { unsigned char tag; int count; int lo_x; int hi_x; int lo_y; int hi_y; } BlobStats;
BlobStats blob_stats[256];
// ICON FIXME Would like to get rid of this memset
memset(blob_stats, 0, sizeof(BlobStats)*256);
uint8_t *spdiff;
uint8_t last_x, last_y;
@ -369,22 +364,15 @@ bool Zone::CheckAlarms(const Image *delta_image) {
int lo_x = ranges[y].lo_x;
int hi_x = ranges[y].hi_x;
pdiff = (uint8_t*)diff_image->Buffer( lo_x, y );
pdiff = (uint8_t*)diff_image->Buffer(lo_x, y);
for ( int x = lo_x; x <= hi_x; x++, pdiff++ ) {
if ( *pdiff == WHITE ) {
Debug(9, "Got white pixel at %d,%d (%p)", x, y, pdiff);
//last_x = (x>lo_x)?*(pdiff-1):0;
//last_y = (y>lo_y&&x>=last_lo_x&&x<=last_hi_x)?*(pdiff-diff_width):0;
last_x = 0;
if ( x > 0 ) {
if ( (x-1) >= lo_x ) {
last_x = *(pdiff-1);
}
}
last_x = ((x > 0) && ( (x-1) >= lo_x )) ? *(pdiff-1) : 0;
last_y = 0;
if (y > 0 ) {
if ( y > 0 ) {
if ( (y-1) >= lo_y && ranges[(y-1)].lo_x <= x && ranges[(y-1)].hi_x >= x ) {
last_y = *(pdiff-diff_width);
}
@ -631,7 +619,7 @@ bool Zone::CheckAlarms(const Image *delta_image) {
}
if ( max_blob_pixels != 0 )
score = (100*alarm_blob_pixels)/(max_blob_pixels);
score = (100*alarm_blob_pixels)/max_blob_pixels;
else
score = (100*alarm_blob_pixels)/polygon.Area();
@ -758,67 +746,42 @@ bool Zone::CheckAlarms(const Image *delta_image) {
}
bool Zone::ParsePolygonString(const char *poly_string, Polygon &polygon) {
Debug(3, "Parsing polygon string '%s'", poly_string);
char *str_ptr = new char[strlen(poly_string)+1];
char *str = str_ptr;
strcpy(str, poly_string);
char *str = (char *)poly_string;
char *ws;
char *cp;
int n_coords = 0;
int max_n_coords = strlen(str)/4;
Coord *coords = new Coord[max_n_coords];
while( true ) {
if ( *str == '\0' ) {
break;
}
ws = strchr(str, ' ');
if ( ws ) {
*ws = '\0';
}
char *cp = strchr(str, ',');
while ( *str != '\0' ) {
cp = strchr(str, ',');
if ( !cp ) {
Error("Bogus coordinate %s found in polygon string", str);
delete[] coords;
delete[] str_ptr;
return false;
} else {
*cp = '\0';
char *xp = str;
char *yp = cp+1;
break;
}
int x = atoi(str);
int y = atoi(cp+1);
Debug(3, "Got coordinate %d,%d from polygon string", x, y);
coords[n_coords++] = Coord(x, y);
int x = atoi(xp);
int y = atoi(yp);
Debug(3, "Got coordinate %d,%d from polygon string", x, y);
#if 0
if ( x < 0 )
x = 0;
else if ( x >= width )
x = width-1;
if ( y < 0 )
y = 0;
else if ( y >= height )
y = height-1;
#endif
coords[n_coords++] = Coord( x, y );
}
ws = strchr(cp+2, ' ');
if ( ws )
str = ws+1;
else
break;
}
polygon = Polygon(n_coords, coords);
} // end while ! end of string
Debug(3, "Successfully parsed polygon string");
//printf( "Area: %d\n", pg.Area() );
//printf( "Centre: %d,%d\n", pg.Centre().X(), pg.Centre().Y() );
if ( n_coords > 2 ) {
Debug(3, "Successfully parsed polygon string %s", str);
polygon = Polygon(n_coords, coords);
} else {
Error("Not enough coordinates to form a polygon!");
n_coords = 0;
}
delete[] coords;
delete[] str_ptr;
return true;
}
return n_coords ? true : false;
} // end bool Zone::ParsePolygonString(const char *poly_string, Polygon &polygon)
bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, Polygon &polygon) {
Debug(3, "Parsing zone string '%s'", zone_string);
@ -827,13 +790,12 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
char *str = str_ptr;
strcpy(str, zone_string);
zone_id = strtol(str, 0, 10);
Debug(3, "Got zone %d from zone string", zone_id);
char *ws = strchr(str, ' ');
if ( !ws ) {
Debug(3, "No initial whitespace found in zone string '%s', finishing", str);
}
zone_id = strtol(str, 0, 10);
Debug(3, "Got zone %d from zone string", zone_id);
if ( !ws ) {
delete[] str_ptr;
return true;
}
@ -841,13 +803,11 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
*ws = '\0';
str = ws+1;
colour = strtol(str, 0, 16);
Debug(3, "Got colour %06x from zone string", colour);
ws = strchr(str, ' ');
if ( !ws ) {
Debug(3, "No secondary whitespace found in zone string '%s', finishing", zone_string);
}
colour = strtol(str, 0, 16);
Debug(3, "Got colour %06x from zone string", colour);
if ( !ws ) {
delete[] str_ptr;
return true;
}
@ -855,27 +815,28 @@ bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, P
str = ws+1;
bool result = ParsePolygonString(str, polygon);
//printf( "Area: %d\n", pg.Area() );
//printf( "Centre: %d,%d\n", pg.Centre().X(), pg.Centre().Y() );
delete[] str_ptr;
return result;
}
} // end bool Zone::ParseZoneString(const char *zone_string, int &zone_id, int &colour, Polygon &polygon)
int Zone::Load(Monitor *monitor, Zone **&zones) {
static char sql[ZM_SQL_MED_BUFSIZ];
db_mutex.lock();
snprintf(sql, sizeof(sql), "select Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,FilterX,FilterY,MinFilterPixels,MaxFilterPixels,MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,OverloadFrames,ExtendAlarmFrames from Zones where MonitorId = %d order by Type, Id", monitor->Id());
snprintf(sql, sizeof(sql), "SELECT Id,Name,Type+0,Units,Coords,AlarmRGB,CheckMethod+0,"
"MinPixelThreshold,MaxPixelThreshold,MinAlarmPixels,MaxAlarmPixels,"
"FilterX,FilterY,MinFilterPixels,MaxFilterPixels,"
"MinBlobPixels,MaxBlobPixels,MinBlobs,MaxBlobs,"
"OverloadFrames,ExtendAlarmFrames"
" FROM Zones WHERE MonitorId = %d ORDER BY Type, Id", monitor->Id());
if ( mysql_query(&dbconn, sql) ) {
Error("Can't run query: %s", mysql_error(&dbconn));
db_mutex.unlock();
return 0;
}
MYSQL_RES *result = mysql_store_result( &dbconn );
MYSQL_RES *result = mysql_store_result(&dbconn);
if ( !result ) {
Error("Can't use query result: %s", mysql_error(&dbconn));
db_mutex.unlock();
@ -944,7 +905,13 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
} else if ( atoi(dbrow[2]) == Zone::PRIVACY ) {
zones[i] = new Zone(monitor, Id, Name, (Zone::ZoneType)Type, polygon);
}
zones[i] = new Zone(monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB, (Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold, MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ), MinFilterPixels, MaxFilterPixels, MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs, OverloadFrames, ExtendAlarmFrames);
zones[i] = new Zone(
monitor, Id, Name, (Zone::ZoneType)Type, polygon, AlarmRGB,
(Zone::CheckMethod)CheckMethod, MinPixelThreshold, MaxPixelThreshold,
MinAlarmPixels, MaxAlarmPixels, Coord( FilterX, FilterY ),
MinFilterPixels, MaxFilterPixels,
MinBlobPixels, MaxBlobPixels, MinBlobs, MaxBlobs,
OverloadFrames, ExtendAlarmFrames);
} // end foreach row
mysql_free_result(result);
return n_zones;
@ -953,9 +920,9 @@ int Zone::Load(Monitor *monitor, Zone **&zones) {
bool Zone::DumpSettings(char *output, bool /*verbose*/) {
output[0] = 0;
sprintf( output+strlen(output), " Id : %d\n", id );
sprintf( output+strlen(output), " Label : %s\n", label );
sprintf( output+strlen(output), " Type: %d - %s\n", type,
sprintf(output+strlen(output), " Id : %d\n", id );
sprintf(output+strlen(output), " Label : %s\n", label );
sprintf(output+strlen(output), " Type: %d - %s\n", type,
type==ACTIVE?"Active":(
type==INCLUSIVE?"Inclusive":(
type==EXCLUSIVE?"Exclusive":(
@ -1020,10 +987,10 @@ void Zone::std_alarmedpixels(
*pdiff = BLACK;
}
}
}
} // end for y = lo_y to hi_y
/* Store the results */
*pixel_count = pixelsalarmed;
*pixel_sum = pixelsdifference;
Debug(7, "STORED pixelsalarmed(%d), pixelsdifference(%d)", pixelsalarmed, pixelsdifference);
}
} // end void Zone::std_alarmedpixels(Image* pdiff_image, const Image* ppoly_image, unsigned int* pixel_count, unsigned int* pixel_sum)

View File

@ -32,15 +32,14 @@ class Monitor;
// This describes a 'zone', or an area of an image that has certain
// detection characteristics.
//
class Zone
{
class Zone {
protected:
struct Range
{
struct Range {
int lo_x;
int hi_x;
int off_x;
};
typedef struct { unsigned char tag; int count; int lo_x; int hi_x; int lo_y; int hi_y; } BlobStats;
public:
typedef enum { ACTIVE=1, INCLUSIVE, EXCLUSIVE, PRECLUSIVE, INACTIVE, PRIVACY } ZoneType;
@ -52,8 +51,8 @@ protected:
int id;
char *label;
ZoneType type;
Polygon polygon;
ZoneType type;
Polygon polygon;
Rgb alarm_rgb;
CheckMethod check_method;
@ -67,17 +66,18 @@ protected:
int min_filter_pixels;
int max_filter_pixels;
BlobStats blob_stats[256];
int min_blob_pixels;
int max_blob_pixels;
int min_blobs;
int max_blobs;
int overload_frames;
int overload_frames;
int extend_alarm_frames;
// Outputs/Statistics
bool alarmed;
bool was_alarmed;
bool alarmed;
bool was_alarmed;
int pixel_diff;
unsigned int alarm_pixels;
int alarm_filter_pixels;
@ -139,8 +139,7 @@ public:
inline Coord GetAlarmCentre() const { return( alarm_centre ); }
inline unsigned int Score() const { return( score ); }
inline void ResetStats()
{
inline void ResetStats() {
alarmed = false;
was_alarmed = false;
pixel_diff = 0;

View File

@ -156,10 +156,14 @@ if [ ! -d "${GITHUB_FORK}_zoneminder_release" ]; then
if [ -d "${GITHUB_FORK}_ZoneMinder.git" ]; then
echo "Using local clone ${GITHUB_FORK}_ZoneMinder.git to pull from."
cd "${GITHUB_FORK}_ZoneMinder.git"
echo "git pull..."
git pull
echo "git fetch..."
git fetch
echo "git checkout $BRANCH"
git checkout $BRANCH
if [ $? -ne 0 ]; then
echo "Failed to switch to branch."
exit 1;
fi;
echo "git pull..."
git pull
cd ../
@ -335,7 +339,7 @@ EOF
dput="Y";
if [ "$INTERACTIVE" != "no" ]; then
read -p "Ready to dput $SC to $PPA ? Y/N...";
read -p "Ready to dput $SC to $PPA ? Y/n...";
if [[ "$REPLY" == [yY] ]]; then
dput $PPA $SC
fi;

View File

@ -361,7 +361,7 @@ elif [ "${OS}" == "debian" ] || [ "${OS}" == "ubuntu" ] || [ "${OS}" == "raspbia
execpackpack
# Try to install and run the newly built zoneminder package
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "xenial" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
if [ "${OS}" == "ubuntu" ] && [ "${DIST}" == "bionic" ] && [ "${ARCH}" == "x86_64" ] && [ "${TRAVIS}" == "true" ]; then
echo "Begin Deb package installation..."
install_deb
fi

33
web/ajax/controlcaps.php Normal file
View File

@ -0,0 +1,33 @@
<?php
if ( !canEdit('Control') ) {
ZM\Warning('Need Control permissions to edit control capabilities');
return;
}
if ( empty($_REQUEST['action']) ) {
ajaxError('Action Not Provided');
return;
} else {
$action = $_REQUEST['action'];
}
if ( isset($_REQUEST['cids']) ) {
$cids = $_REQUEST['cids'];
} else {
ajaxError('At least one Control Id must be Provided.');
return;
}
if ( $action == 'delete' ) {
foreach( $cids as $cid ) {
dbQuery('UPDATE Monitors SET Controllable = 0, ControlId = 0 WHERE ControlId = ?', array($cid));
dbQuery('DELETE FROM Controls WHERE Id = ?', array($cid));
}
} else {
ajaxError('Unrecognised action ' .$_REQUEST['action']);
return;
}
ajaxResponse();
return;
?>

View File

@ -185,7 +185,7 @@ switch ( $_REQUEST['task'] ) {
$Servers = ZM\Server::find();
$servers_by_Id = array();
# There is probably a better way to do this.
foreach ( $servers as $server ) {
foreach ( $Servers as $server ) {
$servers_by_Id[$server->Id()] = $server;
}
@ -245,6 +245,9 @@ switch ( $_REQUEST['task'] ) {
}
$exportKey = substr(md5(rand()), 0, 8);
$exportFile = 'zm-log.'.$exportExt;
// mkdir will generate a warning if it exists, but that is ok
error_reporting(0);
if ( ! ( mkdir(ZM_DIR_EXPORTS) || file_exists(ZM_DIR_EXPORTS) ) ) {
ZM\Fatal('Can\'t create exports dir at \''.ZM_DIR_EXPORTS.'\'');
}
@ -371,8 +374,16 @@ switch ( $_REQUEST['task'] ) {
<'.strtolower($field).'>'.htmlspecialchars($value).'</'.strtolower($field).'>
</filter>' );
fwrite( $exportFP,
' <columns>
<column field="datetime">'.translate('DateTime').'</column><column field="component">'.translate('Component').'</column><column field="'.translate('Server').'</column><column field="pid">'.translate('Pid').'</column><column field="level">'.translate('Level').'</column><column field="message">'.translate('Message').'</column><column field="file">'.translate('File').'</column><column field="line">'.translate('Line').'</column>
'
<columns>
<column field="datetime">'.translate('DateTime').'</column>
<column field="component">'.translate('Component').'</column>
<column field="server">'.translate('Server').'</column>
<column field="pid">'.translate('Pid').'</column>
<column field="level">'.translate('Level').'</column>
<column field="message">'.translate('Message').'</column>
<column field="file">'.translate('File').'</column>
<column field="line">'.translate('Line').'</column>
</columns>
<logs count="'.count($logs).'">
' );

View File

@ -1,50 +1,22 @@
<?php
// HOW TO IMPLEMENT A NEW MODAL
// 1) Create a function in skins/classic/includes/functions that returns the desired modal HTML
// 2) Add a new entry to the switch case below that calls the new HTML function
// 3) Create a $j.getJSON Ajax call in js with the right parameters to retrieve the modal
// 4) Open the modal with $j('#myModal').modal('show')
//
if ( empty($_REQUEST['modal']) ) ajaxError('Modal Name Not Provided');
if ( empty($_REQUEST['modal']) ) {
ajaxError('Modal Name Not Provided');
return;
}
global $OLANG;
$modal = validJsStr($_REQUEST['modal']);
$data = array();
// Not sure if this is required
if ( ZM_OPT_USE_AUTH && (ZM_AUTH_RELAY == 'hashed') ) {
$auth_hash = generateAuthHash(ZM_AUTH_HASH_IPS);
if ( isset($_REQUEST['auth']) and ($_REQUEST['auth'] != $auth_hash) ) {
$data['auth'] = $auth_hash;
}
}
switch ( $modal ) {
case 'optionhelp' :
if ( empty($_REQUEST['ohndx']) ) ajaxError('Option Help Index Not Provided');
$data['html'] = getOptionHelpHTML($_REQUEST['ohndx'], $OLANG);
break;
case 'enoperm' :
$data['html'] = getENoPermHTML();
break;
case 'delconfirm' :
$data['html'] = getDelConfirmHTML();
break;
case 'storage' :
if ( !isset($_REQUEST['id']) ) ajaxError('Storage Id Not Provided');
$data['html'] = getStorageModalHTML($_REQUEST['id']);
break;
case 'eventdetail' :
$eid = isset($_REQUEST['eid']) ? $_REQUEST['eid'] : '';
$eids = isset($_REQUEST['eids']) ? $_REQUEST['eids'] : '';
$data['html'] = getEventDetailHTML($eid, $eids);
break;
default :
// Maybe don't need both
ZM\Warning('Unknown modal '.$modal);
ajaxError("Unknown modal '".$modal."'");
return;
ZM\Logger::Debug("Including modals/$modal.php");
# Shouldn't be necessary but at the moment we have last .conf file contents
ob_start();
@$result = include('modals/'.$modal.'.php');
$data['html'] = ob_get_contents();
ob_end_clean();
if ( !$result ) {
ajaxError("Unknown modal '".$modal."'");
return;
}
ajaxResponse($data);

View File

@ -0,0 +1,26 @@
<?php
// This is the HTML representing the Delete confirmation modal on the Events page and other pages
$delTextKey = isset($_REQUEST['key']) ? $_REQUEST['key'] : 'ConfirmDeleteEvents';
?>
<div id="deleteConfirm" class="modal fade" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('ConfirmDeleteTitle') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p><?php echo translate($delTextKey) ?></p>
</div>
<div class="modal-footer">
<button id="delCancelBtn" type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
<button id ="delConfirmBtn" type="button" class="btn btn-danger"><?php echo translate('Delete') ?></button>
</div>
</div>
</div>
</div>

View File

@ -18,10 +18,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canEdit('System') ) {
$view = 'error';
return;
}
if ( !canEdit('System') ) return;
$options = array(
'go' => translate('DonateYes'),
@ -45,25 +42,25 @@ $options = array(
</button>
</div>
<div class="modal-body">
<form name="contentForm" id="contentForm" method="post" action="?">
<input type="hidden" name="view" value="donate"/>
<input type="hidden" name="action" value="donate"/>
<p>
<?php echo translate('DonateEnticement') ?>
</p>
<p>
<?php echo buildSelect('option', $options); ?>
</p>
<div id="contentButtons">
<button type="submit"><?php echo translate('Apply') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Close') ?></button>
</div>
</form>
<form name="contentForm" id="donateForm" method="post" action="?">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="donate"/>
<input type="hidden" name="action" value="donate"/>
<p>
<?php echo translate('DonateEnticement') ?>
</p>
<p>
<?php echo buildSelect('option', $options); ?>
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Understood</button>
<button type="submit" class="btn btn-primary" id="donateApplyBtn"><?php echo translate('Apply') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Close') ?></button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,24 @@
<?php
// Return an Error No Permissions Modal
?>
<div id="ENoPerm" class="modal fade" id="staticBackdrop" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">ZoneMinder <?php echo translate('Error') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p><?php echo translate('YouNoPerms') ?></p>
<p><?php echo translate('ContactAdmin') ?></p>
</div>
<div class="modal-footer">
<button type="button" id="enpCloseBtn" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,89 @@
<?php
// This is the HTML representing the Event Detail modal on the Events page
$eid = isset($_REQUEST['eid']) ? $_REQUEST['eid'] : '';
$eids = isset($_REQUEST['eids']) ? $_REQUEST['eids'] : '';
$result = '';
$inputs = '';
$disabled = 'disabled="disabled"';
$null = '';
if ( !canEdit('Events') ) return;
if ( $eid ){ // Single Event Mode
$eid = validInt($eid);
$title = translate('Event').' '.$eid.PHP_EOL;
$inputs .= '<input type="hidden" name="markEids[]" value="' .$eid. '"/>';
$newEvent = dbFetchOne('SELECT E.* FROM Events AS E WHERE E.Id = ?', NULL, array($eid));
} elseif ( $eids ) { // Multi Event Mode
$title = translate('Events');
$sql = 'SELECT E.* FROM Events AS E WHERE ';
$sqlWhere = array();
$sqlValues = array();
foreach ( $eids as $eid ) {
$eid = validInt($eid);
$inputs .= '<input type="hidden" name="markEids[]" value="' .$eid. '"/>';
$sqlWhere[] = 'E.Id = ?';
$sqlValues[] = $eid;
}
unset($eid);
$sql .= join(' OR ', $sqlWhere);
foreach( dbFetchAll( $sql, NULL, $sqlValues ) as $row ) {
if ( !isset($newEvent) ) {
$newEvent = $row;
} else {
if ( $newEvent['Cause'] && $newEvent['Cause'] != $row['Cause'] )
$newEvent['Cause'] = '';
if ( $newEvent['Notes'] && $newEvent['Notes'] != $row['Notes'] )
$newEvent['Notes'] = '';
}
}
} else { // Event Mode not specified - should we really proceed if neither eid nor eids is set?
$title = translate('Events');
}
?>
<div class="modal fade" id="eventDetailModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo $title ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form name="contentForm" id="eventDetailForm" method="post" action="?view=eventdetail&action=eventdetail">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
echo $inputs;
?>
<input type="hidden" name="action" value="eventdetail"/>
<input type="hidden" name="view" value="eventdetail"/>
<table class="table-sm">
<tbody>
<tr>
<th scope="row"><?php echo translate('Cause') ?></th>
<td><input type="text" name="newEvent[Cause]" value="<?php echo validHtmlStr($newEvent['Cause']) ?>" size="32"/></td>
</tr>
<tr>
<th scope="row" class="align-middle"><?php echo translate('Notes') ?></th>
<td><textarea name="newEvent[Notes]" rows="6" cols="33"><?php echo validHtmlStr($newEvent['Notes']) ?></textarea></td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" name="action" id="eventDetailSaveBtn" class="btn btn-primary" value="save" <?php echo !canEdit('Events') ? $disabled : $null .'>'. translate('Save') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
<div class="modal fade" id="filterdebugModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('FilterDebug') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<?php
//require_once('includes/Filter.php');
$fid = validInt($_REQUEST['fid']);
if ( !$fid ) {
echo '<div class="error">No filter id specified.</div>';
} else {
$filter = new ZM\Filter($_REQUEST['fid']);
if ( ! $filter->Id() ) {
echo '<div class="error">Filter not found for id '.$_REQUEST['fid'].'</div>';
}
}
?>
<form name="contentForm" id="filterdebugForm" method="post" action="?">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<p><label>SQL</label><?php echo $filter->sql() ?></p>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel')?> </button>
</div>
</form>
</div>
</div>
</div>

View File

@ -18,17 +18,18 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canEdit('Monitors') ) {
$view = 'error';
return;
}
?>
if ( !canEdit('Monitors') ) return;
?>
<div id="modalFunction" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form id="function_form" action="?view=function&action=function" method="post">
<input type="hidden" name="mid"/>
<form id="function_form" action="?view=function&action=function" method="post">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="mid"/>
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('Function') ?> - <span id="function_monitor_name"></span></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
@ -46,7 +47,7 @@ if ( !canEdit('Monitors') ) {
<button type="button" class="funcSaveBtn btn btn-primary"><?php echo translate('Save') ?></button>
<button type="button" class="funcCancelBtn btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</form>
</form>
</div>
</div>
</div>

135
web/ajax/modals/group.php Normal file
View File

@ -0,0 +1,135 @@
<?php
// This is the HTML representing the Group modal accessed from the Groups (plural) view
//
// DEFINE SUPPORTING FUNCTIONS
//
function get_Id( $G ) {
return $G->Id();
}
function get_children($Group) {
global $children;
$kids = array();
if ( isset( $children[$Group->Id()] ) ) {
$kids += array_map('get_Id', $children[$Group->Id()]);
foreach ( $children[$Group->Id()] as $G ) {
foreach ( get_children($G) as $id ) {
$kids[] = $id;
}
}
}
return $kids;
}
function parentGrpSelect($newGroup) {
$Groups = array();
foreach ( ZM\Group::find() as $Group ) {
$Groups[$Group->Id()] = $Group;
}
# This array is indexed by parent_id
$children = array();
foreach ( $Groups as $id=>$Group ) {
if ( $Group->ParentId() != null ) {
if ( ! isset( $children[$Group->ParentId()] ) )
$children[$Group->ParentId()] = array();
$children[$Group->ParentId()][] = $Group;
}
}
$kids = get_children($newGroup);
if ( $newGroup->Id() )
$kids[] = $newGroup->Id();
$sql = 'SELECT Id,Name FROM `Groups`'.(count($kids)?' WHERE Id NOT IN ('.implode(',',array_map(function(){return '?';}, $kids)).')' : '').' ORDER BY Name';
$options = array(''=>'None');
foreach ( dbFetchAll($sql, null, $kids) as $option ) {
$options[$option['Id']] = str_repeat('&nbsp;&nbsp;', $Groups[$option['Id']]->depth()) . $option['Name'];
}
return htmlSelect('newGroup[ParentId]', $options, $newGroup->ParentId(), array('data-on-change'=>'configModalBtns'));
}
function monitorList($newGroup) {
$result = '';
$monitors = dbFetchAll('SELECT Id,Name FROM Monitors ORDER BY Sequence ASC');
$monitorIds = $newGroup->MonitorIds();
foreach ( $monitors as $monitor ) {
if ( visibleMonitor($monitor['Id']) ) {
$result .= '<option value="' .$monitor['Id']. '"' .( in_array( $monitor['Id'], $monitorIds ) ? ' selected="selected"' : ''). '>' .validHtmlStr($monitor['Name']). '</option>'.PHP_EOL;
}
}
return $result;
}
//
// INITIAL SANITY CHECKS
//
if ( !canEdit('Groups') ) {
$view = 'error';
return;
}
if ( !empty($_REQUEST['gid']) ) {
$newGroup = new ZM\Group($_REQUEST['gid']);
} else {
$newGroup = new ZM\Group();
}
//
// BEGIN HTML
//
?>
<div id="groupModal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('Group').($newGroup->Name() ? ' - ' .validHtmlStr($newGroup->Name()) : '') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="groupForm" name="groupForm" method="post" action="?view=group&action=save">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="group"/>
<input type="hidden" name="gid" value="<?php echo $newGroup->Id() ?>"/>
<table id="groupModalTable" class="table-sm table-borderless">
<tbody>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Name') ?></th>
<td><input type="text" name="newGroup[Name]" value="<?php echo validHtmlStr($newGroup->Name()) ?>" data-on-input="configModalBtns"/></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('ParentGroup') ?></th>
<td><?php echo parentGrpSelect($newGroup) ?></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Monitor') ?></th>
<td>
<select name="newGroup[MonitorIds][]" class="chosen" multiple="multiple" data-on-change="configModalBtns">
<?php echo monitorList($newGroup) ?>
</select>
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" name="action" id="grpModalSaveBtn" value="save"<?php $newGroup->Id() ? '' : ' disabled="disabled"'?>><?php echo translate('Save') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
</div>

View File

@ -0,0 +1,46 @@
<div class="modal fade" id="log_exportModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('ExportLog') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="exportForm" action="" method="post">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
echo $inputs;
?>
<fieldset title="<?php echo translate('ChooseLogSelection') ?>">
<legend><?php echo translate('SelectLog') ?></legend>
<label for="selectorAll"><?php echo translate('All') ?></label>
<input type="radio" id="selectorAll" name="selector" value="all"/>
<label for="selectorFilter"><?php echo translate('Filter') ?></label>
<input type="radio" id="selectorFilter" name="selector" value="filter"/>
<label for="selectorCurrent"><?php echo translate('Current') ?></label>
<input type="radio" id="selectorCurrent" name="selector" value="current" data-validators="validate-one-required"/>
</fieldset>
<fieldset title="<?php echo translate('ChooseLogFormat') ?>">
<legend><?php echo translate('SelectFormat') ?></legend>
<label for="formatText">TXT</label><input type="radio" id="formatText" name="format" value="text"/>
<label for="formatTSV">TSV</label><input type="radio" id="formatTSV" name="format" value="tsv"/>
<label for="formatXML">HTML</label><input type="radio" id="formatHTML" name="format" value="html"/>
<label for="formatXML">XML</label><input type="radio" id="formatXML" name="format" value="xml" class="validate-one-required"/>
</fieldset>
<div id="exportError">
<?php echo translate('ExportFailed') ?>: <span id="exportErrorText"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" id="exportButton" value="Export" data-on-click="exportRequest"><?php echo translate('Export') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
</div>

View File

@ -33,6 +33,10 @@ global $CLANG;
</div>
<div class="modal-footer">
<form name="logoutForm" id="logoutForm" method="post" action="?">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="logout"/>
<button type="submit" name="action" value="logout"><?php echo translate('Logout') ?></button>
<?php if ( ZM_USER_SELF_EDIT ) echo '<button type="submit" name="action" value="config">'.translate('Config').'</button>'.PHP_EOL; ?>

View File

@ -0,0 +1,43 @@
<?php
// Returns the modal html representing the selected Option Help item
if ( empty($_REQUEST['ohndx']) ) {
ajaxError('Option Help Index Not Provided');
return;
}
global $OLANG;
$result = '';
$optionHelpIndex = $_REQUEST['ohndx'];
$ZMoptionHelpIndex = 'ZM_'.$optionHelpIndex;
if ( !empty($OLANG[$optionHelpIndex]) ) {
$optionHelpText = $OLANG[$optionHelpIndex]['Help'];
} else {
$optionHelpText = dbFetchOne('SELECT Help FROM Config WHERE Name=?', 'Help', array($optionHelpIndex));
}
$optionHelpText = validHtmlStr($optionHelpText);
$optionHelpText = preg_replace('/~~/', '<br/>', $optionHelpText );
$optionHelpText = preg_replace('/\[(.+)\]\((.+)\)/', '<a href="$2" target="_blank">$1</a>', $optionHelpText);
?>
<div id="optionhelp" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('OptionHelp') ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h3><?php echo validHtmlStr($optionHelpIndex) ?></h3>
<p class="textblock"><?php echo $optionHelpText ?></p>
</div>
<div class="modal-footer">
<button type="button" id="ohCloseBtn" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

View File

@ -1,49 +1,40 @@
<?php
//
// ZoneMinder web user 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 ( !canEdit('System') ) {
$view = 'error';
// This is the HTML representing the Server modal from Options -> Server
if ( !isset($_REQUEST['id']) ) {
ajaxError('Server Id Not Provided');
return;
}
$Server = new ZM\Server($_REQUEST['id']);
if ( $_REQUEST['id'] and ! $Server->Id() ) {
$view = 'error';
return;
}
$result = '';
$checked = ' checked="checked"';
$null = '';
$sid = $_REQUEST['id'];
$focusWindow = true;
if ( !canEdit('System') ) return;
$Server = new ZM\Server($sid);
if ( $sid and ! $Server->Id() ) return;
xhtmlHeaders(__FILE__, translate('Server').' - '.$Server->Name());
getBodyTopHTML();
?>
<div id="page">
<div id="header">
<h2><?php echo translate('Server').' - '.$Server->Name() ?></h2>
</div>
<div id="content">
<form name="contentForm" method="post" action="?" class="validateFormOnSubmit">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<div class="modal fade" id="ServerModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('Server') .' - '. $Server->Name() ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="serverModalForm" name="contentForm" method="post" action="?view=server&action=save" class="validateFormOnSubmit">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="server"/>
<input type="hidden" name="object" value="server"/>
<input type="hidden" name="id" value="<?php echo validHtmlStr($_REQUEST['id']) ?>"/>
<table id="contentTable" class="major">
<table class="table-sm">
<tbody>
<tr>
<th scope="row"><?php echo translate('Name') ?></th>
@ -76,38 +67,39 @@ getBodyTopHTML();
<tr>
<th scope="row"><?php echo translate('RunStats') ?></th>
<td>
<input type="radio" name="newServer[zmstats]" value="1"<?php echo $Server->zmstats() ? ' checked="checked"' : '' ?>/> Yes
<input type="radio" name="newServer[zmstats]" value="0"<?php echo $Server->zmstats() ? '' : ' checked="checked"' ?>/> No
<input type="radio" name="newServer[zmstats]" value="1" <?php echo $Server->zmstats() ? $checked : $null ?>/> Yes
<input type="radio" name="newServer[zmstats]" value="0" <?php echo $Server->zmstats() ? $null : $checked ?>/> No
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('RunAudit') ?></th>
<td>
<input type="radio" name="newServer[zmaudit]" value="1"<?php echo $Server->zmaudit() ? ' checked="checked"' : '' ?>/> Yes
<input type="radio" name="newServer[zmaudit]" value="0"<?php echo $Server->zmaudit() ? '' : ' checked="checked"' ?>/> No
<input type="radio" name="newServer[zmaudit]" value="1"<?php echo $Server->zmaudit() ? $checked : $null ?>/> Yes
<input type="radio" name="newServer[zmaudit]" value="0"<?php echo $Server->zmaudit() ? $null : $checked ?>/> No
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('RunTrigger') ?></th>
<td>
<input type="radio" name="newServer[zmtrigger]" value="1"<?php echo $Server->zmtrigger() ? ' checked="checked"' : '' ?>/> Yes
<input type="radio" name="newServer[zmtrigger]" value="0"<?php echo $Server->zmtrigger() ? '' : ' checked="checked"' ?>/> No
<input type="radio" name="newServer[zmtrigger]" value="1" <?php echo $Server->zmtrigger() ? $checked : $null ?>/> Yes
<input type="radio" name="newServer[zmtrigger]" value="0" <?php echo $Server->zmtrigger() ? $null : $checked ?>/> No
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('RunEventNotification') ?></th>
<td>
<input type="radio" name="newServer[zmeventnotification]" value="1"<?php echo $Server->zmeventnotification() ? ' checked="checked"' : '' ?>/> Yes
<input type="radio" name="newServer[zmeventnotification]" value="0"<?php echo $Server->zmeventnotification() ? '' : ' checked="checked"' ?>/> No
<input type="radio" name="newServer[zmeventnotification]" value="1" <?php echo $Server->zmeventnotification() ? $checked : $null ?>/> Yes
<input type="radio" name="newServer[zmeventnotification]" value="0" <?php echo $Server->zmeventnotification() ? $null : $checked ?>/> No
</td>
</tr>
</tbody>
</table>
<div id="contentButtons">
<button type="submit" name="action" value="Save" ><?php echo translate('Save') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
<div class="modal-footer">
<button name="action" id="serverSubmitBtn" type="submit" class="btn btn-primary" value="Save"><?php echo translate('Save') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</div>
</div>
<?php xhtmlFooter() ?>
</div>

View File

@ -17,12 +17,10 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
global $running;
if ( !canEdit('System') ) {
$view = 'error';
return;
}
if ( !canEdit('System') ) return;
$running = daemonCheck();
$content = '';
if ( $running ) {
@ -53,6 +51,10 @@ foreach ( $states as $state ) {
</div>
<div class="modal-body">
<form class="" name="contentForm" method="get" action="?view=state">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="state"/>
<input type="hidden" name="action" value="state"/>
<input type="hidden" name="apply" value="1"/>

110
web/ajax/modals/storage.php Normal file
View File

@ -0,0 +1,110 @@
<?php
// This is the HTML representing the Storage modal from Options -> Storage
if ( !isset($_REQUEST['id']) ) {
ajaxError('Storage Id Not Provided');
return;
}
$null = '';
$checked = 'checked="checked"';
$sid = $_REQUEST['id'];
if ( !canEdit('System') ) return;
require_once('includes/Server.php');
require_once('includes/Storage.php');
if ( $_REQUEST['id'] ) {
if ( !($newStorage = ZM\Storage::find_one(array('Id'=>$sid)) ) ) {
// Perhaps do something different here, rather than return nothing
return;
}
} else {
$newStorage = new ZM\Storage();
$newStorage->Name(translate('NewStorage'));
}
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
$scheme_options = array(
'Deep' => translate('Deep'),
'Medium' => translate('Medium'),
'Shallow' => translate('Shallow'),
);
$servers = ZM\Server::find( null, array('order'=>'lower(Name)') );
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
}
?>
<div class="modal fade" id="storageModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><?php echo translate('Storage') .' - '. $newStorage->Name() ?></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form id="storageModalForm" name="contentForm" method="post" action="?view=storage&action=save" class="validateFormOnSubmit">
<?php
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
echo getCSRFinputHTML();
?>
<input type="hidden" name="view" value="storage"/>
<input type="hidden" name="object" value="storage"/>
<input type="hidden" name="id" value="<?php echo validHtmlStr($sid) ?>"/>
<table class="major table-sm">
<tbody>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Name') ?></th>
<td><input type="text" name="newStorage[Name]" value="<?php echo $newStorage->Name() ?>"/></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Path') ?></th>
<td><input type="text" name="newStorage[Path]" value="<?php echo $newStorage->Path() ?>"/></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Url') ?></th>
<td><input type="text" name="newStorage[Url]" value="<?php echo $newStorage->Url() ?>"/></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Server') ?></th>
<td><?php echo htmlSelect('newStorage[ServerId]', array(''=>'Remote / No Specific Server') + $ServersById, $newStorage->ServerId()) ?></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Type') ?></th>
<td><?php echo htmlSelect('newStorage[Type]', $type_options, $newStorage->Type()) ?></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('StorageScheme') ?></th>
<td><?php echo htmlSelect('newStorage[Scheme]', $scheme_options, $newStorage->Scheme()) ?></td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('StorageDoDelete') ?></th>
<td>
<input type="radio" name="newStorage[DoDelete]" value="1" <?php echo $newStorage->DoDelete() ? $checked : $null ?>>Yes
<input type="radio" name="newStorage[DoDelete]" value="0" <?php echo $newStorage->DoDelete() ? $null : $checked ?>>No
</td>
</tr>
<tr>
<th class="text-right pr-3" scope="row"><?php echo translate('Enabled') ?></th>
<td>
<input type="radio" name="newStorage[Enabled]" value="1" <?php echo $newStorage->Enabled() ? $checked : $null ?>>Yes
<input type="radio" name="newStorage[Enabled]" value="0" <?php echo $newStorage->Enabled() ? $null : $checked ?>>No
</td>
</tr>
</tbody>
</table>
</div>
<div class="modal-footer">
<button name="action" id="storageSubmitBtn" type="submit" class="btn btn-primary" value="Save"><?php echo translate('Save') ?></button>
<button type="button" class="btn btn-secondary" data-dismiss="modal"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
</div>

132
web/ajax/newlog.php Normal file
View File

@ -0,0 +1,132 @@
<?php
global $Servers;
if ( !canView('System') ) {
ajaxError('Insufficient permissions to view log entries');
return;
}
// Only the query task is supported at the moment
if ( !isset($_REQUEST['task']) or $_REQUEST['task'] != 'query' ) {
ajaxError('Unrecognised action');
return;
}
// The table we want our data from
$table = 'Logs';
// The names of the dB columns in the log table we are interested in
$columns = array('TimeKey', 'Component', 'ServerId', 'Pid', 'Code', 'Message', 'File', 'Line');
// The names of columns shown in the log view that are NOT dB columns in the database
$col_alt = array('DateTime', 'Server');
// 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
$advsearch = isset($_REQUEST['filter']) ? json_decode($_REQUEST['filter'], JSON_OBJECT_AS_ARRAY) : array();
// Sort specifies the name of the column to sort on
$sort = 'TimeKey';
if ( isset($_REQUEST['sort']) ) {
if ( !in_array($_REQUEST['sort'], array_merge($columns, $col_alt)) ) {
ZM\Error('Invalid sort field: ' . $_REQUEST['sort']);
} else {
$sort = $_REQUEST['sort'];
if ( $sort == 'DateTime' ) $sort = 'TimeKey';
}
}
// 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'];
}
}
// Order specifies the sort direction, either asc or desc
$order = (isset($_REQUEST['order']) and (strtolower($_REQUEST['order']) == 'asc')) ? 'ASC' : 'DESC';
// Limit specifies the number of rows to return
$limit = 100;
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'];
}
}
$col_str = implode(', ', $columns);
$data = array();
$query = array();
$query['values'] = array();
$likes = array();
$where = '';
// 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) ) {
foreach ( $advsearch as $col=>$text ) {
if ( !in_array($col, array_merge($columns, $col_alt)) ) {
ZM\Error("'$col' is not a sortable column name");
continue;
}
$text = '%' .$text. '%';
array_push($likes, $col.' LIKE ?');
array_push($query['values'], $text);
}
$wherevalues = $query['values'];
$where = ' WHERE (' .implode(' OR ', $likes). ')';
} else if ( $search != '' ) {
$search = '%' .$search. '%';
foreach ( $columns as $col ) {
array_push($likes, $col.' LIKE ?');
array_push($query['values'], $search);
}
$wherevalues = $query['values'];
$where = ' WHERE (' .implode(' OR ', $likes). ')';
}
$query['sql'] = 'SELECT ' .$col_str. ' FROM `' .$table. '` ' .$where. ' ORDER BY ' .$sort. ' ' .$order. ' LIMIT ?, ?';
array_push($query['values'], $offset, $limit);
//ZM\Warning('Calling the following sql query: ' .$query['sql']);
$data['totalNotFiltered'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table, 'Total');
if ( $search != '' || count($advsearch) ) {
$data['total'] = dbFetchOne('SELECT count(*) AS Total FROM ' .$table.$where , 'Total', $wherevalues);
} else {
$data['total'] = $data['totalNotFiltered'];
}
if ( !$Servers )
$Servers = ZM\Server::find();
$servers_by_Id = array();
# There is probably a better way to do this.
foreach ( $Servers as $server ) {
$servers_by_Id[$server->Id()] = $server;
}
$rows = array();
foreach ( dbFetchAll($query['sql'], NULL, $query['values']) as $row ) {
$row['DateTime'] = strftime('%Y-%m-%d %H:%M:%S', intval($row['TimeKey']));
$row['Server'] = ( $row['ServerId'] and isset($servers_by_Id[$row['ServerId']]) ) ? $servers_by_Id[$row['ServerId']]->Name() : '';
// First strip out any html tags
// Second strip out all characters that are not ASCII 32-126 (yes, 126)
$row['Message'] = preg_replace('/[^\x20-\x7E]/', '', strip_tags($row['Message']));
$rows[] = $row;
}
$data['rows'] = $rows;
$data['logstate'] = logState();
$data['updated'] = preg_match('/%/', DATE_FMT_CONSOLE_LONG) ? strftime(DATE_FMT_CONSOLE_LONG) : date(DATE_FMT_CONSOLE_LONG);
ajaxResponse($data);

View File

@ -434,14 +434,11 @@ class EventsController extends AppController {
// Find the max Frame for this Event. Error out otherwise.
$this->loadModel('Frame');
if (! $frame = $this->Frame->find('first', array(
$frame = $this->Frame->find('first', array(
'conditions' => array(
'EventId' => $event['Event']['Id'],
'Score' => $event['Event']['MaxScore']
)
))) {
throw new NotFoundException(__('Can not find Frame for Event ' . $event['Event']['Id']));
}
return $frame['Frame']['Id'];
'EventId' => $event['Event']['Id'],
'Score' => $event['Event']['MaxScore']
)));
return empty($frame)?null:$frame['Frame']['Id'];
}
} // end class EventsController

View File

@ -1,7 +1,7 @@
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.17.1
* @version v1.18.0
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT

File diff suppressed because one or more lines are too long

View File

@ -50,10 +50,10 @@ class Filter extends ZM_Object {
return $this->_sql;
}
public function querystring() {
if ( ! isset($this->_querystring) ) {
public function querystring($separator='&amp;') {
if ( (! isset($this->_querystring)) or ( $separator != '&amp;' ) ) {
foreach ( $this->FilterTerms() as $term ) {
$this->_querystring .= $term->querystring();
$this->_querystring .= $term->querystring($separator);
} # end foreach term
}
return $this->_querystring;
@ -196,7 +196,7 @@ class Filter extends ZM_Object {
if ( isset( $this->Query()['sort_asc'] ) ) {
return $this->{'Query'}['sort_asc'];
}
return ZM_WEB_EVENT_SORT_ORDER;
return ZM_WEB_EVENT_SORT_ORDER == 'asc' ? 1 : 0;
#return $this->defaults{'sort_asc'};
}
@ -308,6 +308,312 @@ class Filter extends ZM_Object {
return $failed;
}
function tree() {
$terms = $this->terms();
if ( count($terms) <= 0 ) {
return false;
}
$StorageArea = NULL;
$postfixExpr = array();
$postfixStack = array();
$priorities = array(
'<' => 1,
'<=' => 1,
'>' => 1,
'>=' => 1,
'=' => 2,
'!=' => 2,
'=~' => 2,
'!~' => 2,
'=[]' => 2,
'![]' => 2,
'and' => 3,
'or' => 4,
);
for ( $i = 0; $i < count($terms); $i++ ) {
$term = $terms[$i];
if ( !empty($term['cnj']) ) {
while( true ) {
if ( !count($postfixStack) ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} elseif ( $priorities[$term['cnj']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} else {
$postfixExpr[] = array_pop($postfixStack);
}
}
} # end if ! empty cnj
if ( !empty($term['obr']) ) {
for ( $j = 0; $j < $term['obr']; $j++ ) {
$postfixStack[] = array('type'=>'obr', 'value'=>$term['obr']);
}
}
if ( !empty($term['attr']) ) {
$dtAttr = false;
switch ( $term['attr']) {
case 'MonitorName':
$sqlValue = 'M.'.preg_replace( '/^Monitor/', '', $term['attr']);
break;
case 'ServerId':
$sqlValue .= 'M.ServerId';
break;
case 'StorageServerId':
$sqlValue .= 'S.ServerId';
break;
case 'FilterServerId':
$sqlValue .= ZM_SERVER_ID;
break;
case 'DateTime':
case 'StartDateTime':
$sqlValue = 'E.StartTime';
$dtAttr = true;
break;
case 'Date':
case 'StartDate':
$sqlValue = 'to_days(E.StartTime)';
$dtAttr = true;
break;
case 'Time':
case 'StartTime':
$sqlValue = 'extract(hour_second from E.StartTime)';
break;
case 'Weekday':
case 'StartWeekday':
$sqlValue = 'weekday(E.StartTime)';
break;
case 'EndDateTime':
$sqlValue = 'E.EndTime';
$dtAttr = true;
break;
case 'EndDate':
$sqlValue = 'to_days(E.EndTime)';
$dtAttr = true;
break;
case 'EndTime':
$sqlValue = 'extract(hour_second from E.EndTime)';
break;
case 'EndWeekday':
$sqlValue = 'weekday(E.EndTime)';
break;
case 'Id':
case 'Name':
case 'MonitorId':
case 'StorageId':
case 'SecondaryStorageId':
case 'Length':
case 'Frames':
case 'AlarmFrames':
case 'TotScore':
case 'AvgScore':
case 'MaxScore':
case 'Cause':
case 'Notes':
case 'StateId':
case 'Archived':
$sqlValue = 'E.'.$term['attr'];
break;
case 'DiskPercent':
// Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH
if ( ! $StorageArea ) {
for ( $j = 0; $j < count($terms); $j++ ) {
if ( isset($terms[$j]['attr']) and $terms[$j]['attr'] == 'StorageId' and isset($terms[$j]['val']) ) {
$StorageArea = new Storage($terms[$j]['val']);
break;
}
} // end foreach remaining term
if ( ! $StorageArea ) $StorageArea = new Storage();
} // end no StorageArea found yet
$sqlValue = getDiskPercent($StorageArea);
break;
case 'DiskBlocks':
// Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH
if ( ! $StorageArea ) {
for ( $j = 0; $j < count($terms); $j++ ) {
if ( isset($terms[$j]['attr']) and $terms[$j]['attr'] == 'StorageId' and isset($terms[$j]['val']) ) {
$StorageArea = new Storage($terms[$j]['val']);
break;
}
} // end foreach remaining term
if ( ! $StorageArea ) $StorageArea = new Storage();
} // end no StorageArea found yet
$sqlValue = getDiskBlocks($StorageArea);
break;
default :
$sqlValue = $term['attr'];
break;
}
if ( $dtAttr ) {
$postfixExpr[] = array('type'=>'attr', 'value'=>$term['attr'], 'sqlValue'=>$sqlValue, 'dtAttr'=>true);
} else {
$postfixExpr[] = array('type'=>'attr', 'value'=>$term['attr'], 'sqlValue'=>$sqlValue);
}
} # end if attr
if ( isset($term['op']) ) {
if ( empty($term['op']) ) {
$term['op'] = '=';
}
switch ( $term['op']) {
case '=' :
case '!=' :
case '>=' :
case '>' :
case '<' :
case '<=' :
case 'LIKE' :
case 'NOT LIKE':
$sqlValue = $term['op'];
break;
case '=~' :
$sqlValue = 'regexp';
break;
case '!~' :
$sqlValue = 'not regexp';
break;
case '=[]' :
case 'IN' :
$sqlValue = 'in (';
break;
case '![]' :
$sqlValue = 'not in (';
break;
case 'IS' :
case 'IS NOT' :
if ( $term['val'] == 'Odd' ) {
$sqlValue .= ' % 2 = 1';
} else if ( $term['val'] == 'Even' ) {
$sqlValue .= ' % 2 = 0';
} else {
$sqlValue .= ' '.$term['op'];
}
break;
default :
ZM\Error('Unknown operator in filter '.$term['op']);
}
while( true ) {
if ( !count($postfixStack) ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue);
break;
} elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue);
break;
} elseif ( $priorities[$term['op']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue );
break;
} else {
$postfixExpr[] = array_pop($postfixStack);
}
} // end while
} // end if operator
if ( isset($term['val']) ) {
$valueList = array();
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
switch ( $term['attr'] ) {
case 'MonitorName':
case 'Name':
case 'Cause':
case 'Notes':
if ( $term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE' ) {
$value = '%'.$value.'%';
}
$value = dbEscape($value);
break;
case 'MonitorServerId':
case 'FilterServerId':
case 'StorageServerId':
case 'ServerId':
if ( $value == 'ZM_SERVER_ID' ) {
$value = ZM_SERVER_ID;
} else if ( $value == 'NULL' ) {
} else {
$value = dbEscape($value);
}
break;
case 'StorageId':
$StorageArea = new Storage($value);
if ( $value != 'NULL' )
$value = dbEscape($value);
break;
case 'DateTime':
case 'EndDateTime':
case 'StartDateTime':
$value = "'".strftime(STRF_FMT_DATETIME_DB, strtotime($value))."'";
break;
case 'Date':
case 'EndDate':
case 'StartDate':
$value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
case 'Time':
case 'EndTime':
case 'StartTime':
$value = 'extract(hour_second from \''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
case 'Weekday':
case 'EndWeekday':
case 'StartWeekday':
$value = 'weekday(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
default :
if ( $value != 'NULL' )
$value = dbEscape($value);
} // end switch attribute
$valueList[] = $value;
} // end foreach value
$postfixExpr[] = array('type'=>'val', 'value'=>$term['val'], 'sqlValue'=>join(',', $valueList));
} // end if has val
if ( !empty($term['cbr']) ) {
for ( $j = 0; $j < $term['cbr']; $j++ ) {
while ( count($postfixStack) ) {
$element = array_pop($postfixStack);
if ( $element['type'] == 'obr' ) {
$postfixExpr[count($postfixExpr)-1]['bracket'] = true;
break;
}
$postfixExpr[] = $element;
}
}
} #end if cbr
} # end foreach term
while ( count($postfixStack) ) {
$postfixExpr[] = array_pop($postfixStack);
}
$exprStack = array();
foreach ( $postfixExpr as $element ) {
if ( $element['type'] == 'attr' || $element['type'] == 'val' ) {
$node = array('data'=>$element, 'count'=>0);
$exprStack[] = $node;
} elseif ( $element['type'] == 'op' || $element['type'] == 'cnj' ) {
$right = array_pop($exprStack);
$left = array_pop($exprStack);
$node = array('data'=>$element, 'count'=>2+$left['count']+$right['count'], 'right'=>$right, 'left'=>$left);
$exprStack[] = $node;
} else {
ZM\Fatal('Unexpected element type \''.$element['type'].'\', value \''.$element['value'].'\'');
}
}
if ( count($exprStack) != 1 ) {
ZM\Fatal('Expression stack has '.count($exprStack).' elements');
}
return array_pop($exprStack);
} # end function tree
} # end class Filter

View File

@ -61,7 +61,7 @@ class FilterTerm {
public function sql_values() {
$values = array();
if ( !isset($this->val) ) {
Logger::Warning("No value in term ");
Logger::Warning('No value in term'.$this->attr);
return $values;
}
@ -75,6 +75,10 @@ class FilterTerm {
case 'ExistsInFileSystem':
$value = '';
break;
case 'DiskSpace':
$value = '';
break;
case 'MonitorName':
case 'MonitorName':
case 'Name':
case 'Cause':
@ -137,10 +141,11 @@ class FilterTerm {
} # end function sql_values
public function sql_operator() {
if ( $this->attr == 'AlarmZoneId' ) {
switch ( $this->attr ) {
case 'AlarmZoneId':
return ' EXISTS ';
}
if ( $this->attr == 'ExistsInFileSystem' ) {
case 'ExistsInFileSystem':
case 'DiskSpace':
return '';
}
@ -197,6 +202,7 @@ class FilterTerm {
switch ( $this->attr ) {
case 'ExistsInFileSystem':
case 'DiskSpace':
$sql .= 'TRUE /*'.$this->attr.'*/';
break;
case 'MonitorName':
@ -256,7 +262,7 @@ class FilterTerm {
break;
case 'Id':
case 'Name':
case 'DiskSpace':
case 'EventDiskSpace':
case 'MonitorId':
case 'StorageId':
case 'SecondaryStorageId':

View File

@ -567,7 +567,7 @@ class Monitor extends ZM_Object {
return false;
}
} else if ( $command != 'quit' ) {
$command = ZM_PATH_BIN.'/zmcontrol.pl '.$command.' --id='.$this->{'Id'};
$command = ZM_PATH_BIN.'/zmcontrol.pl '.$command.' --id '.$this->{'Id'};
// Can't connect so use script
$ctrlOutput = exec(escapeshellcmd($command));
@ -628,5 +628,9 @@ class Monitor extends ZM_Object {
return $this->connKey;
}
function canEdit() {
global $user;
return ( $user && ($user['Monitors'] == 'Edit') && ( !$this->{'Id'} || visibleMonitor($this->{'Id'}) ));
}
} // end class Monitor
?>

View File

@ -144,7 +144,6 @@ class ZM_Object {
public function _remove_from_cache($class, $object) {
global $object_cache;
unset($object_cache[$class][$object->Id()]);
Logger::Debug("Unsset $class " . $object->Id() . " " . count($object_cache[$class]));
}
public static function Objects_Indexed_By_Id($class, $params=null) {

View File

@ -8,8 +8,9 @@ class Zone extends ZM_Object {
protected static $table = 'Zones';
protected $defaults = array(
'Id' => null,
'Name' => '',
'Id' => null,
'MonitorId' => null,
'Name' => '',
'Type' => 'Active',
'Units' => 'Pixels',
'CheckMethod' => 'Blobs',
@ -36,6 +37,14 @@ class Zone extends ZM_Object {
public static function find_one( $parameters = array(), $options = array() ) {
return ZM_Object::_find_one(get_class(), $parameters, $options);
}
public function Monitor() {
if ( isset($this->{'MonitorId'}) ) {
$Monitor = Monitor::find_one(array('Id'=>$this->{'MonitorId'}));
if ( $Monitor )
return $Monitor;
}
return new Monitor();
}
} # end class Zone
?>

View File

@ -89,7 +89,6 @@ if ( $action == 'controlcap' ) {
//$changes = getFormChanges( $control, $_REQUEST['newControl'], $types, $columns );
$Control->save($_REQUEST['newControl']);
$refreshParent = true;
$view = 'none';
$redirect = '?view=controlcaps';
} // end if action
?>

View File

@ -49,6 +49,6 @@ if ( $action == 'donate' && isset($_REQUEST['option']) ) {
Warning("Unknown value for option in donate: $option");
break;
} // end switch option
$view = 'none';
$redirect = '?view=console';
}
?>

View File

@ -51,11 +51,9 @@ if ( $action == 'function' ) {
if ( $newFunction != 'None' && $newFunction != 'NoDect' )
zmaControl($monitor, 'start');
}
$refreshParent = true;
} else {
ZM\Logger::Debug('No change to function, not doing anything.');
}
} // end if action
$view = 'none';
$closePopup = true;
$view = 'console';
?>

View File

@ -26,26 +26,24 @@ if ( !canEdit('Groups') ) {
return;
}
if ( $action == 'Save' ) {
if ( $action == 'save' ) {
$group_id = null;
if ( !empty($_POST['gid']) )
$group_id = $_POST['gid'];
if ( !empty($_REQUEST['gid']) )
$group_id = $_REQUEST['gid'];
$group = new ZM\Group($group_id);
$group->save(
array(
'Name'=> $_POST['newGroup']['Name'],
'ParentId'=>( $_POST['newGroup']['ParentId'] == '' ? null : $_POST['newGroup']['ParentId'] ),
'Name'=> $_REQUEST['newGroup']['Name'],
'ParentId'=>( $_REQUEST['newGroup']['ParentId'] == '' ? null : $_REQUEST['newGroup']['ParentId'] ),
)
);
dbQuery('DELETE FROM `Groups_Monitors` WHERE `GroupId`=?', array($group_id));
$group_id = $group->Id();
if ( $group_id ) {
foreach ( $_POST['newGroup']['MonitorIds'] as $mid ) {
foreach ( $_REQUEST['newGroup']['MonitorIds'] as $mid ) {
dbQuery('INSERT INTO `Groups_Monitors` (`GroupId`,`MonitorId`) VALUES (?,?)', array($group_id, $mid));
}
}
$view = 'none';
$refreshParent = true;
$closePopup = true;
$redirect = '?view=groups';
}
?>

View File

@ -24,7 +24,7 @@ if ( ! canEdit('Monitors') ) {
return;
}
if ( $action == 'monitor' ) {
if ( $action == 'save' ) {
$mid = 0;
if ( !empty($_REQUEST['mid']) ) {
$mid = validInt($_REQUEST['mid']);
@ -273,7 +273,7 @@ if ( $action == 'monitor' ) {
// really should thump zmwatch and maybe zmtrigger too.
//daemonControl( 'restart', 'zmwatch.pl' );
} // end if restart
$view = 'console';
$redirect = '?view=console';
} else {
ZM\Warning("Unknown action $action in Monitor");
} // end if action == Delete

View File

@ -24,7 +24,7 @@ if ( ! canEdit('System') ) {
return;
}
if ( $action == 'Save' ) {
if ( $action == 'save' ) {
if ( !empty($_REQUEST['id']) ) {
$dbServer = dbFetchOne(
'SELECT * FROM Servers WHERE Id=?',
@ -46,7 +46,7 @@ if ( $action == 'Save' ) {
}
$refreshParent = true;
}
$view = 'none';
$redirect = '?view=options&tab=servers';
} else {
ZM\Error("Unknown action $action in saving Server");
}

View File

@ -17,33 +17,39 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
require_once('includes/Zone.php');
global $error_message;
if ( !empty($_REQUEST['mid']) && canEdit('Monitors', $_REQUEST['mid']) ) {
$mid = validInt($_REQUEST['mid']);
$monitor = new ZM\Monitor($mid);
if ( $action == 'delete' ) {
if ( isset($_REQUEST['markZids']) ) {
$restart_zmc = 0;
foreach ( $_REQUEST['markZids'] as $markZid ) {
$monitors_to_restart = array();
if ( ! $restart_zmc ) {
$zone = dbFetchOne('SELECT * FROM Zones WHERE Id=?', NULL, array($markZid));
if ( $zone['Type'] == 'Privacy' ) {
$restart_zmc = 1;
}
}
dbQuery('DELETE FROM Zones WHERE MonitorId=? AND Id=?', array($mid, $markZid));
if ( $action == 'delete' ) {
if ( isset($_REQUEST['markZids']) ) {
foreach ( $_REQUEST['markZids'] as $markZid ) {
$zone = new ZM\Zone($markZid);
if ( ! $zone->Id() ) {
$error_message .= 'Zone not found for id ' . $markZid.'<br/>';
continue;
}
if ( daemonCheck() && $monitor->Type() != 'WebSite' ) {
$monitor = $zone->Monitor();
if ( !$monitor->CanEdit() ) {
$error_message .= 'You do not have permission to edit zones for monitor ' . $monitor->Name().'.<br/>';
continue;
}
# Could use true but store the object instead for easy access later
$monitors_to_restart[$monitor->Id()] = $monitor;
$error_message .= $zone->delete();
} # end foreach Zone
foreach ( $monitors_to_restart as $mid => $monitor ) {
if ( daemonCheck() and ($monitor->Type() != 'WebSite') ) {
zmaControl($mid, 'stop');
if ( $restart_zmc )
if ( $monitor->Type() == 'Privacy' )
zmcControl($mid, 'restart');
zmaControl($mid, 'start');
} // end if daemonCheck()
$refreshParent = true;
} // end if isset($_REQUEST['markZids'])
} // end if action
} // end if $mid and canEdit($mid)
}
$refreshParent = true;
} // end if isset($_REQUEST['markZids'])
} // end if action
?>

View File

@ -64,7 +64,8 @@ function dbConnect() {
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $ex) {
echo "Unable to connect to ZM db using dsn $dsn host".ZM_DB_HOST.' user: ('.ZM_DB_USER.') password ('.ZM_DB_PASS.': '.$ex->getMessage();
global $error_message;
$error_message = "Unable to connect to ZM db using dsn $dsn<br/><br/>".$ex->getMessage();
error_log('Unable to connect to ZM DB ' . $ex->getMessage());
$dbConn = null;
}
@ -72,7 +73,8 @@ function dbConnect() {
} // end function dbConnect
if ( !dbConnect() ) {
ZM\Fatal('Failed db connection');
include('views/no_database_connection.php');
exit();
}
function dbDisconnect() {

View File

@ -487,6 +487,16 @@ function makePopupButton($url, $winName, $winSize, $buttonValue, $condition=1, $
return $string;
}
function makeButton($url, $buttonValue, $condition=1, $options='') {
$string = '<button type="button" data-on-click-this="'.$buttonValue.'"';
$string .= ' data-url="' .$url. '"';
if (!$condition) {
$string .= ' disabled="disabled"';
}
$string .= ($options ? (' ' . $options) : '') . '/>'.translate($buttonValue).'</button>'.PHP_EOL;
return $string;
}
function htmlSelect($name, $contents, $values, $behaviours=false) {
$behaviourText = '';
if ( !empty($behaviours) ) {
@ -1109,7 +1119,7 @@ function parseFilter(&$filter, $saveToSession=false, $querySep='&amp;') {
$Filter = ZM\Filter::parse($filter, $querySep);
$filter['sql'] = $Filter->sql();
$filter['querystring'] = $Filter->querystring();
$filter['querystring'] = $Filter->querystring($querySep);
$filter['hidden_fields'] = $Filter->hidden_fields();
$filter['pre_sql_conditions'] = $Filter->pre_sql_conditions();
$filter['post_sql_conditions'] = $Filter->post_sql_conditions();
@ -2148,7 +2158,10 @@ function getStreamHTML($monitor, $options = array()) {
}
$options['mode'] = 'single';
$streamSrc = $monitor->getStreamSrc($options);
return getImageStill('liveStream'.$monitor->Id(), $streamSrc, $options['width'], $options['height'], $monitor->Name());
return getImageStill('liveStream'.$monitor->Id(), $streamSrc,
(isset($options['width']) ? $options['width'] : null),
(isset($options['height']) ? $options['height'] : null),
$monitor->Name());
}
} // end function getStreamHTML

View File

@ -125,7 +125,8 @@ $SLANG = array(
'AttrEndDate' => 'End Date',
'AttrStartDateTime' => 'Start Date/Time',
'AttrEndDateTime' => 'End Date/Time',
'AttrDiskSpace' => 'Disk Space',
'AttrEventDiskSpace' => 'Event Disk Space',
'AttrDiskSpace' => 'File System Disk Space',
'AttrDiskBlocks' => 'Disk Blocks',
'AttrDiskPercent' => 'Disk Percent',
'AttrDuration' => 'Duration',
@ -260,7 +261,9 @@ $SLANG = array(
'ConfigType' => 'Config Type',
'ConfiguredFor' => 'Configured for',
'ConfigURL' => 'Config Base URL',
'ConfirmDeleteControl' => 'Warning, deleting a control will reset all monitors that use it to be uncontrollable.<br><br>Are you sure you wish to delete?',
'ConfirmDeleteEvents' => 'Are you sure you wish to delete the selected events?',
'ConfirmDeleteTitle' => 'Delete Confirmation',
'ConfirmPassword' => 'Confirm Password',
'ConjAnd' => 'and',
'ConjOr' => 'or',
@ -319,6 +322,7 @@ $SLANG = array(
'DuplicateMonitorName' => 'Duplicate Monitor Name',
'Duration' => 'Duration',
'Edit' => 'Edit',
'EditControl' => 'Edit Control',
'EditLayout' => 'Edit Layout',
'Email' => 'Email',
'EnableAlarms' => 'Enable Alarms',

View File

@ -326,24 +326,10 @@ ul.tabList li.active a {
color: #dc143c;
}
fieldset {
border: 1px solid black;
padding: 4px;
margin-bottom: 8px;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
fieldset > legend {
padding: 0 2px;
}
/*
* Behavior classes
*/
.ok, .infoText {
color: #0fb9b1;
}

View File

@ -0,0 +1,18 @@
tr.log-fat td {
background-color:#ffcccc;
font-weight: bold;
}
tr.log-err td {
background-color:#ffcccc;
}
tr.log-war td {
background-color: #ffe4b5;
}
tr.log-dbg td {
color: #666666;
font-style: italic;
}

View File

@ -0,0 +1,3 @@
input[type="number"] {
width: 50px;
}

View File

@ -572,7 +572,7 @@ function getLogHTML() {
if ( ZM\logToDatabase() > ZM\Logger::NOLOG ) {
$logstate = logState();
$class = ($logstate == 'ok') ? 'text-success' : ($logstate == 'alert' ? 'text-warning' : (($logstate == 'alarm' ? 'text-danger' : '')));
$result .= '<li id="getLogHTML" class="nav-item dropdown mx-2">'.makePopupLink('?view=log', 'zmLog', 'log', '<span class="nav-link '.$class.'">'.translate('Log').'</span>').'</li>'.PHP_EOL;
$result .= '<li id="getLogHTML" class="nav-item dropdown mx-2">'.makeLink('?view=log', '<span class="nav-link '.$class.'">'.translate('Log').'</span>').'</li>'.PHP_EOL;
}
}
@ -588,7 +588,7 @@ function getLogIconHTML() {
$logstate = logState();
$class = ( $logstate == 'alert' ) ? 'text-warning' : (( $logstate == 'alarm' ) ? 'text-danger' : '');
$result .= '<li id="getLogIconHTML" class="nav-item dropdown">'.
makePopupLink('?view=log', 'zmLog', 'log', '<span class="mx-1 ' .$class. '"><i class="material-icons md-18">report</i>'.translate('Log').'</span>').
makeLink('?view=log', '<span class="mx-1 ' .$class. '"><i class="material-icons md-18">report</i>'.translate('Log').'</span>').
'</li>'.PHP_EOL;
}
}
@ -702,8 +702,6 @@ function getHeaderFlipHTML() {
// Returns the html representing the logged in user name and avatar
function getAcctCircleHTML($skin, $user=null) {
// Include Logout modal
include("skins/$skin/views/logout.php");
$result = '';
if ( ZM_OPT_USE_AUTH and $user ) {
@ -723,7 +721,7 @@ function getStatusBtnHTML($status) {
if ( canEdit('System') ) {
//$result .= '<li class="nav-item dropdown">'.PHP_EOL;
$result .= '<form id="getStatusBtnHTML" class="form-inline">'.PHP_EOL;
$result .= '<button type="button" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modalState">' .$status. '</button>'.PHP_EOL;
$result .= '<button type="button" class="btn btn-default navbar-btn" id="stateModalBtn">' .$status. '</button>'.PHP_EOL;
$result .= '</form>'.PHP_EOL;
//$result .= '</li>'.PHP_EOL;
@ -754,69 +752,6 @@ function runtimeStatus($running=null) {
return $running ? ($state ? $state : translate('Running')) : translate('Stopped');
}
// Returns the modal html representing the selected Option Help item
function getOptionHelpHTML($optionHelpIndex, $OLANG) {
$result = '';
$ZMoptionHelpIndex = 'ZM_'.$optionHelpIndex;
if ( !empty($OLANG[$optionHelpIndex]) ) {
$optionHelpText = $OLANG[$optionHelpIndex]['Help'];
} else {
$optionHelpText = dbFetchOne('SELECT Help FROM Config WHERE Name=?', 'Help', array($optionHelpIndex));
}
$optionHelpText = validHtmlStr($optionHelpText);
$optionHelpText = preg_replace('/~~/', '<br/>', $optionHelpText );
$optionHelpText = preg_replace('/\[(.+)\]\((.+)\)/', '<a href="$2" target="_blank">$1</a>', $optionHelpText);
$result .= '<div id="optionhelp" class="modal" tabindex="-1" role="dialog">'.PHP_EOL;
$result .= '<div class="modal-dialog" role="document">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title">' .translate('OptionHelp'). '</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<h3>' .validHtmlStr($optionHelpIndex). '</h3>'.PHP_EOL;
$result .= '<p class="textblock">' .$optionHelpText. '</p>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button type="button" id="ohCloseBtn" class="btn btn-secondary" data-dismiss="modal">Close</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
// Return an Error No Permissions Modal
function getENoPermHTML() {
$result = '';
$result .= '<div id="ENoPerm" class="modal fade" id="staticBackdrop" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">'.PHP_EOL;
$result .= '<div class="modal-dialog">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title" id="staticBackdropLabel">ZoneMinder ' .translate('Error'). '</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<p>' .translate('YouNoPerms'). '</p>'.PHP_EOL;
$result .= '<p>' .translate('ContactAdmin'). '</p>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button type="button" id="enpCloseBtn" class="btn btn-secondary" data-dismiss="modal">Close</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
function getStatsTableHTML($eid, $fid, $row='') {
if ( !canView('Events') ) return;
$result = '';
@ -878,231 +813,14 @@ function getStatsTableHTML($eid, $fid, $row='') {
return $result;
}
// This is the HTML representing the Delete confirmation modal on the Events page
function getDelConfirmHTML() {
$result = '';
$result .= '<div id="deleteConfirm" class="modal fade" class="modal" tabindex="-1">'.PHP_EOL;
$result .= '<div class="modal-dialog">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title">Delete Confirmation</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<p>' .translate('ConfirmDeleteEvents'). '</p>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button id="delCancelBtn" type="button" class="btn btn-secondary" data-dismiss="modal">' .translate('Cancel'). '</button>'.PHP_EOL;
$result .= '<button id ="delConfirmBtn" type="button" class="btn btn-danger">' .translate('Delete'). '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
function getStorageModalHTML($sid) {
$result = '';
$null = '';
$checked = 'checked="checked"';
if ( !canEdit('System') ) return;
require_once('includes/Server.php');
require_once('includes/Storage.php');
if ( $_REQUEST['id'] ) {
if ( !($newStorage = ZM\Storage::find_one(array('Id'=>$sid)) ) ) {
// Perhaps do something different here, rather than return nothing
return;
}
} else {
$newStorage = new ZM\Storage();
$newStorage->Name(translate('NewStorage'));
}
$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') );
$scheme_options = array(
'Deep' => translate('Deep'),
'Medium' => translate('Medium'),
'Shallow' => translate('Shallow'),
);
$servers = ZM\Server::find( null, array('order'=>'lower(Name)') );
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
}
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
// Use this function to manually insert the csrf key into the form when using a modal generated via ajax call
function getCSRFinputHTML() {
if ( isset($GLOBALS['csrf']['key']) ) {
$csrf_input = '<input type="hidden" name="__csrf_magic" value="key:' .csrf_hash($GLOBALS['csrf']['key']). '" />'.PHP_EOL;
$result = '<input type="hidden" name="__csrf_magic" value="key:' .csrf_hash($GLOBALS['csrf']['key']). '" />'.PHP_EOL;
} else {
$csrf_input = '';
}
$result .= '<div class="modal fade" id="storageModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">'.PHP_EOL;
$result .= '<div class="modal-dialog">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title" id="staticBackdropLabel">' .translate('Storage').' - '.$newStorage->Name(). '</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<form id="storageModalForm" name="contentForm" method="post" action="?view=storage&action=save" class="validateFormOnSubmit">'.PHP_EOL;
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
$result .= $csrf_input;
$result .= '<input type="hidden" name="view" value="storage"/>'.PHP_EOL;
$result .= '<input type="hidden" name="object" value="storage"/>'.PHP_EOL;
$result .= '<input type="hidden" name="id" value="' .validHtmlStr($sid). '"/>'.PHP_EOL;
$result .= '<table id="contentTable" class="major table-sm">'.PHP_EOL;
$result .= '<tbody>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Name'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Name]" value="' .$newStorage->Name(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Path'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Path]" value="' .$newStorage->Path(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Url'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newStorage[Url]" value="' .$newStorage->Url(). '"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Server'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[ServerId]', array(''=>'Remote / No Specific Server') + $ServersById, $newStorage->ServerId()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Type'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[Type]', $type_options, $newStorage->Type()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('StorageScheme'). '</th>'.PHP_EOL;
$result .= '<td>' .htmlSelect('newStorage[Scheme]', $scheme_options, $newStorage->Scheme()). '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('StorageDoDelete'). '</th>'.PHP_EOL;
$result .= '<td>'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[DoDelete]" value="1" ' .($newStorage->DoDelete() ? $checked : $null). '>Yes'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[DoDelete]" value="0" ' .($newStorage->DoDelete() ? $null : $checked). '>No'.PHP_EOL;
$result .= '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th class="text-right pr-3" scope="row">' .translate('Enabled'). '</th>'.PHP_EOL;
$result .= '<td>'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[Enabled]" value="1" ' .($newStorage->Enabled() ? $checked : $null). '>Yes'.PHP_EOL;
$result .= '<input type="radio" name="newStorage[Enabled]" value="0" ' .($newStorage->Enabled() ? $null : $checked). '>No'.PHP_EOL;
$result .= '</td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '</tbody>'.PHP_EOL;
$result .= '</table>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button name="action" id="storageSubmitBtn" type="submit" class="btn btn-primary" value="Save">' .translate('Save'). '</button>'.PHP_EOL;
$result .= '<button type="button" class="btn btn-secondary" data-dismiss="modal">' .translate('Cancel'). '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</form>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
function getEventDetailHTML($eid='', $eids='') {
$result = '';
$inputs = '';
$disabled = 'disabled="disabled"';
$null = '';
if ( !canEdit('Events') ) return;
// We have to manually insert the csrf key into the form when using a modal generated via ajax call
if ( isset($GLOBALS['csrf']['key']) ) {
$csrf_input = '<input type="hidden" name="__csrf_magic" value="key:' .csrf_hash($GLOBALS['csrf']['key']). '" />'.PHP_EOL;
} else {
$csrf_input = '';
}
if ( $eid ){ // Single Event Mode
$eid = validInt($eid);
$title = translate('Event').' '.$eid.PHP_EOL;
$inputs .= '<input type="hidden" name="markEids[]" value="' .$eid. '"/>'.PHP_EOL;
$newEvent = dbFetchOne('SELECT E.* FROM Events AS E WHERE E.Id = ?', NULL, array($eid));
} elseif ( $eids ) { // Multi Event Mode
$title = translate('Events');
$sql = 'SELECT E.* FROM Events AS E WHERE ';
$sqlWhere = array();
$sqlValues = array();
foreach ( $eids as $eid ) {
$eid = validInt($eid);
$inputs .= '<input type="hidden" name="markEids[]" value="' .$eid. '"/>'.PHP_EOL;
$sqlWhere[] = 'E.Id = ?';
$sqlValues[] = $eid;
}
unset($eid);
$sql .= join(' OR ', $sqlWhere);
foreach( dbFetchAll( $sql, NULL, $sqlValues ) as $row ) {
if ( !isset($newEvent) ) {
$newEvent = $row;
} else {
if ( $newEvent['Cause'] && $newEvent['Cause'] != $row['Cause'] )
$newEvent['Cause'] = '';
if ( $newEvent['Notes'] && $newEvent['Notes'] != $row['Notes'] )
$newEvent['Notes'] = '';
}
}
} else { // Event Mode not specified - should we really proceed if neither eid nor eids is set?
$title = translate('Events');
$result = '';
}
$result .= '<div class="modal fade" id="eventDetailModal" data-backdrop="static" data-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">'.PHP_EOL;
$result .= '<div class="modal-dialog">'.PHP_EOL;
$result .= '<div class="modal-content">'.PHP_EOL;
$result .= '<div class="modal-header">'.PHP_EOL;
$result .= '<h5 class="modal-title" id="staticBackdropLabel">' .$title. '</h5>'.PHP_EOL;
$result .= '<button type="button" class="close" data-dismiss="modal" aria-label="Close">'.PHP_EOL;
$result .= '<span aria-hidden="true">&times;</span>'.PHP_EOL;
$result .= '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-body">'.PHP_EOL;
$result .= '<form name="contentForm" id="eventDetailForm" method="post" action="?view=eventdetail&action=eventdetail">'.PHP_EOL;
$result .= $csrf_input;
$result .= '<input type="hidden" name="action" value="eventdetail"/>'.PHP_EOL;
$result .= '<input type="hidden" name="view" value="eventdetail"/>'.PHP_EOL;
$result .= $inputs;
$result .= '<table id="contentTable" class="table-sm">'.PHP_EOL;
$result .= '<tbody>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th scope="row">' .translate('Cause'). '</th>'.PHP_EOL;
$result .= '<td><input type="text" name="newEvent[Cause]" value="' .validHtmlStr($newEvent['Cause']). '" size="32"/></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '<tr>'.PHP_EOL;
$result .= '<th scope="row" class="align-middle">' .translate('Notes'). '</th>'.PHP_EOL;
$result .= '<td><textarea name="newEvent[Notes]" rows="6" cols="33">' .validHtmlStr($newEvent['Notes']). '</textarea></td>'.PHP_EOL;
$result .= '</tr>'.PHP_EOL;
$result .= '</tbody>'.PHP_EOL;
$result .= '</table>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '<div class="modal-footer">'.PHP_EOL;
$result .= '<button type="submit" name="action" id="eventDetailSaveBtn" class="btn btn-primary" value="save" ' .( !canEdit('Events') ? $disabled : $null ). '>' .translate('Save'). '</button>'.PHP_EOL;
$result .= '<button type="button" class="btn btn-secondary" data-dismiss="modal">' .translate('Cancel'). '</button>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</form>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
$result .= '</div>'.PHP_EOL;
return $result;
}
@ -1112,9 +830,6 @@ function xhtmlFooter() {
global $view;
global $skin;
global $basename;
if ( canEdit('System') ) {
include("skins/$skin/views/state.php");
}
$skinJsPhpFile = getSkinFile('js/skin.js.php');
$cssJsFile = getSkinFile('js/'.$css.'.js');
$viewJsFile = getSkinFile('views/js/'.$basename.'.js');
@ -1133,12 +848,13 @@ function xhtmlFooter() {
<script src="skins/<?php echo $skin; ?>/js/bootstrap-table-export.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/bootstrap-table-page-jump-to.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/bootstrap-table-cookie.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/bootstrap-table-toolbar.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/bootstrap-table-auto-refresh.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/chosen/chosen.jquery.min.js"></script>
<script src="skins/<?php echo $skin; ?>/js/dateTimePicker/jquery-ui-timepicker-addon.js"></script>
<script src="<?php echo cache_bust('js/Server.js'); ?>"></script>
<script nonce="<?php echo $cspNonce; ?>">var $j = jQuery.noConflict();</script>
<script src="<?php echo cache_bust('skins/'.$skin.'/views/js/state.js') ?>"></script>
<?php
if ( $view == 'event' ) {
?>

View File

@ -43,316 +43,6 @@ function getSlotFrame($slot) {
return $slotFrame;
}
function parseFilterToTree($filter) {
if ( count($filter['terms']) <= 0 ) {
return false;
}
$terms = $filter['terms'];
$StorageArea = NULL;
$postfixExpr = array();
$postfixStack = array();
$priorities = array(
'<' => 1,
'<=' => 1,
'>' => 1,
'>=' => 1,
'=' => 2,
'!=' => 2,
'=~' => 2,
'!~' => 2,
'=[]' => 2,
'![]' => 2,
'and' => 3,
'or' => 4,
);
for ( $i = 0; $i < count($terms); $i++ ) {
$term = $terms[$i];
if ( !empty($term['cnj']) ) {
while( true ) {
if ( !count($postfixStack) ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} elseif ( $priorities[$term['cnj']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) {
$postfixStack[] = array('type'=>'cnj', 'value'=>$term['cnj'], 'sqlValue'=>$term['cnj']);
break;
} else {
$postfixExpr[] = array_pop($postfixStack);
}
}
} # end if ! empty cnj
if ( !empty($term['obr']) ) {
for ( $j = 0; $j < $term['obr']; $j++ ) {
$postfixStack[] = array('type'=>'obr', 'value'=>$term['obr']);
}
}
if ( !empty($term['attr']) ) {
$dtAttr = false;
switch ( $term['attr']) {
case 'MonitorName':
$sqlValue = 'M.'.preg_replace( '/^Monitor/', '', $term['attr']);
break;
case 'ServerId':
$sqlValue .= 'M.ServerId';
break;
case 'StorageServerId':
$sqlValue .= 'S.ServerId';
break;
case 'FilterServerId':
$sqlValue .= ZM_SERVER_ID;
break;
case 'DateTime':
case 'StartDateTime':
$sqlValue = 'E.StartTime';
$dtAttr = true;
break;
case 'Date':
case 'StartDate':
$sqlValue = 'to_days(E.StartTime)';
$dtAttr = true;
break;
case 'Time':
case 'StartTime':
$sqlValue = 'extract(hour_second from E.StartTime)';
break;
case 'Weekday':
case 'StartWeekday':
$sqlValue = 'weekday(E.StartTime)';
break;
case 'EndDateTime':
$sqlValue = 'E.EndTime';
$dtAttr = true;
break;
case 'EndDate':
$sqlValue = 'to_days(E.EndTime)';
$dtAttr = true;
break;
case 'EndTime':
$sqlValue = 'extract(hour_second from E.EndTime)';
break;
case 'EndWeekday':
$sqlValue = 'weekday(E.EndTime)';
break;
case 'Id':
case 'Name':
case 'MonitorId':
case 'StorageId':
case 'SecondaryStorageId':
case 'Length':
case 'Frames':
case 'AlarmFrames':
case 'TotScore':
case 'AvgScore':
case 'MaxScore':
case 'Cause':
case 'Notes':
case 'StateId':
case 'Archived':
$sqlValue = 'E.'.$term['attr'];
break;
case 'DiskPercent':
// Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH
if ( ! $StorageArea ) {
for ( $j = 0; $j < count($terms); $j++ ) {
if ( isset($terms[$j]['attr']) and $terms[$j]['attr'] == 'StorageId' and isset($terms[$j]['val']) ) {
$StorageArea = new Storage($terms[$j]['val']);
break;
}
} // end foreach remaining term
if ( ! $StorageArea ) $StorageArea = new Storage();
} // end no StorageArea found yet
$sqlValue = getDiskPercent($StorageArea);
break;
case 'DiskBlocks':
// Need to specify a storage area, so need to look through other terms looking for a storage area, else we default to ZM_EVENTS_PATH
if ( ! $StorageArea ) {
for ( $j = 0; $j < count($terms); $j++ ) {
if ( isset($terms[$j]['attr']) and $terms[$j]['attr'] == 'StorageId' and isset($terms[$j]['val']) ) {
$StorageArea = new Storage($terms[$j]['val']);
break;
}
} // end foreach remaining term
if ( ! $StorageArea ) $StorageArea = new Storage();
} // end no StorageArea found yet
$sqlValue = getDiskBlocks($StorageArea);
break;
default :
$sqlValue = $term['attr'];
break;
}
if ( $dtAttr ) {
$postfixExpr[] = array('type'=>'attr', 'value'=>$term['attr'], 'sqlValue'=>$sqlValue, 'dtAttr'=>true);
} else {
$postfixExpr[] = array('type'=>'attr', 'value'=>$term['attr'], 'sqlValue'=>$sqlValue);
}
} # end if attr
if ( isset($term['op']) ) {
if ( empty($term['op']) ) {
$term['op'] = '=';
}
switch ( $term['op']) {
case '=' :
case '!=' :
case '>=' :
case '>' :
case '<' :
case '<=' :
case 'LIKE' :
case 'NOT LIKE':
$sqlValue = $term['op'];
break;
case '=~' :
$sqlValue = 'regexp';
break;
case '!~' :
$sqlValue = 'not regexp';
break;
case '=[]' :
case 'IN' :
$sqlValue = 'in (';
break;
case '![]' :
$sqlValue = 'not in (';
break;
case 'IS' :
case 'IS NOT' :
if ( $term['val'] == 'Odd' ) {
$sqlValue .= ' % 2 = 1';
} else if ( $term['val'] == 'Even' ) {
$sqlValue .= ' % 2 = 0';
} else {
$sqlValue .= ' '.$term['op'];
}
break;
default :
ZM\Error('Unknown operator in filter '.$term['op']);
}
while( true ) {
if ( !count($postfixStack) ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue);
break;
} elseif ( $postfixStack[count($postfixStack)-1]['type'] == 'obr' ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue);
break;
} elseif ( $priorities[$term['op']] < $priorities[$postfixStack[count($postfixStack)-1]['value']] ) {
$postfixStack[] = array('type'=>'op', 'value'=>$term['op'], 'sqlValue'=>$sqlValue );
break;
} else {
$postfixExpr[] = array_pop($postfixStack);
}
} // end while
} // end if operator
if ( isset($term['val']) ) {
$valueList = array();
foreach ( preg_split('/["\'\s]*?,["\'\s]*?/', preg_replace('/^["\']+?(.+)["\']+?$/', '$1', $term['val'])) as $value ) {
switch ( $term['attr'] ) {
case 'MonitorName':
case 'Name':
case 'Cause':
case 'Notes':
if ( $term['op'] == 'LIKE' || $term['op'] == 'NOT LIKE' ) {
$value = '%'.$value.'%';
}
$value = dbEscape($value);
break;
case 'MonitorServerId':
case 'FilterServerId':
case 'StorageServerId':
case 'ServerId':
if ( $value == 'ZM_SERVER_ID' ) {
$value = ZM_SERVER_ID;
} else if ( $value == 'NULL' ) {
} else {
$value = dbEscape($value);
}
break;
case 'StorageId':
$StorageArea = new Storage($value);
if ( $value != 'NULL' )
$value = dbEscape($value);
break;
case 'DateTime':
case 'EndDateTime':
case 'StartDateTime':
$value = "'".strftime(STRF_FMT_DATETIME_DB, strtotime($value))."'";
break;
case 'Date':
case 'EndDate':
case 'StartDate':
$value = 'to_days(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
case 'Time':
case 'EndTime':
case 'StartTime':
$value = 'extract(hour_second from \''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
case 'Weekday':
case 'EndWeekday':
case 'StartWeekday':
$value = 'weekday(\''.strftime(STRF_FMT_DATETIME_DB, strtotime($value)).'\')';
break;
default :
if ( $value != 'NULL' )
$value = dbEscape($value);
} // end switch attribute
$valueList[] = $value;
} // end foreach value
$postfixExpr[] = array('type'=>'val', 'value'=>$term['val'], 'sqlValue'=>join(',', $valueList));
} // end if has val
if ( !empty($term['cbr']) ) {
for ( $j = 0; $j < $term['cbr']; $j++ ) {
while ( count($postfixStack) ) {
$element = array_pop($postfixStack);
if ( $element['type'] == 'obr' ) {
$postfixExpr[count($postfixExpr)-1]['bracket'] = true;
break;
}
$postfixExpr[] = $element;
}
}
} #end if cbr
} # end foreach term
while ( count($postfixStack) ) {
$postfixExpr[] = array_pop($postfixStack);
}
$exprStack = array();
//foreach ( $postfixExpr as $element )
//{
//echo $element['value'].' ';
//}
//echo "<br>";
foreach ( $postfixExpr as $element ) {
if ( $element['type'] == 'attr' || $element['type'] == 'val' ) {
$node = array('data'=>$element, 'count'=>0);
$exprStack[] = $node;
} elseif ( $element['type'] == 'op' || $element['type'] == 'cnj' ) {
$right = array_pop($exprStack);
$left = array_pop($exprStack);
$node = array('data'=>$element, 'count'=>2+$left['count']+$right['count'], 'right'=>$right, 'left'=>$left);
$exprStack[] = $node;
} else {
ZM\Fatal('Unexpected element type \''.$element['type'].'\', value \''.$element['value'].'\'');
}
}
if ( count($exprStack) != 1 ) {
ZM\Fatal('Expression stack has '.count($exprStack).' elements');
}
return array_pop($exprStack);
}
function _parseTreeToInfix($node) {
$expression = '';
if ( isset($node) ) {
@ -443,7 +133,7 @@ function parseTreeToFilter($tree) {
function parseTreeToQuery($tree) {
$filter = parseTreeToFilter($tree);
parseFilter($filter, false, '&');
return $filter['query'];
return $filter['querystring'];
}
function _drawTree($node, $level) {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -23,6 +23,22 @@
//
var popupOptions = "resizable,scrollbars,status=no,toolbar=yes";
// Globally define the icons used in the bootstrap-table top-right toolbar
var icons = {
paginationSwitchDown: 'fa-caret-square-o-down',
paginationSwitchUp: 'fa-caret-square-o-up',
export: 'fa-download',
refresh: 'fa-retweet',
autoRefresh: 'fa-clock-o',
advancedSearchIcon: 'fa-chevron-down',
toggleOff: 'fa-toggle-off',
toggleOn: 'fa-toggle-on',
columns: 'fa-th-list',
fullscreen: 'fa-arrows-alt',
detailOpen: 'fa-plus',
detailClose: 'fa-minus'
};
function checkSize() {
if ( 0 ) {
if (window.outerHeight) {
@ -159,6 +175,22 @@ window.addEventListener("DOMContentLoaded", function onSkinDCL() {
});
});
document.querySelectorAll(".zmlink").forEach(function(el) {
el.addEventListener("click", function onClick(evt) {
var el = this;
var url;
if ( el.hasAttribute("href") ) {
// <a>
url = el.getAttribute("href");
} else {
// buttons
url = el.getAttribute("data-url");
}
evt.preventDefault();
window.location.assign(url);
});
});
document.querySelectorAll(".pillList a").forEach(function addOnClick(el) {
el.addEventListener("click", submitTab);
});
@ -312,6 +344,10 @@ if ( currentView != 'none' && currentView != 'login' ) {
$j.ajaxSetup({timeout: AJAX_TIMEOUT}); //sets timeout for all getJSON.
$j(document).ready(function() {
// Load the Logout and State modals into the dom
getLogoutModal();
if ( canEditSystem ) $j('#stateModalBtn').click(getStateModal);
// Trigger autorefresh of the widget bar stats on the navbar
if ( $j('.navbar').length ) {
setInterval(getNavBar, navBarRefresh);
@ -389,10 +425,7 @@ if ( currentView != 'none' && currentView != 'login' ) {
$j(".optionhelp").click(function(evt) {
$j.getJSON(thisUrl + '?request=modal&modal=optionhelp&ohndx=' + evt.target.id)
.done(optionhelpModal)
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
});
});
@ -416,7 +449,7 @@ if ( currentView != 'none' && currentView != 'login' ) {
.done(setNavBar)
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
console.log("Response Text: " + jqxhr.responseText.replace(/(<([^>]+)>)/gi, ''));
if ( textStatus != "timeout" ) {
// The idea is that this should only fail due to auth, so reload the page
// which should go to login if it can't stay logged in.
@ -426,6 +459,10 @@ if ( currentView != 'none' && currentView != 'login' ) {
}
function setNavBar(data) {
if ( !data ) {
console.error("No data in setNavBar");
return;
}
if ( data.auth ) {
if ( data.auth != auth_hash ) {
// Update authentication token.
@ -714,10 +751,7 @@ function reminderClickFunction() {
var option = $j(this).data('pdsa-dropdown-val');
$j.getJSON(thisUrl + '?view=version&action=version&option=' + option)
.done(window.location.reload(true)) //Do a full refresh to update ZM_DYN_LAST_VERSION
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
});
}
@ -737,8 +771,157 @@ function enoperm() {
$j('#ENoPerm').modal('hide');
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
}
function getLogoutModal() {
$j.getJSON(thisUrl + '?request=modal&modal=logout')
.done(function(data) {
if ( $j('#modalLogout').length ) {
$j('#modalLogout').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
})
.fail(logAjaxFail);
}
function getStateModal() {
$j.getJSON(thisUrl + '?request=modal&modal=state')
.done(function(data) {
if ( $j('#modalState').length ) {
$j('#modalState').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#modalState').modal('show');
manageStateModalBtns();
})
.fail(logAjaxFail);
}
function manageStateModalBtns() {
// Enable or disable the Delete button depending on the selected run state
$j("#runState").change(function() {
runstate = $j(this).val();
if ( (runstate == 'stop') || (runstate == 'restart') || (runstate == 'start') || (runstate == 'default') ) {
$j("#btnDelete").prop("disabled", true);
} else {
$j("#btnDelete").prop("disabled", false);
}
});
// Enable or disable the Save button when entering a new state
$j("#newState").keyup(function() {
length = $j(this).val().length;
if ( length < 1 ) {
$j("#btnSave").prop("disabled", true);
} else {
$j("#btnSave").prop("disabled", false);
}
});
// Delete a state
$j("#btnDelete").click(function() {
stateStuff('delete', $j("#runState").val());
});
// Save a new state
$j("#btnSave").click(function() {
stateStuff('save', undefined, $j("#newState").val());
});
// Change state
$j("#btnApply").click(function() {
stateStuff('state', $j("#runState").val());
});
}
function stateStuff(action, runState, newState) {
// the state action will redirect to console
var formData = {
'view': 'state',
'action': action,
'apply': 1,
'runState': runState,
'newState': newState
};
$j("#pleasewait").toggleClass("hidden");
$j.ajax({
type: 'POST',
url: thisUrl,
data: formData,
dataType: 'html',
timeout: 0
}).done(function(data) {
location.reload();
});
}
function logAjaxFail(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText.replace(/(<([^>]+)>)/gi, '')); // strip any html from the response
}
// Load the Modal HTML via Ajax call
function getModal(id) {
$j.getJSON(thisUrl + '?request=modal&modal='+id)
.done(function(data) {
if ( !data ) {
console.error("Get modal returned no data");
return;
}
if ( $j('#'+id).length ) {
$j('#'+id).replaceWith(data.html);
} else {
$j('body').append(data.html);
}
manageModalBtns(id);
modal = $j('#'+id+'Modal');
if ( ! modal.length ) {
console.log('No modal found');
}
$j('#'+id+'Modal').modal('show');
})
.fail(logAjaxFail);
}
function manageModalBtns(id) {
// Manage the CANCEL modal button
var cancelBtn = document.getElementById(id+"CancelBtn");
if ( cancelBtn ) {
document.getElementById(id+"CancelBtn").addEventListener('click', function onCancelClick(evt) {
$j('#'+id).modal('hide');
});
}
// 'data-on-click-this' calls the global function in the attribute value with the element when a click happens.
document.querySelectorAll('#'+id+'Modal button[data-on-click]').forEach(function attachOnClick(el) {
var fnName = el.getAttribute('data-on-click');
if ( !window[fnName] ) {
console.error('Nothing found to bind to ' + fnName + ' on element ' + el.name);
return;
} else {
console.log("Setting onclick for " + el.name);
}
el.onclick = window[fnName].bind(el, el);
});
}
function human_filesize(size, precision = 2) {
var units = Array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
var step = 1024;
var i = 0;
while ((size / step) > 0.9) {
size = size / step;
i++;
}
return (Math.round(size*(10^precision))/(10^precision))+units[i];
}

View File

@ -72,3 +72,4 @@ var imagePrefix = "<?php echo '?view=image&eid=' ?>";
var auth_hash = '<?php echo generateAuthHash(ZM_AUTH_HASH_IPS) ?>';
var auth_relay = '<?php echo get_auth_relay() ?>';
var running = <?php echo daemonCheck()?'true':'false' ?>;

View File

@ -372,7 +372,7 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
<?php
}
?>
<td class="colZones"><?php echo makePopupLink('?view=zones&amp;mid='.$monitor['Id'], 'zmZones', array('zones', $monitor['Width'], $monitor['Height']), $monitor['ZoneCount'], canView('Monitors')) ?></td>
<td class="colZones"><?php echo makeLink('?view=zones&amp;mid='.$monitor['Id'], $monitor['ZoneCount'], canView('Monitors')) ?></td>
<?php
if ( canEdit('Monitors') ) {
?>
@ -437,8 +437,5 @@ for( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
</div>
</form>
<?php
include('function.php');
// Include Donate Modal
include('donate.php');
xhtmlFooter();
?>

View File

@ -145,32 +145,39 @@ if ( isset($_REQUEST['newControl']) ) {
$newControl = $control;
}
$focusWindow = true;
xhtmlHeaders(__FILE__, translate('ControlCap').' - '.$newControl['Name']);
?>
<body>
<div id="page">
<div id="header">
<h2><?php echo translate('ControlCap') ?> - <?php echo validHtmlStr($newControl['Name']) ?></h2>
</div>
<div id="content">
<ul class="tabList">
<?php echo getNavBarHTML() ?>
<div id="page" class="container-fluid">
<div class="row flex-nowrap">
<nav> <!-- BEGIN PILL LIST -->
<ul class="nav nav-pills flex-column h-100 pillList" id="pills-tab" role="tab" aria-orientation="vertical">
<?php
foreach ( $tabs as $name=>$value ) {
if ( $tab == $name ) {
?>
<li class="active"><?php echo $value ?></li>
<li class="nav-item form-control-sm my-1"><a class="nav-link<?php echo $tab == $name ? ' active' : '' ?>" href="#" data-tab-name="<?php echo $name ?>"><?php echo $value ?></a></li>
<?php
} else {
?>
<li><a href="#" data-tab-name="<?php echo $name ?>"><?php echo $value ?></a></li>
<?php
}
}
?>
</ul>
</nav> <!-- END PILL LIST -->
<div class="clear"></div>
<div class="d-flex flex-column col-sm-offset-2 container-fluid">
<!-- BEGIN MINI HEADER -->
<div class="w-100 py-1">
<div class="float-left pl-3">
<button type="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>
<button type="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>
</div>
<div class="w-100 pt-2">
<h2><?php echo translate('ControlCap') ?> - <?php echo validHtmlStr($newControl['Name']) ?></h2>
</div>
</div>
<!-- BEGIN ITEM LIST -->
<div class="d-flex flex-row container-fluid pr-0">
<form name="contentForm" id="contentForm" method="post" action="?" class="validateFormOnSubmit">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
@ -320,158 +327,158 @@ switch ( $tab ) {
case 'main' :
{
?>
<tr><th scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('Type') ?></th><td><?php
<tr><th class="text-right pr-3" scope="row"><?php echo translate('Name') ?></th><td><input type="text" name="newControl[Name]" value="<?php echo validHtmlStr($newControl['Name']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('Type') ?></th><td><?php
$types = array( 'Local'=>translate('Local'), 'Remote'=>translate('Remote'), 'Ffmpeg'=>translate('Ffmpeg'), 'Libvlc'=>translate('Libvlc'), 'cURL'=>'cURL');
echo buildSelect('newControl[Type]', $types); ?></td></tr>
<tr><th scope="row"><?php echo translate('Protocol') ?></th><td><input type="text" name="newControl[Protocol]" value="<?php echo validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr>
<tr><th scope="row"><?php echo translate('CanWake') ?></th><td><input type="checkbox" name="newControl[CanWake]" value="1"<?php if ( !empty($newControl['CanWake']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSleep') ?></th><td><input type="checkbox" name="newControl[CanSleep]" value="1"<?php if ( !empty($newControl['CanSleep']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanReset') ?></th><td><input type="checkbox" name="newControl[CanReset]" value="1"<?php if ( !empty($newControl['CanReset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanReboot') ?></th><td><input type="checkbox" name="newControl[CanReboot]" value="1"<?php if ( !empty($newControl['CanReboot']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('Protocol') ?></th><td><input type="text" name="newControl[Protocol]" value="<?php echo validHtmlStr($newControl['Protocol']) ?>" size="24"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanWake') ?></th><td><input type="checkbox" name="newControl[CanWake]" value="1"<?php if ( !empty($newControl['CanWake']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanSleep') ?></th><td><input type="checkbox" name="newControl[CanSleep]" value="1"<?php if ( !empty($newControl['CanSleep']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanReset') ?></th><td><input type="checkbox" name="newControl[CanReset]" value="1"<?php if ( !empty($newControl['CanReset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanReboot') ?></th><td><input type="checkbox" name="newControl[CanReboot]" value="1"<?php if ( !empty($newControl['CanReboot']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
break;
}
case 'move' :
{
?>
<tr><th scope="row"><?php echo translate('CanMove') ?></th><td><input type="checkbox" name="newControl[CanMove]" value="1"<?php if ( !empty($newControl['CanMove']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanMoveDiag') ?></th><td><input type="checkbox" name="newControl[CanMoveDiag]" value="1"<?php if ( !empty($newControl['CanMoveDiag']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanMoveMap') ?></th><td><input type="checkbox" name="newControl[CanMoveMap]" value="1"<?php if ( !empty($newControl['CanMoveMap']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanMoveAbs') ?></th><td><input type="checkbox" name="newControl[CanMoveAbs]" value="1"<?php if ( !empty($newControl['CanMoveAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanMoveRel') ?></th><td><input type="checkbox" name="newControl[CanMoveRel]" value="1"<?php if ( !empty($newControl['CanMoveRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanMoveCon') ?></th><td><input type="checkbox" name="newControl[CanMoveCon]" value="1"<?php if ( !empty($newControl['CanMoveCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMove') ?></th><td><input type="checkbox" name="newControl[CanMove]" value="1"<?php if ( !empty($newControl['CanMove']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMoveDiag') ?></th><td><input type="checkbox" name="newControl[CanMoveDiag]" value="1"<?php if ( !empty($newControl['CanMoveDiag']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMoveMap') ?></th><td><input type="checkbox" name="newControl[CanMoveMap]" value="1"<?php if ( !empty($newControl['CanMoveMap']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMoveAbs') ?></th><td><input type="checkbox" name="newControl[CanMoveAbs]" value="1"<?php if ( !empty($newControl['CanMoveAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMoveRel') ?></th><td><input type="checkbox" name="newControl[CanMoveRel]" value="1"<?php if ( !empty($newControl['CanMoveRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanMoveCon') ?></th><td><input type="checkbox" name="newControl[CanMoveCon]" value="1"<?php if ( !empty($newControl['CanMoveCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
break;
}
case 'pan' :
{
?>
<tr><th scope="row"><?php echo translate('CanPan') ?></th><td><input type="checkbox" name="newControl[CanPan]" value="1"<?php if ( !empty($newControl['CanPan']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="number" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="number" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="number" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="number" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasPanSpeed') ?></th><td><input type="checkbox" name="newControl[HasPanSpeed]" value="1"<?php if ( !empty($newControl['HasPanSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="number" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="number" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboPan') ?></th><td><input type="checkbox" name="newControl[HasTurboPan]" value="1"<?php if ( !empty($newControl['HasTurboPan']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="number" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanPan') ?></th><td><input type="checkbox" name="newControl[CanPan]" value="1"<?php if ( !empty($newControl['CanPan']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinPanRange') ?></th><td><input type="number" name="newControl[MinPanRange]" value="<?php echo validHtmlStr($newControl['MinPanRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxPanRange') ?></th><td><input type="number" name="newControl[MaxPanRange]" value="<?php echo validHtmlStr($newControl['MaxPanRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinPanStep') ?></th><td><input type="number" name="newControl[MinPanStep]" value="<?php echo validHtmlStr($newControl['MinPanStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxPanStep') ?></th><td><input type="number" name="newControl[MaxPanStep]" value="<?php echo validHtmlStr($newControl['MaxPanStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasPanSpeed') ?></th><td><input type="checkbox" name="newControl[HasPanSpeed]" value="1"<?php if ( !empty($newControl['HasPanSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinPanSpeed') ?></th><td><input type="number" name="newControl[MinPanSpeed]" value="<?php echo validHtmlStr($newControl['MinPanSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxPanSpeed') ?></th><td><input type="number" name="newControl[MaxPanSpeed]" value="<?php echo validHtmlStr($newControl['MaxPanSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasTurboPan') ?></th><td><input type="checkbox" name="newControl[HasTurboPan]" value="1"<?php if ( !empty($newControl['HasTurboPan']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('TurboPanSpeed') ?></th><td><input type="number" name="newControl[TurboPanSpeed]" value="<?php echo validHtmlStr($newControl['TurboPanSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'tilt' :
{
?>
<tr><th scope="row"><?php echo translate('CanTilt') ?></th><td><input type="checkbox" name="newControl[CanTilt]" value="1"<?php if ( !empty($newControl['CanTilt']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="number" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="number" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="number" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="number" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTiltSpeed') ?></th><td><input type="checkbox" name="newControl[HasTiltSpeed]" value="1"<?php if ( !empty($newControl['HasTiltSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="number" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="number" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasTurboTilt') ?></th><td><input type="checkbox" name="newControl[HasTurboTilt]" value="1"<?php if ( !empty($newControl['HasTurboTilt']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="number" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanTilt') ?></th><td><input type="checkbox" name="newControl[CanTilt]" value="1"<?php if ( !empty($newControl['CanTilt']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinTiltRange') ?></th><td><input type="number" name="newControl[MinTiltRange]" value="<?php echo validHtmlStr($newControl['MinTiltRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxTiltRange') ?></th><td><input type="number" name="newControl[MaxTiltRange]" value="<?php echo validHtmlStr($newControl['MaxTiltRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinTiltStep') ?></th><td><input type="number" name="newControl[MinTiltStep]" value="<?php echo validHtmlStr($newControl['MinTiltStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxTiltStep') ?></th><td><input type="number" name="newControl[MaxTiltStep]" value="<?php echo validHtmlStr($newControl['MaxTiltStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasTiltSpeed') ?></th><td><input type="checkbox" name="newControl[HasTiltSpeed]" value="1"<?php if ( !empty($newControl['HasTiltSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinTiltSpeed') ?></th><td><input type="number" name="newControl[MinTiltSpeed]" value="<?php echo validHtmlStr($newControl['MinTiltSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxTiltSpeed') ?></th><td><input type="number" name="newControl[MaxTiltSpeed]" value="<?php echo validHtmlStr($newControl['MaxTiltSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasTurboTilt') ?></th><td><input type="checkbox" name="newControl[HasTurboTilt]" value="1"<?php if ( !empty($newControl['HasTurboTilt']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('TurboTiltSpeed') ?></th><td><input type="number" name="newControl[TurboTiltSpeed]" value="<?php echo validHtmlStr($newControl['TurboTiltSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'zoom' :
{
?>
<tr><th scope="row"><?php echo translate('CanZoom') ?></th><td><input type="checkbox" name="newControl[CanZoom]" value="1"<?php if ( !empty($newControl['CanZoom']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomAbs') ?></th><td><input type="checkbox" name="newControl[CanZoomAbs]" value="1"<?php if ( !empty($newControl['CanZoomAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomRel') ?></th><td><input type="checkbox" name="newControl[CanZoomRel]" value="1"<?php if ( !empty($newControl['CanZoomRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanZoomCon') ?></th><td><input type="checkbox" name="newControl[CanZoomCon]" value="1"<?php if ( !empty($newControl['CanZoomCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="number" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="number" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="number" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="number" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasZoomSpeed') ?></th><td><input type="checkbox" name="newControl[HasZoomSpeed]" value="1"<?php if ( !empty($newControl['HasZoomSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="number" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="number" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanZoom') ?></th><td><input type="checkbox" name="newControl[CanZoom]" value="1"<?php if ( !empty($newControl['CanZoom']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanZoomAbs') ?></th><td><input type="checkbox" name="newControl[CanZoomAbs]" value="1"<?php if ( !empty($newControl['CanZoomAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanZoomRel') ?></th><td><input type="checkbox" name="newControl[CanZoomRel]" value="1"<?php if ( !empty($newControl['CanZoomRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanZoomCon') ?></th><td><input type="checkbox" name="newControl[CanZoomCon]" value="1"<?php if ( !empty($newControl['CanZoomCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinZoomRange') ?></th><td><input type="number" name="newControl[MinZoomRange]" value="<?php echo validHtmlStr($newControl['MinZoomRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxZoomRange') ?></th><td><input type="number" name="newControl[MaxZoomRange]" value="<?php echo validHtmlStr($newControl['MaxZoomRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinZoomStep') ?></th><td><input type="number" name="newControl[MinZoomStep]" value="<?php echo validHtmlStr($newControl['MinZoomStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxZoomStep') ?></th><td><input type="number" name="newControl[MaxZoomStep]" value="<?php echo validHtmlStr($newControl['MaxZoomStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasZoomSpeed') ?></th><td><input type="checkbox" name="newControl[HasZoomSpeed]" value="1"<?php if ( !empty($newControl['HasZoomSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinZoomSpeed') ?></th><td><input type="number" name="newControl[MinZoomSpeed]" value="<?php echo validHtmlStr($newControl['MinZoomSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxZoomSpeed') ?></th><td><input type="number" name="newControl[MaxZoomSpeed]" value="<?php echo validHtmlStr($newControl['MaxZoomSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'focus' :
{
?>
<tr><th scope="row"><?php echo translate('CanFocus') ?></th><td><input type="checkbox" name="newControl[CanFocus]" value="1"<?php if ( !empty($newControl['CanFocus']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanAutoFocus') ?></th><td><input type="checkbox" name="newControl[CanAutoFocus]" value="1"<?php if ( !empty($newControl['CanAutoFocus']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusAbs') ?></th><td><input type="checkbox" name="newControl[CanFocusAbs]" value="1"<?php if ( !empty($newControl['CanFocusAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusRel') ?></th><td><input type="checkbox" name="newControl[CanFocusRel]" value="1"<?php if ( !empty($newControl['CanFocusRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanFocusCon') ?></th><td><input type="checkbox" name="newControl[CanFocusCon]" value="1"<?php if ( !empty($newControl['CanFocusCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="number" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="number" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="number" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="number" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasFocusSpeed') ?></th><td><input type="checkbox" name="newControl[HasFocusSpeed]" value="1"<?php if ( !empty($newControl['HasFocusSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="number" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="number" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanFocus') ?></th><td><input type="checkbox" name="newControl[CanFocus]" value="1"<?php if ( !empty($newControl['CanFocus']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanAutoFocus') ?></th><td><input type="checkbox" name="newControl[CanAutoFocus]" value="1"<?php if ( !empty($newControl['CanAutoFocus']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanFocusAbs') ?></th><td><input type="checkbox" name="newControl[CanFocusAbs]" value="1"<?php if ( !empty($newControl['CanFocusAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanFocusRel') ?></th><td><input type="checkbox" name="newControl[CanFocusRel]" value="1"<?php if ( !empty($newControl['CanFocusRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanFocusCon') ?></th><td><input type="checkbox" name="newControl[CanFocusCon]" value="1"<?php if ( !empty($newControl['CanFocusCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinFocusRange') ?></th><td><input type="number" name="newControl[MinFocusRange]" value="<?php echo validHtmlStr($newControl['MinFocusRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxFocusRange') ?></th><td><input type="number" name="newControl[MaxFocusRange]" value="<?php echo validHtmlStr($newControl['MaxFocusRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinFocusStep') ?></th><td><input type="number" name="newControl[MinFocusStep]" value="<?php echo validHtmlStr($newControl['MinFocusStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxFocusStep') ?></th><td><input type="number" name="newControl[MaxFocusStep]" value="<?php echo validHtmlStr($newControl['MaxFocusStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasFocusSpeed') ?></th><td><input type="checkbox" name="newControl[HasFocusSpeed]" value="1"<?php if ( !empty($newControl['HasFocusSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinFocusSpeed') ?></th><td><input type="number" name="newControl[MinFocusSpeed]" value="<?php echo validHtmlStr($newControl['MinFocusSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxFocusSpeed') ?></th><td><input type="number" name="newControl[MaxFocusSpeed]" value="<?php echo validHtmlStr($newControl['MaxFocusSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'iris' :
{
?>
<tr><th scope="row"><?php echo translate('CanIris') ?></th><td><input type="checkbox" name="newControl[CanIris]" value="1"<?php if ( !empty($newControl['CanIris']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th scope="row"><?php echo translate('CanAutoIris') ?></th><td><input type="checkbox" name="newControl[CanAutoIris]" value="1"<?php if ( !empty($newControl['CanAutoIris']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisAbs') ?></th><td><input type="checkbox" name="newControl[CanIrisAbs]" value="1"<?php if ( !empty($newControl['CanIrisAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisRel') ?></th><td><input type="checkbox" name="newControl[CanIrisRel]" value="1"<?php if ( !empty($newControl['CanIrisRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanIrisCon') ?></th><td><input type="checkbox" name="newControl[CanIrisCon]" value="1"<?php if ( !empty($newControl['CanIrisCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="number" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="number" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="number" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="number" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasIrisSpeed') ?></th><td><input type="checkbox" name="newControl[HasIrisSpeed]" value="1"<?php if ( !empty($newControl['HasIrisSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="number" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="number" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanIris') ?></th><td><input type="checkbox" name="newControl[CanIris]" value="1"<?php if ( !empty($newControl['CanIris']) ) { ?> checked="checked"<?php } ?>></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanAutoIris') ?></th><td><input type="checkbox" name="newControl[CanAutoIris]" value="1"<?php if ( !empty($newControl['CanAutoIris']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanIrisAbs') ?></th><td><input type="checkbox" name="newControl[CanIrisAbs]" value="1"<?php if ( !empty($newControl['CanIrisAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanIrisRel') ?></th><td><input type="checkbox" name="newControl[CanIrisRel]" value="1"<?php if ( !empty($newControl['CanIrisRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanIrisCon') ?></th><td><input type="checkbox" name="newControl[CanIrisCon]" value="1"<?php if ( !empty($newControl['CanIrisCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinIrisRange') ?></th><td><input type="number" name="newControl[MinIrisRange]" value="<?php echo validHtmlStr($newControl['MinIrisRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxIrisRange') ?></th><td><input type="number" name="newControl[MaxIrisRange]" value="<?php echo validHtmlStr($newControl['MaxIrisRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinIrisStep') ?></th><td><input type="number" name="newControl[MinIrisStep]" value="<?php echo validHtmlStr($newControl['MinIrisStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxIrisStep') ?></th><td><input type="number" name="newControl[MaxIrisStep]" value="<?php echo validHtmlStr($newControl['MaxIrisStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasIrisSpeed') ?></th><td><input type="checkbox" name="newControl[HasIrisSpeed]" value="1"<?php if ( !empty($newControl['HasIrisSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinIrisSpeed') ?></th><td><input type="number" name="newControl[MinIrisSpeed]" value="<?php echo validHtmlStr($newControl['MinIrisSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxIrisSpeed') ?></th><td><input type="number" name="newControl[MaxIrisSpeed]" value="<?php echo validHtmlStr($newControl['MaxIrisSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'gain' :
{
?>
<tr><th scope="row"><?php echo translate('CanGain') ?></th><td><input type="checkbox" name="newControl[CanGain]" value="1"<?php if ( !empty($newControl['CanGain']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanAutoGain') ?></th><td><input type="checkbox" name="newControl[CanAutoGain]" value="1"<?php if ( !empty($newControl['CanAutoGain']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainAbs') ?></th><td><input type="checkbox" name="newControl[CanGainAbs]" value="1"<?php if ( !empty($newControl['CanGainAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainRel') ?></th><td><input type="checkbox" name="newControl[CanGainRel]" value="1"<?php if ( !empty($newControl['CanGainRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanGainCon') ?></th><td><input type="checkbox" name="newControl[CanGainCon]" value="1"<?php if ( !empty($newControl['CanGainCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="number" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="number" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="number" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="number" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasGainSpeed') ?></th><td><input type="checkbox" name="newControl[HasGainSpeed]" value="1"<?php if ( !empty($newControl['HasGainSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="number" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="number" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanGain') ?></th><td><input type="checkbox" name="newControl[CanGain]" value="1"<?php if ( !empty($newControl['CanGain']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanAutoGain') ?></th><td><input type="checkbox" name="newControl[CanAutoGain]" value="1"<?php if ( !empty($newControl['CanAutoGain']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanGainAbs') ?></th><td><input type="checkbox" name="newControl[CanGainAbs]" value="1"<?php if ( !empty($newControl['CanGainAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanGainRel') ?></th><td><input type="checkbox" name="newControl[CanGainRel]" value="1"<?php if ( !empty($newControl['CanGainRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanGainCon') ?></th><td><input type="checkbox" name="newControl[CanGainCon]" value="1"<?php if ( !empty($newControl['CanGainCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinGainRange') ?></th><td><input type="number" name="newControl[MinGainRange]" value="<?php echo validHtmlStr($newControl['MinGainRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxGainRange') ?></th><td><input type="number" name="newControl[MaxGainRange]" value="<?php echo validHtmlStr($newControl['MaxGainRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinGainStep') ?></th><td><input type="number" name="newControl[MinGainStep]" value="<?php echo validHtmlStr($newControl['MinGainStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxGainStep') ?></th><td><input type="number" name="newControl[MaxGainStep]" value="<?php echo validHtmlStr($newControl['MaxGainStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasGainSpeed') ?></th><td><input type="checkbox" name="newControl[HasGainSpeed]" value="1"<?php if ( !empty($newControl['HasGainSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinGainSpeed') ?></th><td><input type="number" name="newControl[MinGainSpeed]" value="<?php echo validHtmlStr($newControl['MinGainSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxGainSpeed') ?></th><td><input type="number" name="newControl[MaxGainSpeed]" value="<?php echo validHtmlStr($newControl['MaxGainSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'white' :
{
?>
<tr><th scope="row"><?php echo translate('CanWhite') ?></th><td><input type="checkbox" name="newControl[CanWhite]" value="1"<?php if ( !empty($newControl['CanWhite']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanAutoWhite') ?></th><td><input type="checkbox" name="newControl[CanAutoWhite]" value="1"<?php if ( !empty($newControl['CanAutoWhite']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteAbs') ?></th><td><input type="checkbox" name="newControl[CanWhiteAbs]" value="1"<?php if ( !empty($newControl['CanWhiteAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteRel') ?></th><td><input type="checkbox" name="newControl[CanWhiteRel]" value="1"<?php if ( !empty($newControl['CanWhiteRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanWhiteCon') ?></th><td><input type="checkbox" name="newControl[CanWhiteCon]" value="1"<?php if ( !empty($newControl['CanWhiteCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="number" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="number" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="number" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="number" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasWhiteSpeed') ?></th><td><input type="checkbox" name="newControl[HasWhiteSpeed]" value="1"<?php if ( !empty($newControl['HasWhiteSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="number" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="number" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanWhite') ?></th><td><input type="checkbox" name="newControl[CanWhite]" value="1"<?php if ( !empty($newControl['CanWhite']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanAutoWhite') ?></th><td><input type="checkbox" name="newControl[CanAutoWhite]" value="1"<?php if ( !empty($newControl['CanAutoWhite']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanWhiteAbs') ?></th><td><input type="checkbox" name="newControl[CanWhiteAbs]" value="1"<?php if ( !empty($newControl['CanWhiteAbs']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanWhiteRel') ?></th><td><input type="checkbox" name="newControl[CanWhiteRel]" value="1"<?php if ( !empty($newControl['CanWhiteRel']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanWhiteCon') ?></th><td><input type="checkbox" name="newControl[CanWhiteCon]" value="1"<?php if ( !empty($newControl['CanWhiteCon']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinWhiteRange') ?></th><td><input type="number" name="newControl[MinWhiteRange]" value="<?php echo validHtmlStr($newControl['MinWhiteRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxWhiteRange') ?></th><td><input type="number" name="newControl[MaxWhiteRange]" value="<?php echo validHtmlStr($newControl['MaxWhiteRange']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinWhiteStep') ?></th><td><input type="number" name="newControl[MinWhiteStep]" value="<?php echo validHtmlStr($newControl['MinWhiteStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxWhiteStep') ?></th><td><input type="number" name="newControl[MaxWhiteStep]" value="<?php echo validHtmlStr($newControl['MaxWhiteStep']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasWhiteSpeed') ?></th><td><input type="checkbox" name="newControl[HasWhiteSpeed]" value="1"<?php if ( !empty($newControl['HasWhiteSpeed']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MinWhiteSpeed') ?></th><td><input type="number" name="newControl[MinWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MinWhiteSpeed']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('MaxWhiteSpeed') ?></th><td><input type="number" name="newControl[MaxWhiteSpeed]" value="<?php echo validHtmlStr($newControl['MaxWhiteSpeed']) ?>"/></td></tr>
<?php
break;
}
case 'presets' :
{
?>
<tr><th scope="row"><?php echo translate('HasPresets') ?></th><td><input type="checkbox" name="newControl[HasPresets]" value="1"<?php if ( !empty($newControl['HasPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('NumPresets') ?></th><td><input type="number" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/></td></tr>
<tr><th scope="row"><?php echo translate('HasHomePreset') ?></th><td><input type="checkbox" name="newControl[HasHomePreset]" value="1"<?php if ( !empty($newControl['HasHomePreset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th scope="row"><?php echo translate('CanSetPresets') ?></th><td><input type="checkbox" name="newControl[CanSetPresets]" value="1"<?php if ( !empty($newControl['CanSetPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasPresets') ?></th><td><input type="checkbox" name="newControl[HasPresets]" value="1"<?php if ( !empty($newControl['HasPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('NumPresets') ?></th><td><input type="number" name="newControl[NumPresets]" value="<?php echo validHtmlStr($newControl['NumPresets']) ?>"/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('HasHomePreset') ?></th><td><input type="checkbox" name="newControl[HasHomePreset]" value="1"<?php if ( !empty($newControl['HasHomePreset']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<tr><th class="text-right pr-3" scope="row"><?php echo translate('CanSetPresets') ?></th><td><input type="checkbox" name="newControl[CanSetPresets]" value="1"<?php if ( !empty($newControl['CanSetPresets']) ) { ?> checked="checked"<?php } ?>/></td></tr>
<?php
break;
}
@ -481,9 +488,11 @@ switch ( $tab ) {
</table>
<div id="contentButtons">
<button type="submit" value="Save"<?php if ( !canEdit( 'Control' ) ) { ?> disabled="disabled"<?php } ?>><?php echo translate('Save') ?></button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
<button type="button" id="cancelBtn"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
</div>
</div>
<?php xhtmlFooter() ?>

View File

@ -30,30 +30,47 @@ $focusWindow = true;
xhtmlHeaders(__FILE__, translate('ControlCaps'));
?>
<body>
<?php echo getNavBarHTML() ?>
<div id="page">
<div id="header">
<div id="headerButtons">
<a href="#" data-on-click="closeWindow"><?php echo translate('Close') ?></a>
</div>
<h2><?php echo translate('ControlCaps') ?></h2>
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
<div id="toolbar">
<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>
<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="addNewBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('AddNewControl') ?>" data-on-click-this="addNewControl" data-url="?view=controlcap"><i class="fa fa-plus"></i></button>
<button id="editBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('EditControl') ?>" data-on-click-this="editControl" data-url="?view=controlcap&cid=" disabled><i class="fa fa-pencil"></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>
</div>
<div id="content">
<form name="contentForm" id="contentForm" method="get" action="?" onsubmit="return( confirmDelete( 'Warning, deleting a control will reset all monitors that use it to be uncontrollable.\nAre you sure you wish to delete?' ) );">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="action" value="delete"/>
<table id="contentTable" class="major">
<table
id="controlTable"
class="table-sm table-borderless"
data-search="true"
data-cookie="true"
data-cookie-id-table="zmControlTable"
data-cookie-expire="2y"
data-remember-order="true"
data-click-to-select="true"
data-maintain-meta-data="true"
data-mobile-responsive="true"
data-buttons-class="btn btn-normal"
data-toolbar="#toolbar"
data-show-columns="true"
>
<thead>
<tr>
<th class="colName"><?php echo translate('Name') ?></th>
<th class="colType"><?php echo translate('Type') ?></th>
<th class="colProtocol"><?php echo translate('Protocol') ?></th>
<th class="colCanMove"><?php echo translate('CanMove') ?></th>
<th class="colCanZoom"><?php echo translate('CanZoom') ?></th>
<th class="colCanFocus"><?php echo translate('CanFocus') ?></th>
<th class="colCanIris"><?php echo translate('CanIris') ?></th>
<th class="colCanWhiteBal"><?php echo translate('CanWhiteBal') ?></th>
<th class="colHasPresets"><?php echo translate('HasPresets') ?></th>
<th class="colMark"><?php echo translate('Mark') ?></th>
<th data-sortable="false" data-field="toggleCheck" data-checkbox="true"></th>
<th class="colId" data-sortable="true" data-field="Id"><?php echo translate('Id') ?></th>
<th class="colName" data-sortable="true" data-field="Name"><?php echo translate('Name') ?></th>
<th class="colType" data-sortable="true" data-field="Type"><?php echo translate('Type') ?></th>
<th class="colProtocol" data-sortable="true" data-field="Protocol"><?php echo translate('Protocol') ?></th>
<th class="colCanMove" data-sortable="true" data-field="CanMove"><?php echo translate('CanMove') ?></th>
<th class="colCanZoom" data-sortable="true" data-field="CanZoom"><?php echo translate('CanZoom') ?></th>
<th class="colCanFocus" data-sortable="true" data-field="CanFocus"><?php echo translate('CanFocus') ?></th>
<th class="colCanIris" data-sortable="true" data-field="CanIris"><?php echo translate('CanIris') ?></th>
<th class="colCanWhiteBal" data-sortable="true" data-field="CanWhiteBal"><?php echo translate('CanWhiteBal') ?></th>
<th class="colHasPresets" data-sortable="true" data-field="HasPresets"><?php echo translate('HasPresets') ?></th>
</tr>
</thead>
<tbody>
@ -61,7 +78,9 @@ xhtmlHeaders(__FILE__, translate('ControlCaps'));
foreach( $controls as $control ) {
?>
<tr>
<td class="colName"><?php echo makePopupLink( '?view=controlcap&cid='.$control['Id'], 'zmControlCap', 'controlcap', validHtmlStr($control['Name']), canView( 'Control' ) ) ?></td>
<td class="colMark" data-checkbox="true"></td>
<td class="colId"><?php echo $control['Id'] ?></td>
<td class="colName"><?php echo $control['Name'] ?></td>
<td class="colType"><?php echo $control['Type'] ?></td>
<td class="colProtocol"><?php echo validHtmlStr($control['Protocol']) ?></td>
<td class="colCanMove"><?php echo $control['CanMove']?translate('Yes'):translate('No') ?></td>
@ -70,18 +89,12 @@ foreach( $controls as $control ) {
<td class="colCanIris"><?php echo $control['CanIris']?translate('Yes'):translate('No') ?></td>
<td class="colCanWhiteBal"><?php echo $control['CanWhite']?translate('Yes'):translate('No') ?></td>
<td class="colHasPresets"><?php echo $control['HasHomePreset']?'H':'' ?><?php echo $control['HasPresets']?$control['NumPresets']:'0' ?></td>
<td class="colMark"><input type="checkbox" name="markCids[]" value="<?php echo $control['Id'] ?>" data-on-click-this="configureDeleteButton"<?php if ( !canEdit( 'Control' ) ) {?> disabled="disabled"<?php } ?>/></td>
</tr>
<?php
}
?>
</tbody>
</table>
<div id="contentButtons">
<?php echo makePopupButton('?view=controlcap', 'zmControlCap', 'controlcap', translate('AddNewControl'), canEdit( 'Control' )); ?>
<input type="submit" name="deleteBtn" value="<?php echo translate('Delete') ?>" disabled="disabled"/>
</div>
</form>
</div>
</div>
<?php xhtmlFooter() ?>

View File

@ -147,15 +147,15 @@ xhtmlHeaders(__FILE__, translate('CycleWatch'));
<div id="sizeControl">
<span id="widthControl">
<label><?php echo translate('Width') ?>:</label>
<?php echo htmlSelect('width', $widths, $options['width'], array('data-on-change-this'=>'changeSize') ); ?>
<?php echo htmlSelect('width', $widths, $options['width'], array('id'=>'width', 'data-on-change-this'=>'changeSize') ); ?>
</span>
<span id="heightControl">
<label><?php echo translate('Height') ?>:</label>
<?php echo htmlSelect('height', $heights, $options['height'], array('data-on-change-this'=>'changeSize') ); ?>
<?php echo htmlSelect('height', $heights, $options['height'], array('id'=>'height', 'data-on-change-this'=>'changeSize') ); ?>
</span>
<span id="scaleControl">
<label><?php echo translate('Scale') ?>:</label>
<?php echo htmlSelect('scale', $scales, $options['scale'], array('data-on-change-this'=>'changeScale') ); ?>
<?php echo htmlSelect('scale', $scales, $options['scale'], array('id'=>'scale', 'data-on-change-this'=>'changeScale') ); ?>
</span>
</div>
</div>

View File

@ -54,15 +54,8 @@ if ( isset($_REQUEST['exportFormat']) ) {
}
}
if ( !empty($_REQUEST['eid']) ) {
$Event = new ZM\Event($_REQUEST['eid']);
if ( !$Event->Id ) {
Error('Invalid event id');
}
}
$focusWindow = true;
$connkey = isset($_REQUEST['connkey']) ? $_REQUEST['connkey'] : generateConnKey();
$connkey = isset($_REQUEST['connkey']) ? validInt($_REQUEST['connkey']) : generateConnKey();
xhtmlHeaders(__FILE__, translate('Download'));
?>
@ -75,7 +68,7 @@ xhtmlHeaders(__FILE__, translate('Download'));
<h2><?php echo translate('Download') ?></h2>
</div>
<div id="content">
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<form name="contentForm" id="contentForm" method="post" action="?">
<input type="hidden" name="connkey" value="<?php echo $connkey; ?>"/>
<?php
if ( !empty($_REQUEST['eid']) ) {
@ -83,7 +76,12 @@ if ( !empty($_REQUEST['eid']) ) {
<input type="hidden" name="id" value="<?php echo validInt($_REQUEST['eid']) ?>"/>
<?php
$Event = new ZM\Event($_REQUEST['eid']);
echo 'Downloading event ' . $Event->Id . '. Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() );
if ( !$Event->Id() ) {
ZM\Error('Invalid event id');
echo '<div class="error">Invalid event id</div>';
} else {
echo 'Downloading event ' . $Event->Id . '. Resulting file should be approximately ' . human_filesize( $Event->DiskSpace() );
}
} else if ( !empty($_REQUEST['eids']) ) {
$total_size = 0;
foreach ( $_REQUEST['eids'] as $eid ) {

View File

@ -23,6 +23,7 @@ $focusWindow = true;
xhtmlHeaders(__FILE__, translate('Error') );
?>
<body>
<?php echo getNavBarHTML() ?>
<div id="page">
<div id="header">
<h1>ZoneMinder <?php echo translate('Error') ?></h1>
@ -34,9 +35,6 @@ xhtmlHeaders(__FILE__, translate('Error') );
<p>
<?php echo translate('ContactAdmin') ?>
</p>
<p>
<button type="button" data-on-click="closeWindow"><?php echo translate('Close') ?></button>
</p>
</div>
</div>
</body>

View File

@ -42,7 +42,7 @@ if ( isset($_REQUEST['filter'])) {
parseSort();
$filterQuery = $filter->querystring();
ZM\Logger::Debug("Filter ".print_r($filter, true));
ZM\Logger::Debug('Filter '.print_r($filter, true));
if ( $filter->sql() ) {
$eventsSql .= ' AND ('.$filter->sql().')';
@ -50,7 +50,7 @@ if ( $filter->sql() ) {
ZM\Warning('No filters');
exit;
}
$eventsSql .= " ORDER BY $sortColumn $sortOrder";
$eventsSql .= ' ORDER BY '.$sortColumn.' '.$sortOrder;
if ( $sortColumn != 'E.Id' ) $eventsSql .= ',E.Id '.$sortOrder;
$page = isset($_REQUEST['page']) ? validInt($_REQUEST['page']) : 0;
@ -71,6 +71,10 @@ if ( $failed ) {
$results = $failed ? null : dbQuery($eventsSql);
$nEvents = $results ? $results->rowCount() : 0;
if ( ! $results ) {
global $error_message;
$error_message = dbError($eventsSql);
}
ZM\Logger::Debug("Pre conditions succeeded sql return $nEvents events");
if ( !empty($limit) && ($nEvents > $limit) ) {
@ -91,13 +95,12 @@ if ( !empty($page) ) {
$limitLeft = $limit - $limitStart;
$limitAmount = ($limitLeft>ZM_WEB_EVENTS_PER_PAGE)?ZM_WEB_EVENTS_PER_PAGE:$limitLeft;
}
$eventsSql .= " LIMIT $limitStart, $limitAmount";
$eventsSql .= ' LIMIT '.$limitStart.', '.$limitAmount;
} else if ( !empty($limit) ) {
$eventsSql .= ' LIMIT 0, '.$limit;
}
$maxShortcuts = 5;
$pagination = getPagination($pages, $page, $maxShortcuts, $filter->querystring().$sortQuery.$limitQuery);
$focusWindow = true;
@ -108,9 +111,9 @@ foreach ( $storage_areas as $S ) {
}
xhtmlHeaders(__FILE__, translate('Events'));
getBodyTopHTML();
?>
<body>
<?php echo getNavBarHTML() ?>
<div id="page" class="container-fluid p-3">
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
@ -131,7 +134,6 @@ xhtmlHeaders(__FILE__, translate('Events'));
<div class="row justify-content-center">
<table
id="eventTable"
data-toggle="table"
data-pagination="true"
data-show-pagination-switch="true"
data-page-list="[10, 25, 50, 100, 200, All]"
@ -229,7 +231,7 @@ if ( $results ) {
<td class="text-center"><?php echo ( $event->Archived() ) ? 'Yes' : 'No' ?></td>
<td class="text-center"><?php echo ( $event->Emailed() ) ? 'Yes' : 'No' ?></td>
<td><?php echo makePopupLink( '?view=monitor&amp;mid='.$event->MonitorId(), 'zmMonitor'.$event->MonitorId(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
<td><?php echo makeLink( '?view=monitor&amp;mid='.$event->MonitorId(), $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
<td><?php echo makeLink( '#', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid=' .$event->Id(). '"') ?>
<?php
# display notes as small text
@ -237,9 +239,7 @@ if ( $results ) {
# if notes include detection objects, then link it to objdetect.jpg
if ( strpos($event->Notes(), 'detected:') !== false ) {
# make a link
echo makePopupLink( '?view=image&amp;eid='.$event->Id().'&amp;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>');
echo makeLink( '?view=image&amp;eid='.$event->Id().'&amp;fid=objdetect', '<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>';
}
@ -254,10 +254,7 @@ if ( $results ) {
<td><a href="?view=frames&amp;eid=<?php echo $event->Id() ?>"><?php echo $event->AlarmFrames() ?></a></td>
<td><?php echo $event->TotScore() ?></td>
<td><?php echo $event->AvgScore() ?></td>
<td><?php echo makePopupLink(
'?view=frame&amp;eid='.$event->Id().'&amp;fid=0', 'zmImage',
array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)), $event->MaxScore()
); ?></td>
<td><?php echo makeLink('?view=frame&amp;eid='.$event->Id().'&amp;fid=0', $event->MaxScore()); ?></td>
<?php
if ( count($storage_areas) > 1 ) {
?>

View File

@ -56,17 +56,22 @@ if (isset($_REQUEST['exportFormat'])) {
}
$focusWindow = true;
$connkey = isset($_REQUEST['connkey']) ? $_REQUEST['connkey'] : generateConnKey();
$connkey = isset($_REQUEST['connkey']) ? validInt($_REQUEST['connkey']) : generateConnKey();
xhtmlHeaders(__FILE__, translate('Export'));
?>
<body>
<div id="page">
<?php echo getNavBarHTML() ?>
<div id="header">
<h2><?php echo translate('ExportOptions') ?></h2>
</div>
<div id="content">
<div class="w-100 py-1">
<div class="float-left pl-3">
<button type="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>
<button type="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>
</div>
<div class="w-100 pt-2">
<h2><?php echo translate('ExportOptions') ?></h2>
</div>
</div> <div id="content">
<form name="contentForm" id="contentForm" method="post" action="?view=export">
<input type="hidden" name="connkey" value="<?php echo $connkey; ?>"/>
<?php
@ -145,19 +150,17 @@ while ( $event_row = dbFetchNext($results) ) {
<a href="?view=event&amp;eid=<?php echo $event->Id().$filterQuery.$sortQuery ?>&amp;page=1"><?php echo $event->Id().($event->Archived()?'*':'') ?></a>
</td>
<td class="colName"><a href="?view=event&amp;eid=<?php echo $event->Id().$filterQuery.$sortQuery ?>&amp;page=1"><?php echo validHtmlStr($event->Name()).($event->Archived()?'*':'') ?></a></td>
<td class="colMonitorName"><?php echo makePopupLink( '?view=monitor&amp;mid='.$event->MonitorId(), 'zmMonitor'.$event->MonitorId(), 'monitor', $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
<td class="colMonitorName"><?php echo makeLink( '?view=monitor&amp;mid='.$event->MonitorId(), $event->MonitorName(), canEdit( 'Monitors' ) ) ?></td>
<td class="colCause"><?php echo makeLink( '#', validHtmlStr($event->Cause()), canEdit( 'Events' ), 'title="' .htmlspecialchars($event->Notes()). '" class="eDetailLink" data-eid=' .$event->Id(). '"') ?></td>
<td class="colTime"><?php echo strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->StartTime())) .
( $event->EndTime() ? ' until ' . strftime(STRF_FMT_DATETIME_SHORTER, strtotime($event->EndTime()) ) : '' ) ?>
</td>
<td class="colDuration"><?php echo gmdate("H:i:s", $event->Length() ) ?></td>
<td class="colFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames', 'frames', $event->Frames() ) ?></td>
<td class="colAlarmFrames"><?php echo makePopupLink( '?view=frames&amp;eid='.$event->Id(), 'zmFrames', 'frames', $event->AlarmFrames() ) ?></td>
<td class="colFrames"><?php echo makeLink( '?view=frames&amp;eid='.$event->Id(), $event->Frames() ) ?></td>
<td class="colAlarmFrames"><?php echo makeLink( '?view=frames&amp;eid='.$event->Id(), $event->AlarmFrames() ) ?></td>
<td class="colTotScore"><?php echo $event->TotScore() ?></td>
<td class="colAvgScore"><?php echo $event->AvgScore() ?></td>
<td class="colMaxScore"><?php echo
$event->MaxScore();
#makePopupLink('?view=frame&amp;eid='.$event->Id().'&amp;fid=0', 'zmImage', array('image', reScale($event->Width(), $scale), reScale($event->Height(), $scale)), $event->MaxScore()) ?></td>
<td class="colMaxScore"><?php echo $event->MaxScore() ?></td>
<?php
if ( ZM_WEB_EVENT_DISK_SPACE ) {
$disk_space_total += $event->DiskSpace();

View File

@ -80,6 +80,7 @@ $attrTypes = array(
'DiskBlocks' => translate('AttrDiskBlocks'),
'DiskPercent' => translate('AttrDiskPercent'),
'DiskSpace' => translate('AttrDiskSpace'),
'EventDiskSpace' => translate('AttrEventDiskSpace'),
'EndDateTime' => translate('AttrEndDateTime'),
'EndDate' => translate('AttrEndDate'),
'EndTime' => translate('AttrEndTime'),
@ -489,6 +490,7 @@ if ( canEdit('Events') ) {
}
}
?>
<button type="button" value="Debug" data-on-click-this="debugFilter"><?php echo translate('Debug') ?></button>
<button type="button" value="Reset" data-on-click-this="resetFilter"><?php echo translate('Reset') ?></button>
</div>
</form>

View File

@ -125,7 +125,6 @@ xhtmlHeaders(__FILE__, translate('Frames').' - '.$Event->Id());
<div class="row justify-content-center">
<table
id="framesTable"
data-toggle="table"
data-pagination="true"
data-show-pagination-switch="true"
data-page-list="[10, 25, 50, 100, 200, All]"

View File

@ -1,130 +0,0 @@
<?php
//
// ZoneMinder web group detail 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 ( !canEdit('Groups') ) {
$view = 'error';
return;
}
if ( !empty($_REQUEST['gid']) ) {
$newGroup = new ZM\Group($_REQUEST['gid']);
} else {
$newGroup = new ZM\Group();
}
xhtmlHeaders(__FILE__, translate('Group').' - '.$newGroup->Name());
?>
<body>
<div id="page">
<div id="header">
<h2><?php echo translate('Group') ?> - <?php echo validHtmlStr($newGroup->Name()); ?></h2>
</div>
<div id="content">
<form id="groupForm" name="groupForm" method="post" action="?">
<input type="hidden" name="view" value="<?php echo $view ?>"/>
<input type="hidden" name="gid" value="<?php echo $newGroup->Id() ?>"/>
<table id="contentTable" class="major">
<tbody>
<tr>
<th scope="row"><?php echo translate('Name') ?></th>
<td><input type="text" name="newGroup[Name]" value="<?php echo validHtmlStr($newGroup->Name()) ?>" data-on-input="configureButtons"/></td>
</tr>
<tr>
<th scope="row"><?php echo translate('ParentGroup') ?></th>
<td>
<?php
$Groups = array();
foreach ( ZM\Group::find() as $Group ) {
$Groups[$Group->Id()] = $Group;
}
# This array is indexed by parent_id
$children = array();
foreach ( $Groups as $id=>$Group ) {
if ( $Group->ParentId() != null ) {
if ( ! isset( $children[$Group->ParentId()] ) )
$children[$Group->ParentId()] = array();
$children[$Group->ParentId()][] = $Group;
}
}
function get_Id( $G ) {
return $G->Id();
}
function get_children($Group) {
global $children;
$kids = array();
if ( isset( $children[$Group->Id()] ) ) {
$kids += array_map('get_Id', $children[$Group->Id()]);
foreach ( $children[$Group->Id()] as $G ) {
foreach ( get_children($G) as $id ) {
$kids[] = $id;
}
}
}
return $kids;
}
$kids = get_children($newGroup);
if ( $newGroup->Id() )
$kids[] = $newGroup->Id();
$sql = 'SELECT Id,Name FROM `Groups`'.(count($kids)?' WHERE Id NOT IN ('.implode(',',array_map(function(){return '?';}, $kids)).')' : '').' ORDER BY Name';
$options = array(''=>'None');
foreach ( dbFetchAll($sql, null, $kids) as $option ) {
$options[$option['Id']] = str_repeat('&nbsp;&nbsp;', $Groups[$option['Id']]->depth()) . $option['Name'];
}
echo htmlSelect('newGroup[ParentId]', $options, $newGroup->ParentId(), array('data-on-change'=>'configureButtons'));
?>
</td>
</tr>
<tr>
<th scope="row"><?php echo translate('Monitor') ?></th>
<td>
<select name="newGroup[MonitorIds][]" class="chosen" multiple="multiple" data-on-change="configureButtons">
<?php
$monitors = dbFetchAll('SELECT Id,Name FROM Monitors ORDER BY Sequence ASC');
$monitorIds = $newGroup->MonitorIds();
foreach ( $monitors as $monitor ) {
if ( visibleMonitor($monitor['Id']) ) {
?>
<option value="<?php echo $monitor['Id'] ?>"<?php if ( in_array( $monitor['Id'], $monitorIds ) ) { ?> selected="selected"<?php } ?>><?php echo validHtmlStr($monitor['Name']) ?></option>
<?php
}
}
?>
</select>
</td>
</tr>
</tbody>
</table>
<div id="contentButtons">
<button type="submit" name="action" value="Save"<?php $newGroup->Id() ? '' : ' disabled="disabled"'?>>
<?php echo translate('Save') ?>
</button>
<button type="button" data-on-click="closeWindow"><?php echo translate('Cancel') ?></button>
</div>
</form>
</div>
</div>
<script nonce="<?php echo $cspNonce;?>">$j('.chosen').chosen();</script>
<?php xhtmlFooter() ?>

View File

@ -127,27 +127,8 @@ function reloadWindow() {
window.location.replace( thisUrl );
}
function initPage() {
reloadWindow.periodical(consoleRefreshTimeout);
if ( showVersionPopup ) {
window.location.assign('?view=version');
}
if ( showDonatePopup ) {
$j('#donate').modal('show');
}
// Makes table sortable
$j( function() {
$j( "#consoleTableBody" ).sortable({
handle: ".sort",
update: applySort,
axis: 'Y'} );
$j( "#consoleTableBody" ).disableSelection();
} );
// Setup the thumbnail video animation
initThumbAnimation();
// Manage the the Function modal and its buttons
function manageFunctionModal() {
$j('.functionLnk').click(function(evt) {
evt.preventDefault();
if ( !canEditEvents ) {
@ -173,6 +154,7 @@ function initPage() {
$j('#modalFunction').modal('show');
});
// Manage the CANCEL modal buttons
$j('.funcCancelBtn').click(function(evt) {
evt.preventDefault();
@ -182,19 +164,59 @@ function initPage() {
// Manage the SAVE modal buttons
$j('.funcSaveBtn').click(function(evt) {
evt.preventDefault();
var form = evt.currentTarget.form;
var mid = form.elements['mid'].value;
var newFunc = $j('#newFunction').val();
var newEnabled = $j('#newEnabled').is(':checked') ? 1 : 0;
$j.getJSON(thisUrl + '?view=function&action=function&mid='+mid+'&newFunction='+newFunc+'&newEnabled='+newEnabled)
.done(window.location.reload(true))
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
$j('#function_form').submit();
});
}
function initPage() {
reloadWindow.periodical(consoleRefreshTimeout);
if ( showVersionPopup ) {
window.location.assign('?view=version');
}
if ( showDonatePopup ) {
$j.getJSON(thisUrl + '?request=modal&modal=donate')
.done(function(data) {
if ( $j('#donate').length ) {
$j('#donate').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#donate').modal('show');
// Manage the Apply button
$j('#donateApplyBtn').click(function(evt) {
evt.preventDefault();
$j('#donateForm').submit();
});
})
.fail(logAjaxFail);
}
// Makes table sortable
$j( function() {
$j( "#consoleTableBody" ).sortable({
handle: ".sort",
update: applySort,
axis: 'Y'} );
$j( "#consoleTableBody" ).disableSelection();
} );
// Setup the thumbnail video animation
initThumbAnimation();
// Load the Function modal on page load
$j.getJSON(thisUrl + '?request=modal&modal=function')
.done(function(data) {
if ( $j('#modalFunction').length ) {
$j('#modalFunction').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
// Manage the Function modal
manageFunctionModal();
})
.fail(logAjaxFail);
}
function applySort(event, ui) {
var monitor_ids = $j(this).sortable('toArray');
var ajax = new Request.JSON( {

View File

@ -108,3 +108,29 @@ function validateForm( form ) {
return true;
}
function initPage() {
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Disable the back button if there is nothing to go back to
$j('#backBtn').prop('disabled', !document.referrer.length);
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
// Manage the CANCEL Button
document.getElementById("cancelBtn").addEventListener("click", function onCancelClick(evt) {
evt.preventDefault();
window.location.assign('?view=controlcaps');
});
}
$j(document).ready(function() {
initPage();
});

View File

@ -0,0 +1,119 @@
var table = $j('#controlTable');
var addNewBtn = $j('#addNewBtn');
var editBtn = $j('#editBtn');
var deleteBtn = $j('#deleteBtn');
// Manage the Add New Control button
function AddNewControl(el) {
url = el.getAttribute('data-url');
window.location.assign(url);
}
// Manage the Add New Control button
function addNewControl(el) {
url = el.getAttribute('data-url');
window.location.assign(url);
}
// Manage the Edit Control button
function editControl(el) {
var selection = getIdSelections();
url = el.getAttribute('data-url');
window.location.assign(url+selection);
}
// Returns the event id's of the selected rows
function getIdSelections() {
return $j.map(table.bootstrapTable('getSelections'), function(row) {
return row.Id.replace(/(<([^>]+)>)/gi, ''); // strip the html from the element before sending
});
}
// Load the Delete Confirmation Modal HTML via Ajax call
function getDelConfirmModal(key) {
$j.getJSON(thisUrl + '?request=modal&modal=delconfirm&key=' + key)
.done(function(data) {
if ( $j('#deleteConfirm').length ) {
$j('#deleteConfirm').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
manageDelConfirmModalBtns();
})
.fail(logAjaxFail);
}
// Manage the DELETE CONFIRMATION modal button
function manageDelConfirmModalBtns() {
document.getElementById("delConfirmBtn").addEventListener("click", function onDelConfirmClick(evt) {
if ( ! canEditControl ) {
enoperm();
return;
}
var selections = getIdSelections();
evt.preventDefault();
$j.getJSON(thisUrl + '?request=controlcaps&action=delete&cids[]='+selections.join('&cids[]='))
.done( function(data) {
$j('#eventTable').bootstrapTable('refresh');
window.location.reload(true);
})
.fail(logAjaxFail);
});
}
function initPage() {
// enable or disable buttons based on current selection and user rights
table.on('check.bs.table uncheck.bs.table ' +
'check-all.bs.table uncheck-all.bs.table',
function() {
selections = table.bootstrapTable('getSelections');
addNewBtn.prop('disabled', (selections.length || !canEditControl));
editBtn.prop('disabled', !((selections.length == 1) && canEditControl));
deleteBtn.prop('disabled', !(selections.length && canEditControl));
});
// Init the bootstrap-table
table.bootstrapTable({icons: icons});
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Disable the back button if there is nothing to go back to
$j('#backBtn').prop('disabled', !document.referrer.length);
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
// Manage the DELETE button
document.getElementById("deleteBtn").addEventListener("click", function onDeleteClick(evt) {
if ( ! canEditControl ) {
enoperm();
return;
}
evt.preventDefault();
$j('#deleteConfirm').modal('show');
});
// Load the delete confirmation modal into the DOM
getDelConfirmModal('ConfirmDeleteControl');
// Hide these columns on first run when no cookie is saved
if ( !getCookie("zmControlTable.bs.table.columns") ) {
table.bootstrapTable('hideColumn', 'Id');
}
}
$j(document).ready(function() {
initPage();
});

View File

@ -0,0 +1 @@
var canEditControl = <?php echo canEdit('Control')?'true':'false' ?>;

View File

@ -1,3 +0,0 @@
if ( action == 'donate' && option == 'go' ) {
zmWindow('/donate/');
}

View File

@ -1,2 +0,0 @@
var action = '<?php echo isset($_REQUEST['action'])?validJsStr($_REQUEST['action']):'' ?>';
var option = '<?php echo isset($_REQUEST['option'])?validJsStr($_REQUEST['option']):'' ?>';

View File

@ -50,10 +50,7 @@ var cueFrames = null; //make cueFrames available even if we don't send another a
function initialAlarmCues(eventId) {
$j.getJSON(thisUrl + '?view=request&request=status&entity=frames&id=' + eventId, setAlarmCues) //get frames data for alarmCues and inserts into html
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
}
function setAlarmCues(data) {
@ -953,12 +950,27 @@ function renameEvent() {
actQuery('rename', {eventName: newName});
}
// Manage the EDIT button
function editEvent() {
createPopup('?view=eventdetail&eid='+eventData.Id, 'zmEventDetail', 'eventdetail');
$j.getJSON(thisUrl + '?request=modal&modal=eventdetail&eid='+eventData.Id)
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(logAjaxFail);
}
function exportEvent() {
createPopup('?view=export&eid='+eventData.Id, 'zmExport', 'export');
window.location.assign('?view=export&eid='+eventData.Id);
}
function archiveEvent() {
@ -970,7 +982,7 @@ function unarchiveEvent() {
}
function showEventFrames() {
createPopup('?view=frames&eid='+eventData.Id, 'zmFrames', 'frames', WEB_LIST_THUMB_WIDTH, WEB_LIST_THUMB_HEIGHT);
window.location.assign('?view=frames&eid='+eventData.Id);
}
function showStream() {
@ -1018,7 +1030,7 @@ function showStills() {
function showFrameStats() {
var fid = $('eventImageNo').get('text');
createPopup('?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height);
window.location.assign('?view=stats&eid='+eventData.Id+'&fid='+fid);
}
function videoEvent() {

View File

@ -46,14 +46,11 @@ function getDelConfirmModal() {
}
manageDelConfirmModalBtns();
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
}
// Manage the DELETE CONFIRMATION modal button
function manageDelConfirmModalBtns() {
// Manage the DELETE CONFIRMATION modal button
document.getElementById("delConfirmBtn").addEventListener("click", function onDelConfirmClick(evt) {
if ( ! canEditEvents ) {
enoperm();
@ -66,11 +63,9 @@ function manageDelConfirmModalBtns() {
$j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]='))
.done( function(data) {
$j('#eventTable').bootstrapTable('refresh');
window.location.reload(true);
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
});
// Manage the CANCEL modal button
@ -81,23 +76,20 @@ function manageDelConfirmModalBtns() {
function getEventDetailModal(eid) {
$j.getJSON(thisUrl + '?request=modal&modal=eventdetail&eids[]=' + eid)
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(logAjaxFail);
}
function initPage() {
@ -114,22 +106,8 @@ function initPage() {
// Load the delete confirmation modal into the DOM
getDelConfirmModal();
// Define the icons used in the bootstrap-table top-right toolbar
var icons = {
paginationSwitchDown: 'fa-caret-square-o-down',
paginationSwitchUp: 'fa-caret-square-o-up',
export: 'fa-download',
refresh: 'fa-sync',
toggleOff: 'fa-toggle-off',
toggleOn: 'fa-toggle-on',
columns: 'fa-th-list',
fullscreen: 'fa-arrows-alt',
detailOpen: 'fa-plus',
detailClose: 'fa-minus'
};
// Init the bootstrap-table
table.bootstrapTable('destroy').bootstrapTable({icons: icons});
table.bootstrapTable({icons: icons});
// Hide these columns on first run when no cookie is saved
if ( !getCookie("zmEventsTable.bs.table.columns") ) {
@ -198,10 +176,7 @@ function initPage() {
$j('#eventTable').bootstrapTable('refresh');
window.location.reload(true);
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
});
// Manage the UNARCHIVE button
@ -220,18 +195,9 @@ function initPage() {
$j('#eventTable').bootstrapTable('refresh');
window.location.reload(true);
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
if ( openFilterWindow ) {
//opener.location.reload(true);
createPopup( '?view=filter&page='+thisPage+filterQuery, 'zmFilter', 'filter' );
location.replace( '?view='+currentView+'&page='+thisPage+filterQuery );
} else {
window.location.reload(true);
}
window.location.reload(true);
});
// Manage the EDIT button
@ -245,23 +211,20 @@ function initPage() {
evt.preventDefault();
$j.getJSON(thisUrl + '?request=modal&modal=eventdetail&eids[]='+selections.join('&eids[]='))
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(logAjaxFail);
});
// Manage the EXPORT button

View File

@ -2,8 +2,6 @@
global $filterQuery;
global $sortQuery;
?>
//var openFilterWindow = <?php echo $_REQUEST['filter']?'true':'false' ?>;
var openFilterWindow = false;
var filterQuery = '<?php echo isset($filterQuery)?validJsStr(htmlspecialchars_decode($filterQuery)):'' ?>';
var sortQuery = '<?php echo isset($sortQuery)?validJsStr(htmlspecialchars_decode($sortQuery)):'' ?>';

View File

@ -82,23 +82,20 @@ function exportEvents( ) {
function getEventDetailModal(eid) {
$j.getJSON(thisUrl + '?request=modal&modal=eventdetail&eids[]=' + eid)
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.done(function(data) {
if ( $j('#eventDetailModal').length ) {
$j('#eventDetailModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#eventDetailModal').modal('show');
// Manage the Save button
$j('#eventDetailSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#eventDetailForm').submit();
});
})
.fail(logAjaxFail);
}
function initPage() {
@ -107,12 +104,28 @@ function initPage() {
startDownload.pass(exportFile).delay(1500);
}
document.getElementById('exportButton').addEventListener('click', exportEvents);
// Manage the eventdetail link in the export list
$j(".eDetailLink").click(function(evt) {
evt.preventDefault();
var eid = $j(this).data('eid');
getEventDetailModal(eid);
});
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Don't enable the back button if there is no previous zm page to go back to
$j('#backBtn').prop('disabled', !document.referrer.length);
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
}
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -39,12 +39,19 @@ function validateForm(form) {
} else if ( form.elements['filter[UpdateDiskSpace]'].checked ) {
var have_endtime_term = false;
for ( var i = 0; i < rows.length; i++ ) {
if ( form.elements['filter[Query][terms][' + i + '][attr]'].value == 'EndDateTime' ) {
if (
( form.elements['filter[Query][terms][' + i + '][attr]'].value == 'EndDateTime' )
||
( form.elements['filter[Query][terms][' + i + '][attr]'].value == 'EndTime' )
||
( form.elements['filter[Query][terms][' + i + '][attr]'].value == 'EndDate' )
) {
have_endtime_term = true;
break;
}
}
if ( ! have_endtime_term ) {
return confirm('You don\'t have an EndTime term in your filter. This might match recordings that are still in progress and so the UpdateDiskSpace action will be a waste of time and resources. Ideally you should have an EndTime IS NOT NULL term. Do you want to continue?');
return confirm('You don\'t have an End Date/Time term in your filter. This might match recordings that are still in progress and so the UpdateDiskSpace action will be a waste of time and resources. Ideally you should have an End Date/Time IS NOT NULL term. Do you want to continue?');
}
} else if ( form.elements['filter[Background]'].checked ) {
if ( ! (
@ -388,6 +395,47 @@ function delTerm( element ) {
parseRows(rows);
}
function debugFilter() {
getModal('filterdebug');
}
// Load the Delete Confirmation Modal HTML via Ajax call
function getModal(id) {
$j.getJSON(thisUrl + '?request=modal&modal='+id+'&fid='+filterid)
.done(function(data) {
if ( !data ) {
console.error("Get modal returned no data");
return;
}
if ( $j('#'+id).length ) {
console.log("replacing");
$j('#'+id).replaceWith(data.html);
} else {
console.log("Adding to body"+data.html);
$j('body').append(data.html);
}
manageModalBtns(id);
modal = $j('#'+id+'Modal');
if ( ! modal.length ) {
console.log("No modal found");
}
$j('#'+id+'Modal').modal('show');
})
.fail(logAjaxFail);
}
function manageModalBtns(id) {
console.log(id);
// Manage the CANCEL modal button
var cancelBtn = document.getElementById(id+"CancelBtn");
if ( cancelBtn ) {
document.getElementById(id+"CancelBtn").addEventListener("click", function onCancelClick(evt) {
$j('#'+id).modal('hide');
});
}
}
function init() {
updateButtons( $('executeButton') );
$j('#Id').chosen();

View File

@ -11,7 +11,9 @@
global $monitors;
global $zones;
global $booleanValues;
global $filter;
?>
var filterid = '<?php echo $filter->Id() ?>';
var filterQuery = '<?php echo isset($filterQuery) ? validJsStr(htmlspecialchars_decode($filterQuery)) : '' ?>';
var sortQuery = '<?php echo isset($sortQuery) ? validJsStr(htmlspecialchars_decode($sortQuery)) : '' ?>';

View File

@ -37,7 +37,7 @@ if ( !scale ) {
}
document.addEventListener('DOMContentLoaded', function onDCL() {
document.getElementById('scale').addEventListener('change', changeScale);
document.getElementById('scaleControl').addEventListener('change', changeScale);
});
function initPage() {

View File

@ -32,31 +32,14 @@ function detailFormatter(index, row, $detail) {
.done(function(data) {
$detail.html(data.html);
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
}
function initPage() {
var backBtn = $j('#backBtn');
var table = $j('#framesTable');
// Define the icons used in the bootstrap-table top-right toolbar
var icons = {
paginationSwitchDown: 'fa-caret-square-o-down',
paginationSwitchUp: 'fa-caret-square-o-up',
export: 'fa-download',
refresh: 'fa-sync',
toggleOff: 'fa-toggle-off',
toggleOn: 'fa-toggle-on',
columns: 'fa-th-list',
fullscreen: 'fa-arrows-alt',
detailOpen: 'fa-plus',
detailClose: 'fa-minus'
};
// Init the bootstrap-table
table.bootstrapTable('destroy').bootstrapTable({icons: icons});
table.bootstrapTable({icons: icons});
// Hide these columns on first run when no cookie is saved
if ( !getCookie("zmFramesTable.bs.table.columns") ) {

View File

@ -1,20 +0,0 @@
function configureButtons() {
var form = $j('#groupForm')[0];
if ( !form ) {
console.log("No groupForm found");
return;
}
if ( !canEditGroups ) {
console.log("Cannot edit groups");
form.elements['action'].disabled = disabled;
return;
}
var disabled = false;
if ( form.elements['newGroup[Name]'].value == '' ) {
disabled = true;
}
form.elements['action'].disabled = disabled;
}
window.focus();

View File

@ -1,5 +1,22 @@
// Manage the NEW Group button
function newGroup() {
createPopup( '?view=group', 'zmGroup', 'group' );
$j.getJSON(thisUrl + '?request=modal&modal=group')
.done(function(data) {
if ( $j('#groupModal').length ) {
$j('#groupModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#groupModal').modal('show');
$j('.chosen').chosen("destroy");
$j('.chosen').chosen();
// Manage the Save button
$j('#grpModalSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#groupForm').submit();
});
})
.fail(logAjaxFail);
}
function setGroup( element ) {
@ -13,7 +30,23 @@ function editGroup( element ) {
if ( !gid ) {
console.log('No group id found in editGroup');
} else {
createPopup('?view=group&gid='+gid, 'zmGroup'+gid, 'group');
$j.getJSON(thisUrl + '?request=modal&modal=group&gid=' + gid)
.done(function(data) {
if ( $j('#groupModal').length ) {
$j('#groupModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#groupModal').modal('show');
$j('.chosen').chosen("destroy");
$j('.chosen').chosen();
// Manage the Save button
$j('#grpModalSaveBtn').click(function(evt) {
evt.preventDefault();
$j('#groupForm').submit();
});
})
.fail(logAjaxFail);
}
}
@ -33,4 +66,21 @@ function configureButtons( element ) {
}
}
window.focus();
function configModalBtns() {
var form = $j('#groupForm')[0];
if ( !form ) {
console.log("No groupForm found");
return;
}
if ( !canEditGroups ) {
console.log("Cannot edit groups");
form.elements['action'].disabled = disabled;
return;
}
var disabled = false;
if ( form.elements['newGroup[Name]'].value == '' ) {
disabled = true;
}
form.elements['action'].disabled = disabled;
}

View File

@ -210,22 +210,31 @@ function resetLog() {
refreshLog();
}
var exportFormValidator;
var exportFormValidator = null;
function exportLog() {
exportFormValidator.reset();
$('exportLog').overlayShow();
getModal('log_export');
if ( !exportFormValidator ) {
exportFormValidator = new Form.Validator.Inline($('exportForm'), {
useTitles: true,
warningPrefix: '',
errorPrefix: ''
});
} else {
exportFormValidator.reset();
}
}
function exportResponse( response ) {
$('exportLog').unspin();
$('log_exportModal').unspin();
if ( response.result == 'Ok' ) {
window.location.replace( thisUrl+'?view=request&request=log&task=download&key='+response.key+'&format='+response.format );
}
}
function exportFail( request ) {
$('exportLog').unspin();
$('log_exportModal').unspin();
$('exportErrorText').set('text', request.status+' / '+request.statusText);
$('exportError').show();
Error('Export request failed: '+request.status+' / '+request.statusText);
@ -233,12 +242,18 @@ function exportFail( request ) {
function exportRequest() {
var form = $('exportForm');
console.log(form);
$('exportErrorText').set('text', '');
$('exportError').hide();
if ( form.validate() ) {
var exportParms = "view=request&request=log&task=export";
var exportReq = new Request.JSON({url: thisUrl, method: 'post', link: 'cancel', onSuccess: exportResponse, onFailure: exportFail});
var selection = form.getElement('input[name=selector]:checked').get('value');
var selector = form.querySelectorAll('input[name=selector]:checked');
if ( !selector.length ) {
alert("Please select how to filter logs");
return;
}
var selection = selector[0].get('value');
if ( selection == 'filter' || selection == 'current' ) {
$$('#filters select').each(
function( select ) {
@ -257,7 +272,7 @@ function exportRequest() {
}
}
exportReq.send(exportParms+"&"+form.toQueryString());
$('exportLog').spin();
$('log_exportModal').spin();
}
}
@ -294,6 +309,8 @@ function updateFilterSelectors() {
if ( filter[key] ) {
selector.set('value', filter[key]);
}
$j(selector).chosen('destroy');
$j(selector).chosen();
}
);
}
@ -331,11 +348,6 @@ function initPage() {
} // end if loCount > displayLimit
}
);
exportFormValidator = new Form.Validator.Inline($('exportForm'), {
useTitles: true,
warningPrefix: '',
errorPrefix: ''
});
new Asset.css('css/spinner.css');
fetchNextLogs();
}

View File

@ -137,6 +137,16 @@ function initPage() {
document.querySelectorAll('input[name="newMonitor[WebColour]"]').forEach(function(el) {
el.onchange = window['change_WebColour'].bind(el);
});
document.querySelectorAll('select[name="newMonitor[Type]"]').forEach(function(el) {
el.onchange = function() {
var form = document.getElementById('contentForm');
form.tab.value = 'general';
form.submit();
};
});
document.querySelectorAll('input[name="newMonitor[ImageBufferCount]"],input[name="newMonitor[Width]"],input[name="newMonitor[Height]"]').forEach(function(el) {
el.oninput = window['update_estimated_ram_use'].bind(el);
});
$j('.chosen').chosen();
@ -219,4 +229,17 @@ function random_WebColour() {
);
}
function update_estimated_ram_use() {
var buffer_count = document.querySelectorAll('input[name="newMonitor[ImageBufferCount]"]')[0].value;
console.log(buffer_count);
var width = document.querySelectorAll('input[name="newMonitor[Width]"]')[0].value;
console.log(width);
var height = document.querySelectorAll('input[name="newMonitor[Height]"]')[0].value;
console.log(height);
var colours = document.querySelectorAll('select[name="newMonitor[Colours]"]')[0].value;
console.log(colours);
document.getElementById('estimated_ram_use').innerHTML = human_filesize(buffer_count * width * height * colours, 0);
}
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -0,0 +1,105 @@
var table = $j('#logTable');
/*
This is the format of the json object sent by bootstrap-table
var params =
{
"type":"get",
"data":
{
"search":"some search text",
"sort":"DateTime",
"order":"asc",
"offset":0,
"limit":25
"filter":
{
"message":"some advanced search text"
"level":"some more advanced search text"
}
},
"cache":true,
"contentType":"application/json",
"dataType":"json"
};
*/
// Called by bootstrap-table to retrieve zm log data
function ajaxRequest(params) {
$j.getJSON(thisUrl + '?view=request&request=newlog&task=query', params.data)
.done(function(data) {
//console.log('Ajax parameters: ' + JSON.stringify(params));
// rearrange the result into what bootstrap-table expects
params.success({total: data.total, totalNotFiltered: data.totalNotFiltered, rows: data.rows});
updateHeaderStats(data);
})
.fail(logAjaxFail);
}
function updateHeaderStats(data) {
var pageNum = table.bootstrapTable('getOptions').pageNumber;
var pageSize = table.bootstrapTable('getOptions').pageSize;
var startRow = ( (pageNum - 1 ) * pageSize ) + 1;
var stopRow = pageNum * pageSize;
var newClass = (data.logstate == 'ok') ? 'text-success' : (data.logstate == 'alert' ? 'text-warning' : ((data.logstate == 'alarm' ? 'text-danger' : '')));
$j('#logState').text(data.logstate);
$j('#logState').removeClass('text-success');
$j('#logState').removeClass('text-warning');
$j('#logState').removeClass('text-danger');
$j('#logState').addClass(newClass);
$j('#totalLogs').text(data.total);
$j('#availLogs').text(data.totalNotFiltered);
$j('#lastUpdate').text(data.updated);
$j('#displayLogs').text(startRow + ' to ' + stopRow);
}
function initPage() {
var backBtn = $j('#backBtn');
// Init the bootstrap-table with custom icons
table.bootstrapTable({icons: icons});
// Assign inf, err, fat, dbg color classes to the rows in the table
table.on('post-body.bs.table', function(data) {
var lvl_ndx = $j('#logTable tr th').filter(function() {
return $j(this).text().trim() == 'Level';
}).index();
$j('#logTable tr').each(function(ndx, row) {
var row = $j(row);
var level = row.find('td').eq(lvl_ndx).text().trim();
if (( level == 'FAT' ) || ( level == 'PNC' )) {
row.addClass('log-fat');
} else if ( level == 'ERR' ) {
row.addClass('log-err');
} else if ( level == 'WAR' ) {
row.addClass('log-war');
} else if ( level == 'DBG' ) {
row.addClass('log-dbg');
}
});
});
// Don't enable the back button if there is no previous zm page to go back to
backBtn.prop('disabled', !document.referrer.length);
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
}
$j(document).ready(function() {
initPage();
});

View File

@ -1,3 +1,34 @@
// Load the Server Modal HTML via Ajax call
function getServerModal(sid) {
$j.getJSON(thisUrl + '?request=modal&modal=server&id=' + sid)
.done(function(data) {
if ( $j('#ServerModal').length ) {
$j('#ServerModal').replaceWith(data.html);
} else {
$j("body").append(data.html);
}
$j('#ServerModal').modal('show');
// Manage the Save button
$j('#serverSubmitBtn').click(function(evt) {
evt.preventDefault();
$j('#serverModalForm').submit();
});
})
.fail(logAjaxFail);
}
function enableServerModal() {
$j(".serverCol").click(function(evt) {
evt.preventDefault();
var sid = $j(this).data('sid');
getServerModal(sid);
});
$j('#NewServerBtn').click(function(evt) {
evt.preventDefault();
getServerModal(0);
});
}
// Load the Storage Modal HTML via Ajax call
function getStorageModal(sid) {
$j.getJSON(thisUrl + '?request=modal&modal=storage&id=' + sid)
@ -14,10 +45,7 @@ function getStorageModal(sid) {
$j('#storageModalForm').submit();
});
})
.fail(function(jqxhr, textStatus, error) {
console.log("Request Failed: " + textStatus + ", " + error);
console.log("Response Text: " + jqxhr.responseText);
});
.fail(logAjaxFail);
}
function enableStorageModal() {
@ -34,10 +62,13 @@ function enableStorageModal() {
function initPage() {
var NewStorageBtn = $j('#NewStorageBtn');
var NewServerBtn = $j('#NewServerBtn');
if ( canEditSystem ) enableStorageModal();
if ( canEditSystem ) enableServerModal();
NewStorageBtn.prop('disabled', !canEditSystem);
NewServerBtn.prop('disabled', !canEditSystem);
}
$j(document).ready(function() {

View File

@ -1,62 +0,0 @@
$j(document).ready(function() {
// Enable or disable the Delete button depending on the selected run state
$j("#runState").change(function() {
runstate = $j(this).val();
if ( (runstate == 'stop') || (runstate == 'restart') || (runstate == 'start') || (runstate == 'default') ) {
$j("#btnDelete").prop("disabled", true);
} else {
$j("#btnDelete").prop("disabled", false);
}
});
// Enable or disable the Save button when entering a new state
$j("#newState").keyup(function() {
length = $j(this).val().length;
if ( length < 1 ) {
$j("#btnSave").prop("disabled", true);
} else {
$j("#btnSave").prop("disabled", false);
}
});
// Delete a state
$j("#btnDelete").click(function() {
stateStuff('delete', $j("#runState").val());
});
// Save a new state
$j("#btnSave").click(function() {
stateStuff('save', undefined, $j("#newState").val());
});
// Change state
$j("#btnApply").click(function() {
stateStuff('state', $j("#runState").val());
});
function stateStuff(action, runState, newState) {
// the state action will redirect to console
var formData = {
'view': 'state',
'action': action,
'apply': 1,
'runState': runState,
'newState': newState
};
$j("#pleasewait").toggleClass("hidden");
$j.ajax({
type: 'POST',
url: thisUrl,
data: formData,
dataType: 'html',
timeout: 0
}).done(function(data) {
location.reload();
});
}
});

View File

@ -1,2 +0,0 @@
var running = <?php echo daemonCheck()?'true':'false' ?>;
var applying = <?php echo !empty($_REQUEST['apply'])?'true':'false' ?>;

View File

@ -28,6 +28,21 @@ function initPage() {
return false;
};
});
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Disable the back button if there is nothing to go back to
$j('#backBtn').prop('disabled', !document.referrer.length);
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
} // end function initPage
window.addEventListener('DOMContentLoaded', initPage);

View File

@ -560,6 +560,9 @@ function watchdogCheck(type) {
function watchdogOk(type) {
watchdogInactive[type] = false;
}
function presetSelectorBlur() {
this.selectedIndex = 0;
}
var monitors = new Array();
@ -569,6 +572,7 @@ function initPage() {
//form.elements['newZone[Name]'].disabled = true;
//form.elements['newZone[Type]'].disabled = true;
form.presetSelector.disabled = true;
form.presetSelector.onblur = window['presetSelectorBlur'].bind(form.presetSelector, form.presetSelector);
//form.elements['newZone[Units]'].disabled = true;
if ( CheckMethod = form.elements['newZone[CheckMethod]'] ) {
CheckMethod.disabled = true;
@ -665,6 +669,21 @@ function initPage() {
el.addEventListener("load", imageLoadEvent, {passive: true});
});
window.addEventListener("resize", drawZonePoints, {passive: true});
// Manage the BACK button
document.getElementById("backBtn").addEventListener("click", function onBackClick(evt) {
evt.preventDefault();
window.history.back();
});
// Disable the back button if there is nothing to go back to
$j('#backBtn').prop('disabled', !document.referrer.length);
// Manage the REFRESH Button
document.getElementById("refreshBtn").addEventListener("click", function onRefreshClick(evt) {
evt.preventDefault();
window.location.reload(true);
});
} // initPage
function imageLoadEvent() {

Some files were not shown because too many files have changed in this diff Show More