Merge branch 'storageareas' into zma_to_thread

This commit is contained in:
Isaac Connor 2018-01-16 17:39:37 -05:00
commit 573c44839a
66 changed files with 1079 additions and 1226 deletions

View File

@ -325,7 +325,7 @@ CREATE TABLE `Groups` (
) ENGINE=@ZM_MYSQL_ENGINE@;
--
--Table structure for table `Groups_Monitors`
-- Table structure for table `Groups_Monitors`
--
DROP TABLE IF EXISTS `Groups_Monitors`;
@ -701,7 +701,7 @@ CREATE TABLE `Storage` (
--
-- Create a default storage location
--
insert into Storage VALUES (NULL, '/var/cache/zoneminder/events', 'Default', 'local', NULL );
insert into Storage VALUES (NULL, '/var/cache/zoneminder/events', 'Default', 'local', NULL, 'Medium', 0 );
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
@ -723,22 +723,6 @@ insert into Users VALUES (NULL,'admin',password('admin'),'',1,'View','Edit','Edi
--
-- Add a sample filter to purge the oldest 100 events when the disk is 95% full
--
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(64) NOT NULL default '',
`Query` text NOT NULL,
`AutoArchive` tinyint(3) unsigned NOT NULL default '0',
`AutoVideo` tinyint(3) unsigned NOT NULL default '0',
`AutoUpload` tinyint(3) unsigned NOT NULL default '0',
`AutoEmail` tinyint(3) unsigned NOT NULL default '0',
`AutoMessage` tinyint(3) unsigned NOT NULL default '0',
`AutoExecute` tinyint(3) unsigned NOT NULL default '0',
`AutoExecuteCmd` tinytext,
`AutoDelete` tinyint(3) unsigned NOT NULL default '0',
`AutoMove` tinyint(3) unsigned NOT NULL default '0',
`AutoMoveTo` smallint(5) unsigned NOT NULL default 0,
`UpdateDiskSpace` tinyint(3) unsigned NOT NULL default '0',
`Background` tinyint(1) unsigned NOT NULL default '0',
`Concurrent` tinyint(1) unsigned NOT NULL default '0',
insert into Filters values (NULL,'PurgeWhenFull','{"sort_field":"Id","terms":[{"val":0,"attr":"Archived","op":"="},{"cnj":"and","val":95,"attr":"DiskPercent","op":">="}],"limit":100,"sort_asc":1}',0/*AutoArchive*/,0/*AutoVideo*/,0/*AutoUpload*/,0/*AutoEmail*/,0/*AutoMessage*/,0/*AutoExecute*/,'',1/*AutoDelete*/,0/*AutoMove*/,0/*MoveTo*/,0/*UpdateDiskSpace*/,1/*Background*/,0/*Concurrent*/);
insert into Filters values (NULL,'Update DiskSpace','{"terms":[{"attr":"DiskSpace","op":"IS","val":"NULL"}]}',0,0,0,0,0,0,'',0,0,0,1,1,0);
@ -861,16 +845,20 @@ INSERT INTO ZonePresets VALUES (5,'Best, low sensitivity','Active','Percent','Bl
INSERT INTO ZonePresets VALUES (6,'Best, medium sensitivity','Active','Percent','Blobs',40,NULL,16,NULL,5,5,12,NULL,10,NULL,1,NULL,0,0);
INSERT INTO ZonePresets VALUES (7,'Best, high sensitivity','Active','Percent','Blobs',20,NULL,8,NULL,3,3,6,NULL,5,NULL,1,NULL,0,0);
DROP TABLE IF EXISTS Maps;
CREATE TABLE Maps (
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` TEXT NOT NULL,
`Filename` TEXT NOT NULL default '',
`Name` VARCHAR(64) NOT NULL,
`Filename` VARCHAR(64) NOT NULL default '',
`NumCoords` tinyint(3) unsigned NOT NULL default '0',
`Coords` tinytext NOT NULL,
`ParentId` int(1) unsigned,
PRIMARY KEY (`Id`)
);
DROP TABLE IF EXISTS MontageLayout;
CREATE TABLE MontageLayouts (
`Id` int(10) unsigned NOT NULL auto_increment,
`Name` TEXT NOT NULL,

View File

@ -244,3 +244,32 @@ SET @s = (SELECT IF(
PREPARE stmt FROM @s;
EXECUTE stmt;
UPDATE Monitors INNER JOIN (
SELECT MonitorId,
COUNT(Id) AS TotalEvents,
SUM(DiskSpace) AS TotalEventDiskSpace,
SUM(IF(Archived,1,0)) AS ArchivedEvents,
SUM(IF(Archived,DiskSpace,0)) AS ArchivedEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 hour),1,0)) AS HourEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 hour),DiskSpace,0)) AS HourEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 day),1,0)) AS DayEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 day),DiskSpace,0)) AS DayEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 week),1,0)) AS WeekEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 week),DiskSpace,0)) AS WeekEventDiskSpace,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 month),1,0)) AS MonthEvents,
SUM(IF(StartTime > DATE_SUB(NOW(), INTERVAL 1 month),DiskSpace,0)) AS MonthEventDiskSpace
FROM Events GROUP BY MonitorId
) AS E ON E.MonitorId=Monitors.Id SET
Monitors.TotalEvents = E.TotalEvents,
Monitors.TotalEventDiskSpace = E.TotalEventDiskSpace,
Monitors.ArchivedEvents = E.ArchivedEvents,
Monitors.ArchivedEventDiskSpace = E.ArchivedEventDiskSpace,
Monitors.HourEvents = E.HourEvents,
Monitors.HourEventDiskSpace = E.HourEventDiskSpace,
Monitors.DayEvents = E.DayEvents,
Monitors.DayEventDiskSpace = E.DayEventDiskSpace,
Monitors.WeekEvents = E.WeekEvents,
Monitors.WeekEventDiskSpace = E.WeekEventDiskSpace,
Monitors.MonthEvents = E.MonthEvents,
Monitors.MonthEventDiskSpace = E.MonthEventDiskSpace;

View File

@ -1451,6 +1451,17 @@ our @options = (
type => $types{boolean},
category => 'logging',
},
{
name => 'ZM_WEB_TITLE',
default => 'ZoneMinder',
description => 'The title displayed wherever the site references itself.',
help => q`
If you want the site to identify as something other than ZoneMinder, change this here.
It can be used to more accurately identify this installation from others.
`,
type => $types{string},
category => 'web',
},
{
name => 'ZM_WEB_TITLE_PREFIX',
default => 'ZM',
@ -1464,6 +1475,27 @@ our @options = (
type => $types{string},
category => 'web',
},
{
name => 'ZM_HOME_URL',
default => 'http://zoneminder.com',
description => 'The url used in the home/logo area of the navigation bar.',
help => q`
By default this takes you to the zoneminder.com website,
but perhaps you would prefer it to take you somewhere else.
`,
type => $types{string},
category => 'web',
},
{
name => 'ZM_HOME_CONTENT',
default => 'ZoneMinder',
description => 'The content of the home button.',
help => q`
You may wish to set this to empty if you are using css to put a background image on it.
`,
type => $types{string},
category => 'web',
},
{
name => 'ZM_WEB_CONSOLE_BANNER',
default => '',

View File

@ -359,7 +359,7 @@ sub delete_files {
my $storage_path = $Storage->Path();
if ( ! $storage_path ) {
Fatal("Empty storage path when deleting files for event $$event{Id} with storage id $$event{StorageId} ");
Error("Empty storage path when deleting files for event $$event{Id} with storage id $$event{StorageId} ");
return;
}

View File

@ -141,7 +141,8 @@ sub new {
$this->{idArgs} = '';
$this->{level} = INFO;
if (-t STDIN) {
$this->{hasTerm} = -t STDERR;
if ( $this->{hasTerm} ) {
$this->{termLevel} = INFO;
} else {
$this->{termLevel} = NOLOG;
@ -152,7 +153,6 @@ if (-t STDIN) {
$this->{effectiveLevel} = INFO;
$this->{autoFlush} = 1;
$this->{hasTerm} = -t STDERR;
( $this->{fileName} = $0 ) =~ s|^.*/||;
$this->{logPath} = $Config{ZM_PATH_LOGS};

View File

@ -349,14 +349,15 @@ sub zmMemRead {
} elsif ( $type =~ /^uint8\[\d+\]$/ ) {
( $value ) = unpack( 'C'.$size, $data );
} else {
Fatal( "Unexpected type '".$type."' found for '".$field."'" );
Error( "Unexpected type '".$type."' found for '".$field."'" );
next;
}
push( @values, $value );
push @values, $value;
}
if ( wantarray() ) {
return( @values )
return @values;
}
return( $values[0] );
return $values[0];
}
sub zmMemInvalidate {

View File

@ -77,19 +77,18 @@ sub zmMemAttach {
my ( $monitor, $size ) = @_;
if ( ! $size ) {
Error( "No size passed to zmMemAttach for monitor $$monitor{Id}\n" );
return( undef );
return undef;
}
if ( !defined($monitor->{MMapAddr}) ) {
my $mmap_file = $Config{ZM_PATH_MAP}."/zm.mmap.".$monitor->{Id};
my $mmap_file = $Config{ZM_PATH_MAP}.'/zm.mmap.'.$monitor->{Id};
if ( ! -e $mmap_file ) {
Error( sprintf( "Memory map file '%s' does not exist. zmc might not be running."
, $mmap_file
)
);
return ( undef );
return undef;
}
my $mmap_file_size = -s $mmap_file;
if ( $mmap_file_size < $size ) {
@ -99,25 +98,25 @@ sub zmMemAttach {
, $mmap_file_size
)
);
return ( undef );
return undef;
}
my $MMAP;
if ( !open( $MMAP, '+<', $mmap_file ) ) {
Error( sprintf( "Can't open memory map file '%s': $!\n", $mmap_file ) );
return( undef );
Error( sprintf( "Can't open memory map file '%s': $!", $mmap_file ) );
return undef;
}
my $mmap = undef;
my $mmap_addr = mmap( $mmap, $size, PROT_READ|PROT_WRITE, MAP_SHARED, $MMAP );
if ( !$mmap_addr || !$mmap ) {
Error( sprintf( "Can't mmap to file '%s': $!\n", $mmap_file ) );
close( $MMAP );
return( undef );
return undef;
}
$monitor->{MMapHandle} = $MMAP;
$monitor->{MMapAddr} = $mmap_addr;
$monitor->{MMap} = \$mmap;
}
return( !undef );
return !undef;
}
sub zmMemDetach {
@ -149,10 +148,10 @@ sub zmMemGet {
, $monitor->{Id}
)
);
return( undef );
return undef;
}
my $data = substr( $$mmap, $offset, $size );
return( $data );
return $data;
}
sub zmMemPut {

View File

@ -237,7 +237,7 @@ MAIN: while( $loop ) {
} elsif ( $$Storage{Scheme} eq 'Medium' ) {
foreach my $event_dir ( glob("$monitor_dir/*/*") ) {
next if ! -d $event_dir;
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d\+)$/;
my ( $date, $event_id ) = $event_dir =~ /^$monitor_dir\/(\d{4}\-\d{2}\-\d{2})\/(\d+)$/;
if ( ! $event_id ) {
Debug("Unable to parse date/event_id from $event_dir");
next;

View File

@ -69,12 +69,10 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
logInit();
logSetSignal();
Info( "Watchdog starting\n" );
Info( "Watchdog pausing for ".START_DELAY." seconds\n" );
Info( "Watchdog starting, pausing for ".START_DELAY." seconds\n" );
sleep( START_DELAY );
my $dbh = zmDbConnect();
my $sql = $Config{ZM_SERVER_ID} ? 'SELECT * FROM Monitors WHERE ServerId=?' : 'SELECT * FROM Monitors';
my $sth = $dbh->prepare_cached( $sql )
or Fatal( "Can't prepare '$sql': ".$dbh->errstr() );
@ -84,7 +82,6 @@ while( 1 ) {
my $res = $sth->execute( $Config{ZM_SERVER_ID} ? $Config{ZM_SERVER_ID} : () )
or Fatal( "Can't execute: ".$sth->errstr() );
while( my $monitor = $sth->fetchrow_hashref() ) {
my $now = time();
next if $monitor->{Function} eq 'None';
my $restart = 0;
@ -99,38 +96,41 @@ while( 1 ) {
}
Debug( "LastWriteTime is = $capture_time." );
if ( !$capture_time ) {
my $startup_time = zmGetStartupTime( $monitor );
if ( $now - $startup_time > $Config{ZM_WATCH_MAX_DELAY} ) {
Info( "Restarting capture daemon for ".$monitor->{Name}.", no image since startup. Startup time was $startup_time - now $now > $Config{ZM_WATCH_MAX_DELAY}\n" );
$restart = 1;
} else {
my $startup_time = zmGetStartupTime( $monitor );
if ( $now - $startup_time > $Config{ZM_WATCH_MAX_DELAY} ) {
Info( "Restarting capture daemon for ".$monitor->{Name}.", no image since startup. Startup time was $startup_time - now $now > $Config{ZM_WATCH_MAX_DELAY}\n" );
$restart = 1;
} else {
# We can't get the last capture time so can't be sure it's died, it might just be starting up.
zmMemInvalidate( $monitor );
next;
}
}
}
if ( ! $restart ) {
my $max_image_delay = ( $monitor->{MaxFPS}
&&($monitor->{MaxFPS}>0)
&&($monitor->{MaxFPS}<1)
) ? (3/$monitor->{MaxFPS})
: $Config{ZM_WATCH_MAX_DELAY}
;
my $image_delay = $now-$capture_time;
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) {
Info( "Restarting capture daemon for "
.$monitor->{Name}.", time since last capture $image_delay seconds ($now-$capture_time)\n"
);
$restart = 1;
}
} # end if ! restart
if ( ! $restart ) {
my $max_image_delay = ( $monitor->{MaxFPS}
&&($monitor->{MaxFPS}>0)
&&($monitor->{MaxFPS}<1)
) ? (3/$monitor->{MaxFPS})
: $Config{ZM_WATCH_MAX_DELAY}
;
my $image_delay = $now-$capture_time;
Debug( "Monitor $monitor->{Id} last captured $image_delay seconds ago, max is $max_image_delay\n" );
if ( $image_delay > $max_image_delay ) {
Info( "Restarting capture daemon for "
.$monitor->{Name}.", time since last capture $image_delay seconds ($now-$capture_time)\n"
);
$restart = 1;
}
} # end if ! restart
} else {
Info( "Restarting capture daemon for ".$monitor->{Name}.", shared data not valid\n" );
$restart = 1;
}
if ( $restart ) {
# Because zma depends on zmc, and zma can hold the shm in place, preventing zmc from using the space in /dev/shm,
# we need to stop zma before restarting zmc.
runCommand( "zmdc.pl stop zma -m $$monitor{Id}" ) if $monitor->{Function} ne 'Monitor';
my $command;
if ( $monitor->{Type} eq 'Local' ) {
$command = "zmdc.pl restart zmc -d $monitor->{Device}";
@ -138,6 +138,7 @@ while( 1 ) {
$command = "zmdc.pl restart zmc -m $monitor->{Id}";
}
runCommand( $command );
runCommand( "zmdc.pl start zma -m $$monitor{Id}" ) if $monitor->{Function} ne 'Monitor';
} elsif ( $monitor->{Function} ne 'Monitor' ) {
# Now check analysis daemon
$restart = 0;

View File

@ -97,7 +97,6 @@ Event::Event( Monitor *p_monitor, struct timeval p_start_time, const std::string
max_score = 0;
have_video_keyframe = false;
struct stat statbuf;
char id_file[PATH_MAX];
struct tm *stime = localtime( &start_time.tv_sec );
@ -399,7 +398,10 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
static char event_file[PATH_MAX];
snprintf( event_file, sizeof(event_file), staticConfig.capture_file_format, path, frames );
if ( ! ( monitor->GetOptSaveJPEGs() & 3 ) ) {
if ( monitor->GetOptSaveJPEGs() & 1 ) {
Debug( 1, "Writing pre-capture frame %d", frames );
WriteFrameImage( images[i], *(timestamps[i]), event_file );
} else {
//If this is the first frame, we should add a thumbnail to the event directory
// ICON: We are working through the pre-event frames so this snapshot won't
// neccessarily be of the motion. But some events are less than 10 frames,
@ -409,10 +411,9 @@ void Event::AddFramesInternal( int n_frames, int start_frame, Image **images, st
WriteFrameImage( images[i], *(timestamps[i]), snapshot_file.c_str() );
}
}
if ( monitor->GetOptSaveJPEGs() & 1 ) {
Debug( 1, "Writing pre-capture frame %d", frames );
WriteFrameImage( images[i], *(timestamps[i]), event_file );
}
//if ( videowriter != NULL ) {
//WriteFrameVideo( images[i], *(timestamps[i]), videowriter );
//}
struct DeltaTimeval delta_time;
DELTA_TIMEVAL( delta_time, *(timestamps[i]), start_time, DT_PREC_2 );
@ -466,20 +467,17 @@ void Event::AddFrame( Image *image, struct timeval timestamp, int score, Image *
static char event_file[PATH_MAX];
snprintf( event_file, sizeof(event_file), staticConfig.capture_file_format, path, frames );
if ( ! ( monitor->GetOptSaveJPEGs() & 3 ) ) {
//if ( monitor->GetOptSaveJPEGs() & 4 ) {
// Only snapshots
//If this is the first frame, we should add a thumbnail to the event directory
if ( frames == 10 || frames == 1 ) {
std::string snapshot_file = std::string(path) + "/snapshot.jpg";
WriteFrameImage( image, timestamp, snapshot_file.c_str() );
}
}
if ( monitor->GetOptSaveJPEGs() & 1 ) {
Debug( 1, "Writing capture frame %d to %s", frames, event_file );
if ( ! WriteFrameImage( image, timestamp, event_file ) ) {
Error("Failed to write frame image");
}
} else {
//If this is the first frame, we should add a thumbnail to the event directory
if ( frames == 10 || frames == 1 ) {
std::string snapshot_file = std::string(path) + "/snapshot.jpg";
WriteFrameImage( image, timestamp, snapshot_file.c_str() );
}
}
struct DeltaTimeval delta_time;

View File

@ -135,6 +135,61 @@ public $defaults = array(
return $this->{'MonitorIds'};
}
public static function get_group_dropdown() {
session_start();
$selected_group_id = 0;
if ( isset($_REQUEST['groups']) ) {
$selected_group_id = $group_id = $_SESSION['groups'] = $_REQUEST['groups'];
} else if ( isset( $_SESSION['groups'] ) ) {
$selected_group_id = $group_id = $_SESSION['groups'];
} else if ( isset($_REQUEST['filtering']) ) {
unset($_SESSION['groups']);
}
session_write_close();
$Groups = array();
foreach ( Group::find_all( ) as $Group ) {
$Groups[$Group->Id()] = $Group;
}
# This array is indexed by parent_id
global $children;
$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_options( $Group ) {
global $children;
$options = array( $Group->Id() => str_repeat('&nbsp;&nbsp;&nbsp;', $Group->depth() ) . $Group->Name() );
if ( isset($children[$Group->Id()]) ) {
foreach ( $children[$Group->Id()] as $child ) {
$options += get_options( $child );
}
}
return $options;
}
$group_options = array();
foreach ( $Groups as $id=>$Group ) {
if ( ! $Group->ParentId() ) {
$group_options += get_options( $Group );
}
}
return htmlSelect( 'Group[]', $group_options, isset($_SESSION['Group'])?$_SESSION['Group']:null, array(
'onchange' => 'this.form.submit();',
'class'=>'chosen',
'multiple'=>'multiple',
'data-placeholder'=>'All',
) );
} # end public static function get_group_dropdown
public static function get_group_dropdowns() {
# This will end up with the group_id of the deepest selection
$group_id = 0;
@ -142,6 +197,8 @@ public $defaults = array(
$groups = array();
$parent_group_ids = null;
session_start();
$group_options = array(0=>'All');
while(1) {
$Groups = Group::find_all( array('ParentId'=>$parent_group_ids) );
if ( ! count( $Groups ) )
@ -161,15 +218,17 @@ public $defaults = array(
if ( ! isset( $groups[$depth] ) ) {
$groups[$depth] = array(0=>'All');
}
$group_options[$Group->Id()] = str_repeat( '&nbsp;', $depth ) . $Group->Name();
$groups[$depth][$Group->Id()] = $Group->Name();
if ( $selected_group_id and ( $selected_group_id == $Group->Id() ) )
$parent_group_ids[] = $Group->Id();
}
echo htmlSelect( 'group'.$depth, $groups[$depth], $selected_group_id, "this.form.submit();" );
//echo htmlSelect( 'group'.$depth, $groups[$depth], $selected_group_id, "this.form.submit();" );
if ( ! count($parent_group_ids) ) break;
$depth += 1;
}
echo htmlSelect( 'groups', $group_options, $selected_group_id, 'this.form.submit();' );
session_write_close();
return $group_id;
@ -179,9 +238,17 @@ public $defaults = array(
public static function get_group_sql( $group_id ) {
$groupSql = '';
if ( $group_id ) {
$MonitorIds = dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($group_id) );
if ( is_array( $group_id ) ) {
$group_id_sql_part = ' IN ('.implode(',', array_map(function(){return '?';}, $group_id ) ).')';
$MonitorIds = array_merge( $MonitorIds, dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id) ) );
$MonitorIds = dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId'.$group_id_sql_part, 'MonitorId', $group_id );
$MonitorIds = array_merge( $MonitorIds, dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId'.$group_id_sql_part.')', 'MonitorId', $group_id ) );
} else {
$MonitorIds = dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId=?', 'MonitorId', array($group_id) );
$MonitorIds = array_merge( $MonitorIds, dbFetchAll( 'SELECT MonitorId FROM Groups_Monitors WHERE GroupId IN (SELECT Id FROM Groups WHERE ParentId = ?)', 'MonitorId', array($group_id) ) );
}
$groupSql = " find_in_set( Id, '".implode( ',', $MonitorIds )."' )";
}
return $groupSql;

View File

@ -23,15 +23,39 @@ class Server {
$this->{'Hostname'} = '';
}
}
public static function find_all() {
$servers = array();
$result = dbQuery( 'SELECT * FROM Servers ORDER BY Name');
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server' );
foreach ( $results as $row => $server_obj ) {
$servers[] = $server_obj;
}
return $servers;
}
public static function find_all( $parameters = null, $options = null ) {
$filters = array();
$sql = 'SELECT * FROM Servers ';
$values = array();
if ( $parameters ) {
$fields = array();
$sql .= 'WHERE ';
foreach ( $parameters as $field => $value ) {
if ( $value == null ) {
$fields[] = $field.' IS NULL';
} else if ( is_array( $value ) ) {
$func = function(){return '?';};
$fields[] = $field.' IN ('.implode(',', array_map( $func, $value ) ). ')';
$values += $value;
} else {
$fields[] = $field.'=?';
$values[] = $value;
}
}
$sql .= implode(' AND ', $fields );
}
if ( $options and isset($options['order']) ) {
$sql .= ' ORDER BY ' . $options['order'];
}
$result = dbQuery($sql, $values);
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Server');
foreach ( $results as $row => $obj ) {
$filters[] = $obj;
}
return $filters;
}
public function Url() {
if ( $this->Id() ) {

File diff suppressed because it is too large Load Diff

View File

@ -636,10 +636,10 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
{
if ( is_array( $newValues[$key] ) ) {
if ( join(',',$newValues[$key]) != $values[$key] ) {
$changes[$key] = "$key = ".dbEscape(join(',',$newValues[$key]));
$changes[$key] = "`$key` = ".dbEscape(join(',',$newValues[$key]));
}
} elseif ( $values[$key] ) {
$changes[$key] = "$key = ''";
$changes[$key] = "`$key` = ''";
}
break;
}
@ -696,9 +696,9 @@ function getFormChanges( $values, $newValues, $types=false, $columns=false ) {
{
if ( !isset($values[$key]) || ($values[$key] != $value) ) {
if ( ! isset($value) || $value == '' ) {
$changes[$key] = "$key = NULL";
$changes[$key] = "`$key` = NULL";
} else {
$changes[$key] = $key . ' = '.dbEscape(trim($value));
$changes[$key] = "`$key` = ".dbEscape(trim($value));
}
}
break;
@ -1198,8 +1198,9 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&amp;' ) {
// 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' ) {
$StorageArea = new Storage( $terms[$j]['val'] );
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();
@ -1211,8 +1212,8 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&amp;' ) {
// 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 = $i; $j < count($terms); $j++ ) {
if ( isset($terms[$i]['attr']) and $terms[$i]['attr'] == 'StorageId' ) {
$StorageArea = new Storage( $terms[$i]['val'] );
if ( isset($terms[$i]['attr']) and $terms[$i]['attr'] == 'StorageId' and isset($terms[$j]['val']) ) {
$StorageArea = new Storage($terms[$i]['val']);
}
} // end foreach remaining term
} // end no StorageArea found yet
@ -1298,8 +1299,10 @@ function parseFilter( &$filter, $saveToSession=false, $querySep='&amp;' ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][op]").'='.urlencode($terms[$i]['op']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][op]\" value=\"".htmlspecialchars($terms[$i]['op'])."\"/>\n";
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($terms[$i]['val']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($terms[$i]['val'])."\"/>\n";
if ( isset($terms[$i]['val']) ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][val]").'='.urlencode($terms[$i]['val']);
$filter['fields'] .= "<input type=\"hidden\" name=\"filter[Query][terms][$i][val]\" value=\"".htmlspecialchars($terms[$i]['val'])."\"/>\n";
}
} // end foreach term
if ( isset($terms[$i]['cbr']) ) {
$filter['query'] .= $querySep.urlencode("filter[Query][terms][$i][cbr]").'='.urlencode($terms[$i]['cbr']);
@ -2145,7 +2148,8 @@ function cache_bust( $file ) {
# To defeat caching. Should probably use md5 hash
$parts = pathinfo($file);
global $css;
$cacheFile = 'cache/'.$parts['filename'].'-'.$css.'-'.filemtime($file).'.'.$parts['extension'];
$dirname = preg_replace( '/\//', '_', $parts['dirname'] );
$cacheFile = 'cache/'.$dirname.'_'.$parts['filename'].'-'.$css.'-'.filemtime($file).'.'.$parts['extension'];
if ( file_exists( ZM_PATH_WEB.'/'.$cacheFile ) or symlink( ZM_PATH_WEB.'/'.$file, ZM_PATH_WEB.'/'.$cacheFile ) ) {
return $cacheFile;
} else {

View File

@ -151,5 +151,4 @@
width: 24px;
color: #ffffff;
text-align: center;
background-color: #016A9D;
}

View File

@ -1,3 +1,7 @@
#options {
padding-top: 10px;
}
input.small {
width: 6em;
}

View File

@ -19,14 +19,14 @@
//
// Don't load in additional JS to these views
$bad_views = array('monitor', 'log');
function xhtmlHeaders( $file, $title ) {
global $css;
global $skin;
$skinCssFile = getSkinFile( 'css/'.$css.'/skin.css' );
$skinCssFilejquery = getSkinFile( 'css/'.$css.'/jquery-ui-theme.css' );
# This idea is that we always include the classic css files,
# and then any different skin only needs to contain things that are different.
$baseCssPhpFile = getSkinFile( 'css/base/skin.css.php' );
$skinCssPhpFile = getSkinFile( 'css/'.$css.'/skin.css.php' );
$skinJsFile = getSkinFile( 'js/skin.js' );
@ -34,15 +34,22 @@ function xhtmlHeaders( $file, $title ) {
$cssJsFile = getSkinFile( 'js/'.$css.'.js' );
$basename = basename( $file, '.php' );
$viewCssFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css' );
if ($basename == 'watch') {
$viewCssFileExtra = getSkinFile( '/css/'.$css.'/views/control.css' );
}
$viewCssPhpFile = getSkinFile( '/css/'.$css.'/views/'.$basename.'.css.php' );
$viewJsFile = getSkinFile( 'views/js/'.$basename.'.js' );
$viewJsPhpFile = getSkinFile( 'views/js/'.$basename.'.js.php' );
extract( $GLOBALS, EXTR_OVERWRITE );
function output_link_if_exists( $files ) {
global $skin;
$html = array();
foreach ( $files as $file ) {
if ( getSkinFile( $file ) ) {
$html[] = '<link rel="stylesheet" href="'.cache_bust( 'skins/'.$skin.'/'.$file ).'" type="text/css"/>';
}
}
return implode("\n", $html);
}
?>
<!DOCTYPE html>
<html lang="en">
@ -66,19 +73,25 @@ if ( file_exists( "skins/$skin/css/$css/graphics/favicon.ico" ) ) {
<link rel="stylesheet" href="css/reset.css" type="text/css"/>
<link rel="stylesheet" href="css/overlay.css" type="text/css"/>
<link rel="stylesheet" href="css/bootstrap.min.css" type="text/css"/>
<link rel="stylesheet" href="<?php echo cache_bust($skinCssFile) ?>" type="text/css" media="screen"/>
<link rel="stylesheet" href="<?php echo cache_bust($skinCssFilejquery) ?>" type="text/css" media="screen"/>
<?php
if ( $viewCssFile ) {
<?php
echo output_link_if_exists( array(
'css/base/skin.css',
'css/'.$css.'/skin.css',
'css/base/views/'.$basename.'.css',
'css/'.$css.'/views/'.$basename.'.css',
'/js/dateTimePicker/jquery-ui-timepicker-addon.css',
'/js/jquery-ui-structure.css',
'/css/'.$css.'/jquery-ui-theme.css',
)
);
?>
<link rel="stylesheet" href="<?php echo cache_bust($viewCssFile) ?>" type="text/css" media="screen"/>
<?php
}
if ( isset($viewCssFileExtra) ) {
?>
<link rel="stylesheet" href="<?php echo cache_bust($viewCssFileExtra) ?>" type="text/css" media="screen"/>
<link rel="stylesheet" href="skins/classic/js/chosen/chosen.min.css" type="text/css"/>
<?php
if ($basename == 'watch') {
echo output_link_if_exists( array(
'/css/base/views/control.css',
'/css/'.$css.'/views/control.css'
) );
}
if ( $viewCssPhpFile ) {
?>
@ -92,6 +105,7 @@ if ( file_exists( "skins/$skin/css/$css/graphics/favicon.ico" ) ) {
<?php
}
?>
<script type="text/javascript" src="tools/mootools/mootools-core.js"></script>
<script type="text/javascript" src="tools/mootools/mootools-more.js"></script>
<script type="text/javascript" src="js/mootools.ext.js"></script>
@ -101,9 +115,6 @@ if ( file_exists( "skins/$skin/css/$css/graphics/favicon.ico" ) ) {
<script type="text/javascript" src="skins/<?php echo $skin; ?>/js/chosen/chosen.jquery.min.js"></script>
<script type="text/javascript" src="skins/<?php echo $skin; ?>/js/dateTimePicker/jquery-ui-timepicker-addon.js"></script>
<link href="skins/<?php echo $skin ?>/js/dateTimePicker/jquery-ui-timepicker-addon.css" rel="stylesheet">
<link href="skins/<?php echo $skin ?>/js/jquery-ui-structure.css" rel="stylesheet">
<link href="skins/<?php echo $skin ?>/js/chosen/chosen.min.css" rel="stylesheet">
<script type="text/javascript">
//<![CDATA[
<!--
@ -164,7 +175,7 @@ if ( file_exists( "skins/$skin/css/$css/graphics/favicon.ico" ) ) {
<?php
} else {
?>
<script type="text/javascript" src="skins/classic/js/classic.js"></script>
<script type="text/javascript" src="skins/classic/js/base.js"></script>
<?php } ?>
<script type="text/javascript" src="<?php echo cache_bust($skinJsFile) ?>"></script>
<script type="text/javascript" src="js/logger.js"></script>
@ -205,7 +216,7 @@ function getNavBarHTML($reload = null) {
?>
<noscript>
<div style="background-color:red;color:white;font-size:x-large;">
ZoneMinder requires Javascript. Please enable Javascript in your browser for this site.
<?php echo ZM_WEB_TITLE ?> requires Javascript. Please enable Javascript in your browser for this site.
</div>
</noscript>
<div class="navbar navbar-inverse navbar-static-top">
@ -217,10 +228,11 @@ ZoneMinder requires Javascript. Please enable Javascript in your browser for thi
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.zoneminder.com" target="ZoneMinder">ZoneMinder</a>
<div class="navbar-brand"><a href="<?php echo ZM_HOME_URL?>" target="<?php echo ZM_WEB_TITLE ?>"><?php echo ZM_HOME_CONTENT ?></a></div>
</div>
<div class="collapse navbar-collapse" id="main-header-nav">
<?php if ( canView('Monitors') ) { ?>
<ul class="nav navbar-nav">
<li><a href="?view=console"><?php echo translate('Console') ?></a></li>
<?php if ( canView( 'System' ) ) { ?>
@ -271,9 +283,10 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
}
?>
</ul>
<?php } // end if canView('Monitors') ?>
<div class="navbar-right">
<?php if ( ZM_OPT_USE_AUTH ) { ?>
<?php if ( ZM_OPT_USE_AUTH and $user ) { ?>
<p class="navbar-text"><?php echo translate('LoggedInAs') ?> <?php echo makePopupLink( '?view=logout', 'zmLogout', 'logout', $user['Username'], (ZM_AUTH_TYPE == "builtin") ) ?> </p>
<?php } ?>
@ -288,20 +301,22 @@ if (isset($_REQUEST['filter']['Query']['terms']['attr'])) {
</div> <!-- End .container-fluid -->
<?php
}//end reload null. Runs on full page load
if ( (!ZM_OPT_USE_AUTH) or $user ) {
if ($reload == 'reload') ob_start();
?>
<div id="reload" class="container-fluid">
<div class="pull-left">
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bandwidth_options[$_COOKIE['zmBandwidth']] . ' ' . translate('BandwidthHead'), ($user && $user['MaxBandwidth'] != 'low' ) ) ?>
</div>
<div class="pull-right">
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="'.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
<h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3>
<?php } ?>
</div>
<ul class="list-inline">
<li><?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
<div id="Bandwidth" class="pull-left">
<?php echo makePopupLink( '?view=bandwidth', 'zmBandwidth', 'bandwidth', $bandwidth_options[$_COOKIE['zmBandwidth']] . ' ' . translate('BandwidthHead'), ($user && $user['MaxBandwidth'] != 'low' ) ) ?>
</div>
<div id="Version" class="pull-right">
<?php echo makePopupLink( '?view=version', 'zmVersion', 'version', '<span class="version '.$versionClass.'">v'.ZM_VERSION.'</span>', canEdit( 'System' ) ) ?>
<?php if ( defined('ZM_WEB_CONSOLE_BANNER') and ZM_WEB_CONSOLE_BANNER != '' ) { ?>
<h3 id="development"><?php echo ZM_WEB_CONSOLE_BANNER ?></h3>
<?php } ?>
</div>
<ul class="list-inline">
<li class="Load"><?php echo translate('Load') ?>: <?php echo getLoad() ?></li>
<?php
$connections = dbFetchOne( "SHOW status WHERE variable_name='threads_connected'", 'Value' );
$max_connections = dbFetchOne( "SHOW variables WHERE variable_name='max_connections'", 'Value' );
@ -330,6 +345,7 @@ if ($reload == 'reload') ob_start();
<!-- End .footer/reload --></div>
<?php
if ($reload == 'reload') return( ob_get_clean() );
} // end if (!ZM_OPT_USE_AUTH) or $user )
?>
</div><!-- End .navbar .navbar-default -->
<?php

View File

@ -47,7 +47,7 @@ var popupSizes = {
'image': { 'addWidth': 48, 'addHeight': 80 },
'log': { 'width': 1080, 'height': 720 },
'login': { 'width': 720, 'height': 480 },
'logout': { 'width': 260, 'height': 150 },
'logout': { 'width': 460, 'height': 300 },
'monitor': { 'width': 700, 'height': 720 },
'monitorpreset':{ 'width': 440, 'height': 200 },
'monitorprobe': { 'width': 500, 'height': 240 },

View File

@ -1,73 +0,0 @@
//
// ZoneMinder base static javascript 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.
//
//
// This file should only contain static JavaScript and no php.
// Use skin.js.php for JavaScript that need pre-processing
//
// Javascript window sizes
var popupSizes = {
'bandwidth': { 'width': 300, 'height': 200 },
'console': { 'width': 750, 'height': 312 },
'control': { 'width': 380, 'height': 480 },
'controlcaps': { 'width': 780, 'height': 320 },
'controlcap': { 'width': 400, 'height': 400 },
'cycle': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 62 },
'device': { 'width': 260, 'height': 150 },
'devices': { 'width': 400, 'height': 240 },
'donate': { 'width': 500, 'height': 280 },
'download': { 'width': 350, 'height': 215 },
'event': { 'addWidth': 108, 'minWidth': 496, 'addHeight': 230, 'minHeight': 540 },
'eventdetail': { 'width': 600, 'height': 420 },
'events': { 'width': 960, 'height': 780 },
'export': { 'width': 400, 'height': 340 },
'filter': { 'width': 900, 'height': 700 },
'frame': { 'addWidth': 32, 'minWidth': 384, 'addHeight': 200 },
'frames': { 'width': 600, 'height': 700 },
'function': { 'width': 300, 'height': 160 },
'group': { 'width': 360, 'height': 300 },
'groups': { 'width': 540, 'height': 420 },
'image': { 'addWidth': 48, 'addHeight': 80 },
'log': { 'width': 1080, 'height': 720 },
'login': { 'width': 720, 'height': 480 },
'logout': { 'width': 260, 'height': 300 },
'monitor': { 'width': 600, 'height': 780 },
'monitorpreset':{ 'width': 440, 'height': 200 },
'monitorprobe': { 'width': 500, 'height': 240 },
'monitorselect':{ 'width': 160, 'height': 200 },
'montage': { 'width': -1, 'height': -1 },
'onvifprobe': { 'width': 700, 'height': 500 },
'optionhelp': { 'width': 400, 'height': 320 },
'options': { 'width': 1000, 'height': 660 },
'preset': { 'width': 300, 'height': 120 },
'server': { 'width': 600, 'height': 405 },
'settings': { 'width': 220, 'height': 225 },
'state': { 'width': 370, 'height': 134 },
'stats': { 'width': 840, 'height': 200 },
'storage': { 'width': 600, 'height': 405 },
'timeline': { 'width': 760, 'height': 540 },
'user': { 'width': 360, 'height': 720 },
'version': { 'width': 360, 'height': 140 },
'video': { 'width': 420, 'height': 360 },
'videoview': { 'addWidth': 48, 'addHeight': 80 },
'watch': { 'addWidth': 96, 'minWidth': 420, 'addHeight': 384 },
'zone': { 'addWidth': 520, 'addHeight': 260, 'minHeight': 600 },
'zones': { 'addWidth': 72, 'addHeight': 232 }
};

View File

@ -18,13 +18,13 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
$servers = Server::find_all();
$servers = Server::find_all( null, array('order'=>'lower(Name)'));
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
}
session_start();
foreach ( array('ServerId','StorageId','Status','MonitorId') as $var ) {
foreach ( array('Group', 'ServerId','StorageId','Status','MonitorId') as $var ) {
if ( isset( $_REQUEST[$var] ) ) {
if ( $_REQUEST[$var] != '' ) {
$_SESSION[$var] = $_REQUEST[$var];
@ -49,7 +49,8 @@ foreach ( $storage_areas as $S ) {
<span id="groupControl"><label><?php echo translate('Group') ?>:</label>
<?php
# This will end up with the group_id of the deepest selection
$group_id = Group::get_group_dropdowns();
$group_id = isset($_SESSION['Group']) ? $_SESSION['Group'] : null;
echo Group::get_group_dropdown();
$groupSql = Group::get_group_sql( $group_id );
?>
</span>

View File

@ -92,7 +92,8 @@ if ( $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']] = $option['Name'];
$options[$option['Id']] = str_repeat('&nbsp;&nbsp;', $Groups[$option['Id']]->depth() ) . $option['Name'];
}
echo htmlSelect( 'newGroup[ParentId]', $options, $newGroup->ParentId(), array('onchange'=>'configureButtons(this);' ));
?>

View File

@ -18,7 +18,7 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
if ( !canView( 'Groups' ) ) {
if ( !canView('Groups') ) {
$view = 'error';
return;
}
@ -64,8 +64,7 @@ function group_line( $Group ) {
global $children;
global $max_depth;
$html = '<tr>';
for ( $i = 1; $i<$Group->depth(); $i+=1 )
$html .= '<td class="colName">&nbsp;</td>';
$html .= str_repeat( '<td class="colName">&nbsp;</td>', $Group->depth() );
$html .= '<td class="colName" colspan="'.($max_depth-($Group->depth()-1)).'">';
if ( canEdit('Groups') ) {
$html .= '<a href="#" onclick="editGroup('.$Group->Id().');">'. validHtmlStr($Group->Id() . ' ' . $Group->Name()).'</a>';

View File

@ -13,14 +13,11 @@ function getControlResponse( respObj, respText ) {
function controlCmd( control, event, xtell, ytell ) {
var locParms = "&id="+$('mid').get('value');
if ( event && (xtell || ytell) ) {
var xEvent = new Event( event );
var target = xEvent.target;
var target = event.target;
var coords = $(target).getCoordinates();
var l = coords.left;
var t = coords.top;
var x = xEvent.page.x - l;
var y = xEvent.page.y - t;
var x = event.pageX - coords.left;
var y = event.pageY - coords.top;
if ( xtell ) {
var xge = parseInt( (x*100)/coords.width );

View File

@ -6,7 +6,7 @@ function vjsReplay() {
case 'none':
break;
case 'single':
player.play();
vid.play();
break;
case 'all':
if (nextEventId == 0) {

View File

@ -526,7 +526,7 @@ function clicknav(minSecs,maxSecs,live) {// we use the current time if we can
if ( monitorZoomScale[monitorPtr[i]] < 0.99 || monitorZoomScale[monitorPtr[i]] > 1.01 ) // allow for some up/down changes and just treat as 1 of almost 1
zoomStr += "&z" + monitorPtr[i].toString() + "=" + monitorZoomScale[monitorPtr[i]].toFixed(2);
var uri = "?view=" + currentView + '&fit='+(fitMode==1?'1':'0') + groupStr + minStr + maxStr + currentStr + intervalStr + liveStr + zoomStr + "&scale=" + $j("#scaleslider")[0].value + "&speed=" + speeds[$j("#speedslider")[0].value];
var uri = "?view=" + currentView + '&fit='+(fitMode==1?'1':'0') + minStr + maxStr + currentStr + intervalStr + liveStr + zoomStr + "&scale=" + $j("#scaleslider")[0].value + "&speed=" + speeds[$j("#speedslider")[0].value];
window.location = uri;
} // end function clicknav
@ -745,7 +745,7 @@ function changeDateTime(e) {
if ( monitorZoomScale[monitorPtr[i]] < 0.99 || monitorZoomScale[monitorPtr[i]] > 1.01 ) // allow for some up/down changes and just treat as 1 of almost 1
zoomStr += "&z" + monitorPtr[i].toString() + "=" + monitorZoomScale[monitorPtr[i]].toFixed(2);
var uri = "?view=" + currentView + fitStr + groupStr + minStr + maxStr + liveStr + zoomStr + "&scale=" + $j("#scaleslider")[0].value + "&speed=" + speeds[$j("#speedslider")[0].value];
var uri = "?view=" + currentView + fitStr + minStr + maxStr + liveStr + zoomStr + "&scale=" + $j("#scaleslider")[0].value + "&speed=" + speeds[$j("#speedslider")[0].value];
window.location = uri;
}

View File

@ -27,7 +27,6 @@ var eStorageId = [];
var eStartSecs = [];
var eEndSecs = [];
var eventFrames = []; // this is going to presume all frames equal durationlength
var groupStr=<?php echo $group_id ? "'&group=$group_id'" : '""'; ?>;
<?php

View File

@ -541,14 +541,12 @@ function getControlResponse( respObj, respText ) {
function controlCmd( control, event, xtell, ytell ) {
var locParms = "";
if ( event && (xtell || ytell) ) {
var xEvent = new Event( event );
var target = xEvent.target;
console.log(event);
var target = event.target;
var coords = $(target).getCoordinates();
var l = coords.left;
var t = coords.top;
var x = xEvent.page.x - l;
var y = xEvent.page.y - t;
var x = event.pageX - coords.left;
var y = event.pageY - coords.top;
if ( xtell ) {
var xge = parseInt( (x*100)/coords.width );

View File

@ -2,6 +2,7 @@
xhtmlHeaders(__FILE__, translate('Login') );
?>
<body>
<?php echo getNavBarHTML(); ?>
<div class="container">
<form class="center-block" name="loginForm" id="loginForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="action" value="login"/>
@ -15,7 +16,7 @@ xhtmlHeaders(__FILE__, translate('Login') );
<div id="loginform">
<h1>ZoneMinder <?php echo translate('Login') ?></h1>
<h1><?php echo ZM_WEB_TITLE . ' ' . translate('Login') ?></h1>
<label for="inputUsername" class="sr-only"><?php echo translate('Username') ?></label>
<input type="text" id="inputUsername" name="username" class="form-control" placeholder="Username" required autofocus />

View File

@ -25,7 +25,7 @@ xhtmlHeaders(__FILE__, translate('Logout') );
<body>
<div id="page">
<div id="header">
<h1>ZoneMinder <?php echo translate('Logout') ?></h1>
<h1><?php echo ZM_WEB_TITLE . ' ' . translate('Logout') ?></h1>
</div>
<div id="content">
<form name="contentForm" id="contentForm" method="post" action="<?php echo $_SERVER['PHP_SELF'] ?>">

View File

@ -463,7 +463,6 @@ $savejpegopts = array(
'Frames only' => 1,
'Analysis images only (if available)' => 2,
'Frames + Analysis images (if available)' => 3,
'Snapshot Only' => 4
);
$videowriteropts = array(

View File

@ -19,20 +19,20 @@
//
if ( !canEdit( 'System' ) ) {
$view = 'error';
return;
$view = 'error';
return;
}
if ( $_REQUEST['id'] ) {
if ( !($newStorage = dbFetchOne('SELECT * FROM Storage WHERE Id=?', NULL, ARRAY($_REQUEST['id'])) ) ) {
$view = 'error';
return;
if ( !($newStorage = dbFetchOne('SELECT * FROM Storage WHERE Id=?', NULL, ARRAY($_REQUEST['id'])) ) ) {
$view = 'error';
return;
$newStorage['ServerId'] = '';
}
}
} else {
$newStorage = array();
$newStorage['Name'] = translate('NewStorage');
$newStorage['Path'] = '';
$newStorage = array();
$newStorage['Name'] = translate('NewStorage');
$newStorage['Path'] = '';
$newStorage['Type'] = 'local';
$newStorage['Scheme'] = 'Medium';
}
@ -44,7 +44,7 @@ $scheme_options = array(
'Shallow' => translate('Shallow'),
);
$servers = Server::find_all();
$servers = Server::find_all( null, array('order'=>'lower(Name)') );
$ServersById = array();
foreach ( $servers as $S ) {
$ServersById[$S->Id()] = $S;
@ -75,7 +75,7 @@ xhtmlHeaders(__FILE__, translate('Storage')." - ".$newStorage['Name'] );
</tr>
<tr>
<th scope="row"><?php echo translate('Server') ?></th>
<td><?php echo htmlSelect( 'newStorage[ServerId]', array('','Remote') + $ServersById, $newStorage['ServerId'] ); ?></td>
<td><?php echo htmlSelect( 'newStorage[ServerId]', array(''=>'Remote / No Specific Server') + $ServersById, $newStorage['ServerId'] ); ?></td>
</tr>
<tr>
<th scope="row"><?php echo translate('Type') ?></th>