Merge branch 'master' into storageareas
This commit is contained in:
commit
d4b59211cd
|
@ -186,6 +186,7 @@ CREATE TABLE `Events` (
|
|||
`Id` bigint unsigned NOT NULL auto_increment,
|
||||
`MonitorId` int(10) unsigned NOT NULL default '0',
|
||||
`StorageId` smallint(5) unsigned default 0,
|
||||
`SecondaryStorageId` smallint(5) unsigned default 0,
|
||||
`Name` varchar(64) NOT NULL default '',
|
||||
`Cause` varchar(32) NOT NULL default '',
|
||||
`StartTime` datetime default NULL,
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
--
|
||||
-- Add CopyTo action to Filters
|
||||
--
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Filters'
|
||||
AND column_name = 'AutoCopy'
|
||||
) > 0,
|
||||
"SELECT 'Column AutoCopy already exists in Filters'",
|
||||
"ALTER TABLE Filters ADD `AutoCopy` tinyint(3) unsigned NOT NULL default '0' AFTER `AutoMove`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Filters'
|
||||
AND column_name = 'AutoCopyTo'
|
||||
) > 0,
|
||||
"SELECT 'Column AutoCopyTo already exists in Filters'",
|
||||
"ALTER TABLE Filters ADD `AutoCopyTo` smallint(5) unsigned NOT NULL default '0' AFTER `AutoCopy`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Filters'
|
||||
AND column_name = 'Query_json'
|
||||
) > 0,
|
||||
"SELECT 'Column Query_json already exists in Filters'",
|
||||
"ALTER TABLE `Filters` Change `Query` `Query_json` text NOT NULL"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
||||
|
||||
SET @s = (SELECT IF(
|
||||
(SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema = DATABASE()
|
||||
AND table_name = 'Events'
|
||||
AND column_name = 'SecondaryStorageId'
|
||||
) > 0,
|
||||
"SELECT 'Column SecondaryStorageId already exists in Events'",
|
||||
"ALTER TABLE `Events` ADD `SecondaryStorageId` smallint(5) unsigned default 0 AFTER `StorageId`"
|
||||
));
|
||||
|
||||
PREPARE stmt FROM @s;
|
||||
EXECUTE stmt;
|
|
@ -189,11 +189,17 @@ Add the following to the bottom of the file
|
|||
::
|
||||
|
||||
# Backports repository
|
||||
deb http://httpredir.debian.org/debian jessie-backports main contrib non-free
|
||||
deb http://archive.debian.org/debian/ jessie-backports main contrib non-free
|
||||
|
||||
CTRL+o and <Enter> to save
|
||||
CTRL+x to exit
|
||||
|
||||
Run the following
|
||||
|
||||
::
|
||||
|
||||
echo 'Acquire::Check-Valid-Until no;' > /etc/apt/apt.conf.d/99no-check-valid-until
|
||||
|
||||
**Step 5:** Install ZoneMinder
|
||||
|
||||
::
|
||||
|
|
|
@ -41,6 +41,7 @@ require Number::Bytes::Human;
|
|||
require Date::Parse;
|
||||
require POSIX;
|
||||
use Date::Format qw(time2str);
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
|
||||
#our @ISA = qw(ZoneMinder::Object);
|
||||
use parent qw(ZoneMinder::Object);
|
||||
|
@ -63,6 +64,7 @@ $serial = $primary_key = 'Id';
|
|||
Id
|
||||
MonitorId
|
||||
StorageId
|
||||
SecondaryStorageId
|
||||
Name
|
||||
Cause
|
||||
StartTime
|
||||
|
@ -163,7 +165,8 @@ sub RelativePath {
|
|||
if ( $event->Time() ) {
|
||||
$$event{RelativePath} = join('/',
|
||||
$event->{MonitorId},
|
||||
POSIX::strftime( '%y/%m/%d/%H/%M/%S',
|
||||
POSIX::strftime(
|
||||
'%y/%m/%d/%H/%M/%S',
|
||||
localtime($event->Time())
|
||||
),
|
||||
);
|
||||
|
@ -203,7 +206,8 @@ sub LinkPath {
|
|||
if ( $event->Time() ) {
|
||||
$$event{LinkPath} = join('/',
|
||||
$event->{MonitorId},
|
||||
POSIX::strftime( '%y/%m/%d',
|
||||
POSIX::strftime(
|
||||
'%y/%m/%d',
|
||||
localtime($event->Time())
|
||||
),
|
||||
'.'.$$event{Id}
|
||||
|
@ -282,10 +286,10 @@ sub GenerateVideo {
|
|||
$file_scale =~ s/_00//;
|
||||
$file_scale =~ s/(_\d+)0+$/$1/;
|
||||
$file_scale = 's'.$file_scale;
|
||||
push( @file_parts, $file_scale );
|
||||
push @file_parts, $file_scale;
|
||||
} elsif ( $size ) {
|
||||
my $file_size = 'S'.$size;
|
||||
push( @file_parts, $file_size );
|
||||
push @file_parts, $file_size;
|
||||
}
|
||||
my $video_file = join('-', $video_name, $file_parts[0], $file_parts[1] ).'.'.$format;
|
||||
if ( $overwrite || !-s $video_file ) {
|
||||
|
@ -393,7 +397,11 @@ sub delete {
|
|||
sub delete_files {
|
||||
my $event = shift;
|
||||
|
||||
my $Storage = @_ ? $_[0] : new ZoneMinder::Storage($$event{StorageId});
|
||||
foreach my $Storage (
|
||||
@_ ? ($_[0]) : (
|
||||
new ZoneMinder::Storage($$event{StorageId}),
|
||||
( $$event{SecondaryStorageId} ? new ZoneMinder::Storage($$event{SecondaryStorageId}) : () ),
|
||||
) ) {
|
||||
my $storage_path = $Storage->Path();
|
||||
|
||||
if ( ! $storage_path ) {
|
||||
|
@ -438,7 +446,7 @@ sub delete_files {
|
|||
my $command = "/bin/rm -rf $storage_path/$event_path";
|
||||
ZoneMinder::General::executeShellCommand($command);
|
||||
}
|
||||
}
|
||||
} # end if event_path
|
||||
|
||||
if ( $event->Scheme() eq 'Deep' ) {
|
||||
my $link_path = $event->LinkPath();
|
||||
|
@ -447,7 +455,8 @@ sub delete_files {
|
|||
( $link_path ) = ( $link_path =~ /^(.*)$/ ); # De-taint
|
||||
unlink($storage_path.'/'.$link_path) or Error("Unable to unlink '$storage_path/$link_path': $!");
|
||||
}
|
||||
}
|
||||
} # end if Scheme eq Deep
|
||||
} # end foreach Storage
|
||||
} # end sub delete_files
|
||||
|
||||
sub StorageId {
|
||||
|
@ -519,7 +528,7 @@ sub DiskSpace {
|
|||
return $_[0]{DiskSpace};
|
||||
}
|
||||
|
||||
sub MoveTo {
|
||||
sub CopyTo {
|
||||
my ( $self, $NewStorage ) = @_;
|
||||
|
||||
my $OldStorage = $self->Storage(undef);
|
||||
|
@ -531,9 +540,9 @@ sub MoveTo {
|
|||
# We do this before bothering to lock the event
|
||||
my ( $NewPath ) = ( $NewStorage->Path() =~ /^(.*)$/ ); # De-taint
|
||||
if ( ! $$NewStorage{Id} ) {
|
||||
return "New storage does not have an id. Moving will not happen.";
|
||||
return 'New storage does not have an id. Moving will not happen.';
|
||||
} elsif ( $$NewStorage{Id} == $$self{StorageId} ) {
|
||||
return "Event is already located at " . $NewPath;
|
||||
return 'Event is already located at ' . $NewPath;
|
||||
} elsif ( !$NewPath ) {
|
||||
return "New path ($NewPath) is empty.";
|
||||
} elsif ( ! -e $NewPath ) {
|
||||
|
@ -545,7 +554,7 @@ sub MoveTo {
|
|||
# data is reloaded, so need to check that the move hasn't already happened.
|
||||
if ( $$self{StorageId} == $$NewStorage{Id} ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "Event has already been moved by someone else.";
|
||||
return 'Event has already been moved by someone else.';
|
||||
}
|
||||
|
||||
if ( $$OldStorage{Id} != $$self{StorageId} ) {
|
||||
|
@ -559,7 +568,7 @@ sub MoveTo {
|
|||
$ZoneMinder::Database::dbh->commit();
|
||||
return "New path and old path are the same! $NewPath";
|
||||
}
|
||||
Debug("Moving event $$self{Id} from $OldPath to $NewPath");
|
||||
Debug("Copying event $$self{Id} from $OldPath to $NewPath");
|
||||
|
||||
my $moved = 0;
|
||||
|
||||
|
@ -580,7 +589,7 @@ sub MoveTo {
|
|||
}
|
||||
|
||||
my $event_path = 'events/'.$self->RelativePath();
|
||||
Info("Making dir ectory $event_path/");
|
||||
Debug("Making directory $event_path/");
|
||||
if ( ! $bucket->add_key( $event_path.'/','' ) ) {
|
||||
die "Unable to add key for $event_path/";
|
||||
}
|
||||
|
@ -590,7 +599,7 @@ Debug("Files to move @files");
|
|||
for my $file (@files) {
|
||||
next if $file =~ /^\./;
|
||||
( $file ) = ( $file =~ /^(.*)$/ ); # De-taint
|
||||
my $starttime = time;
|
||||
my $starttime = [gettimeofday];
|
||||
Debug("Moving file $file to $NewPath");
|
||||
my $size = -s $file;
|
||||
if ( ! $size ) {
|
||||
|
@ -605,7 +614,7 @@ Debug("Files to move @files");
|
|||
if ( ! $bucket->add_key($filename, $file_contents) ) {
|
||||
die "Unable to add key for $filename";
|
||||
}
|
||||
my $duration = time - $starttime;
|
||||
my $duration = tv_interval($starttime);
|
||||
Debug('PUT to S3 ' . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . Number::Bytes::Human::format_bytes($duration?$size/$duration:$size) . '/sec');
|
||||
} # end foreach file.
|
||||
|
||||
|
@ -636,21 +645,21 @@ Debug("Files to move @files");
|
|||
my @files = glob("$OldPath/*");
|
||||
if ( ! @files ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
return "No files to move.";
|
||||
return 'No files to move.';
|
||||
}
|
||||
|
||||
for my $file (@files) {
|
||||
next if $file =~ /^\./;
|
||||
( $file ) = ( $file =~ /^(.*)$/ ); # De-taint
|
||||
my $starttime = time;
|
||||
my $starttime = [gettimeofday];
|
||||
Debug("Moving file $file to $NewPath");
|
||||
my $size = -s $file;
|
||||
if ( ! File::Copy::copy( $file, $NewPath ) ) {
|
||||
$error .= "Copy failed: for $file to $NewPath: $!";
|
||||
last;
|
||||
}
|
||||
my $duration = time - $starttime;
|
||||
Debug("Copied " . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . ($duration?Number::Bytes::Human::format_bytes($size/$duration):'inf') . "/sec");
|
||||
my $duration = tv_interval($starttime);
|
||||
Debug('Copied ' . Number::Bytes::Human::format_bytes($size) . " in $duration seconds = " . ($duration?Number::Bytes::Human::format_bytes($size/$duration):'inf') . '/sec');
|
||||
} # end foreach file.
|
||||
} # end if ! moved
|
||||
|
||||
|
@ -658,6 +667,15 @@ Debug("Files to move @files");
|
|||
$ZoneMinder::Database::dbh->commit();
|
||||
return $error;
|
||||
}
|
||||
} # end sub CopyTo
|
||||
|
||||
sub MoveTo {
|
||||
|
||||
my ( $self, $NewStorage ) = @_;
|
||||
my $OldStorage = $self->Storage(undef);
|
||||
|
||||
my $error = $self->CopyTo($NewStorage);
|
||||
return $error if $error;
|
||||
|
||||
# Succeeded in copying all files, so we may now update the Event.
|
||||
$$self{StorageId} = $$NewStorage{Id};
|
||||
|
@ -667,10 +685,8 @@ Debug("Files to move @files");
|
|||
$ZoneMinder::Database::dbh->commit();
|
||||
return $error;
|
||||
}
|
||||
Debug("Committing");
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
$self->delete_files($OldStorage);
|
||||
Debug("Done deleting files, returning");
|
||||
return $error;
|
||||
} # end sub MoveTo
|
||||
|
||||
|
|
|
@ -132,11 +132,13 @@ sub Sql {
|
|||
my $self = shift;
|
||||
$$self{Sql} = shift if @_;
|
||||
if ( ! $$self{Sql} ) {
|
||||
if ( !$self->{Query} ) {
|
||||
Warning('No Query in filter.');
|
||||
$self->{Sql} = '';
|
||||
if ( ! $self->{Query_json} ) {
|
||||
Warning("No query in Filter!");
|
||||
return;
|
||||
}
|
||||
my $filter_expr = ZoneMinder::General::jsonDecode($self->{Query});
|
||||
|
||||
my $filter_expr = ZoneMinder::General::jsonDecode($self->{Query_json});
|
||||
my $sql = 'SELECT E.*,
|
||||
unix_timestamp(E.StartTime) as Time,
|
||||
M.Name as MonitorName,
|
||||
|
@ -146,7 +148,6 @@ sub Sql {
|
|||
INNER JOIN Monitors as M on M.Id = E.MonitorId
|
||||
LEFT JOIN Storage as S on S.Id = E.StorageId
|
||||
';
|
||||
$self->{Sql} = '';
|
||||
|
||||
if ( $filter_expr->{terms} ) {
|
||||
foreach my $term ( @{$filter_expr->{terms}} ) {
|
||||
|
|
|
@ -46,56 +46,13 @@ use ZoneMinder::Database qw(:all);
|
|||
|
||||
use POSIX;
|
||||
|
||||
use vars qw/ $table $primary_key /;
|
||||
use vars qw/ $table $primary_key %fields/;
|
||||
$table = 'Storage';
|
||||
$primary_key = 'Id';
|
||||
#__PACKAGE__->table('Storage');
|
||||
#__PACKAGE__->primary_key('Id');
|
||||
%fields = map { $_ => $_ } qw( Id Name Path DoDelete ServerId Type Url DiskSpace Scheme );
|
||||
|
||||
sub find {
|
||||
shift if $_[0] eq 'ZoneMinder::Storage';
|
||||
my %sql_filters = @_;
|
||||
|
||||
my $sql = 'SELECT * FROM Storage';
|
||||
my @sql_filters;
|
||||
my @sql_values;
|
||||
|
||||
if ( exists $sql_filters{Id} ) {
|
||||
push @sql_filters , ' Id=? ';
|
||||
push @sql_values, $sql_filters{Id};
|
||||
}
|
||||
if ( exists $sql_filters{Name} ) {
|
||||
push @sql_filters , ' Name = ? ';
|
||||
push @sql_values, $sql_filters{Name};
|
||||
}
|
||||
if ( exists $sql_filters{ServerId} ) {
|
||||
push @sql_filters, ' ServerId = ?';
|
||||
push @sql_values, $sql_filters{ServerId};
|
||||
}
|
||||
|
||||
|
||||
$sql .= ' WHERE ' . join(' AND ', @sql_filters) if @sql_filters;
|
||||
$sql .= ' LIMIT ' . $sql_filters{limit} if $sql_filters{limit};
|
||||
|
||||
my $sth = $ZoneMinder::Database::dbh->prepare_cached( $sql )
|
||||
or Fatal( "Can't prepare '$sql': ".$ZoneMinder::Database::dbh->errstr() );
|
||||
my $res = $sth->execute( @sql_values )
|
||||
or Fatal( "Can't execute '$sql': ".$sth->errstr() );
|
||||
|
||||
my @results;
|
||||
|
||||
while( my $db_filter = $sth->fetchrow_hashref() ) {
|
||||
my $filter = new ZoneMinder::Storage( $$db_filter{Id}, $db_filter );
|
||||
push @results, $filter;
|
||||
} # end while
|
||||
Debug("SQL: $sql returned " . @results . ' results');
|
||||
return @results;
|
||||
}
|
||||
|
||||
sub find_one {
|
||||
my @results = find(@_);
|
||||
return $results[0] if @results;
|
||||
}
|
||||
|
||||
sub Path {
|
||||
if ( @_ > 1 ) {
|
||||
|
|
|
@ -240,6 +240,7 @@ sub getFilters {
|
|||
or AutoDelete = 1
|
||||
or UpdateDiskSpace = 1
|
||||
or AutoMove = 1
|
||||
or AutoCopy = 1
|
||||
) ORDER BY Name';
|
||||
my $sth = $dbh->prepare_cached($sql)
|
||||
or Fatal("Unable to prepare '$sql': ".$dbh->errstr());
|
||||
|
@ -283,6 +284,7 @@ sub checkFilter {
|
|||
($filter->{AutoMessage}?'message':()),
|
||||
($filter->{AutoExecute}?'execute':()),
|
||||
($filter->{AutoMove}?'move':()),
|
||||
($filter->{AutoCopy}?'copy':()),
|
||||
($filter->{UpdateDiskSpace}?'update disk space':()),
|
||||
),
|
||||
'returned' , scalar @Events , 'events',
|
||||
|
@ -343,6 +345,23 @@ sub checkFilter {
|
|||
$_ = $Event->MoveTo($NewStorage);
|
||||
Error($_) if $_;
|
||||
}
|
||||
if ( $filter->{AutoCopy} ) {
|
||||
# Copy To is different from MoveTo in that it JUST copies the files
|
||||
# So we still need to update the Event object with the new SecondaryStorageId
|
||||
my $NewStorage = ZoneMinder::Storage->find_one(Id=>$filter->{AutoCopyTo});
|
||||
if ( $NewStorage ) {
|
||||
$_ = $Event->CopyTo($NewStorage);
|
||||
if ( $_ ) {
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
Error($_);
|
||||
} else {
|
||||
$Event->save({SecondaryStorageId=>$$NewStorage{Id}});
|
||||
$ZoneMinder::Database::dbh->commit();
|
||||
}
|
||||
} else {
|
||||
Error("No storage area found for copy to operation. AutoCopyTo was $$filter{AutoCopyTo}");
|
||||
}
|
||||
} # end if AutoCopy
|
||||
|
||||
if ( $filter->{UpdateDiskSpace} ) {
|
||||
$ZoneMinder::Database::dbh->begin_work();
|
||||
|
@ -361,7 +380,7 @@ sub checkFilter {
|
|||
$ZoneMinder::Database::dbh->commit();
|
||||
} # end if UpdateDiskSpace
|
||||
} # end foreach event
|
||||
}
|
||||
} # end sub checkFilter
|
||||
|
||||
sub generateVideo {
|
||||
my $filter = shift;
|
||||
|
@ -623,7 +642,7 @@ sub substituteTags {
|
|||
my $Monitor = $Event->Monitor() if $need_monitor;
|
||||
|
||||
# Do we need the image information too?
|
||||
my $need_images = $text =~ /%(?:EPI1|EPIM|EI1|EIM|EI1A|EIMA)%/;
|
||||
my $need_images = $text =~ /%(?:EPI1|EPIM|EI1|EIM|EI1A|EIMA|EIMOD)%/;
|
||||
my $first_alarm_frame;
|
||||
my $max_alarm_frame;
|
||||
my $max_alarm_score = 0;
|
||||
|
|
|
@ -12,6 +12,7 @@ class Event {
|
|||
'Name',
|
||||
'MonitorId',
|
||||
'StorageId',
|
||||
'SecondaryStorageId',
|
||||
'Name',
|
||||
'Cause',
|
||||
'StartTime',
|
||||
|
@ -85,6 +86,19 @@ class Event {
|
|||
return $this->{'Storage'};
|
||||
}
|
||||
|
||||
public function SecondaryStorage( $new = null ) {
|
||||
if ( $new ) {
|
||||
$this->{'SecondaryStorage'} = $new;
|
||||
}
|
||||
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) ) {
|
||||
if ( isset($this->{'SecondaryStorageId'}) and $this->{'SecondaryStorageId'} )
|
||||
$this->{'SecondaryStorage'} = Storage::find_one(array('Id'=>$this->{'SecondaryStorageId'}));
|
||||
if ( ! ( array_key_exists('SecondaryStorage', $this) and $this->{'SecondaryStorage'} ) )
|
||||
$this->{'SecondaryStorage'} = new Storage(NULL);
|
||||
}
|
||||
return $this->{'SecondaryStorage'};
|
||||
}
|
||||
|
||||
public function Monitor() {
|
||||
if ( isset($this->{'MonitorId'}) ) {
|
||||
$Monitor = Monitor::find_one(array('Id'=>$this->{'MonitorId'}));
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<?php
|
||||
namespace ZM;
|
||||
require_once('Object.php');
|
||||
|
||||
class Filter {
|
||||
class Filter extends ZM_Object {
|
||||
protected static $table = 'Filters';
|
||||
|
||||
public $defaults = array(
|
||||
protected $defaults = array(
|
||||
'Id' => null,
|
||||
'Name' => '',
|
||||
'AutoExecute' => 0,
|
||||
|
@ -16,68 +18,55 @@ public $defaults = array(
|
|||
'AutoMessage' => 0,
|
||||
'AutoMove' => 0,
|
||||
'AutoMoveTo' => 0,
|
||||
'AutoCopy' => 0,
|
||||
'AutoCopyTo' => 0,
|
||||
'UpdateDiskSpace' => 0,
|
||||
'Background' => 0,
|
||||
'Concurrent' => 0,
|
||||
'limit' => 100,
|
||||
'Query' => array(),
|
||||
'sort_field' => ZM_WEB_EVENT_SORT_FIELD,
|
||||
'sort_asc' => ZM_WEB_EVENT_SORT_ORDER,
|
||||
'Query_json' => '',
|
||||
);
|
||||
|
||||
public function __construct( $IdOrRow=NULL ) {
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer($IdOrRow) or is_numeric($IdOrRow) ) {
|
||||
$row = dbFetchOne('SELECT * FROM Filters WHERE Id=?', NULL, array($IdOrRow));
|
||||
if ( ! $row ) {
|
||||
Error('Unable to load Filter record for Id=' . $IdOrRow);
|
||||
public function Query_json() {
|
||||
if ( func_num_args( ) ) {
|
||||
$this->{'Query_json'} = func_get_arg(0);;
|
||||
$this->{'Query'} = jsonDecode($this->{'Query_json'});
|
||||
}
|
||||
} elseif ( is_array($IdOrRow) ) {
|
||||
$row = $IdOrRow;
|
||||
} else {
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Error("Unknown argument passed to Filter Constructor from $file:$line)");
|
||||
Error("Unknown argument passed to Filter Constructor ($IdOrRow)");
|
||||
return;
|
||||
return $this->{'Query_json'};
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
public function Query() {
|
||||
if ( func_num_args( ) ) {
|
||||
$this->{'Query'} = func_get_arg(0);;
|
||||
$this->{'Query_json'} = jsonEncode($this->{'Query'});
|
||||
}
|
||||
if ( array_key_exists('Query', $this) and $this->{'Query'} ) {
|
||||
$this->{'Query'} = jsonDecode($this->{'Query'});
|
||||
if ( !array_key_exists('Query', $this) ) {
|
||||
if ( array_key_exists('Query_json', $this) and $this->{'Query_json'} ) {
|
||||
$this->{'Query'} = jsonDecode($this->{'Query_json'});
|
||||
} else {
|
||||
$this->{'Query'} = array();
|
||||
}
|
||||
}
|
||||
} // end function __construct
|
||||
|
||||
public function __call( $fn, array $args ) {
|
||||
if ( count( $args ) ) {
|
||||
$this->{$fn} = $args[0];
|
||||
}
|
||||
if ( array_key_exists( $fn, $this ) ) {
|
||||
return $this->{$fn};
|
||||
} else if ( array_key_exists( $fn, $this->defaults ) ) {
|
||||
$this->{$fn} = $this->defaults{$fn};
|
||||
return $this->{$fn};
|
||||
} else {
|
||||
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Warning( "Unknown function call Filter->$fn from $file:$line" );
|
||||
if ( !is_array($this->{'Query'}) ) {
|
||||
# Handle existence of both Query_json and Query in the row
|
||||
$this->{'Query'} = jsonDecode($this->{'Query_json'});
|
||||
}
|
||||
}
|
||||
return $this->{'Query'};
|
||||
}
|
||||
|
||||
public static function find( $parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find_one(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
public function terms( ) {
|
||||
if ( func_num_args() ) {
|
||||
$this->Query()['terms'] = func_get_arg(0);
|
||||
$Query = $this->Query();
|
||||
$Query['terms'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if ( isset( $this->Query()['terms'] ) ) {
|
||||
return $this->Query()['terms'];
|
||||
|
@ -88,106 +77,42 @@ public $defaults = array(
|
|||
// The following three fields are actually stored in the Query
|
||||
public function sort_field( ) {
|
||||
if ( func_num_args( ) ) {
|
||||
$this->Query()['sort_field'] = func_get_arg(0);
|
||||
$Query = $this->Query();
|
||||
$Query['sort_field'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if ( isset( $this->Query()['sort_field'] ) ) {
|
||||
return $this->{'Query'}['sort_field'];
|
||||
}
|
||||
return $this->defaults{'sort_field'};
|
||||
return ZM_WEB_EVENT_SORT_FIELD;
|
||||
#return $this->defaults{'sort_field'};
|
||||
}
|
||||
|
||||
public function sort_asc( ) {
|
||||
if ( func_num_args( ) ) {
|
||||
$this->{'Query'}['sort_asc'] = func_get_arg(0);
|
||||
$Query = $this->Query();
|
||||
$Query['sort_asc'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if ( isset( $this->Query()['sort_asc'] ) ) {
|
||||
return $this->{'Query'}['sort_asc'];
|
||||
}
|
||||
return $this->defaults{'sort_asc'};
|
||||
return ZM_WEB_EVENT_SORT_ORDER;
|
||||
#return $this->defaults{'sort_asc'};
|
||||
}
|
||||
|
||||
public function limit( ) {
|
||||
if ( func_num_args( ) ) {
|
||||
$this->{'Query'}['limit'] = func_get_arg(0);
|
||||
$Query = $this->Query();
|
||||
$Query['limit'] = func_get_arg(0);
|
||||
$this->Query($Query);
|
||||
}
|
||||
if ( isset( $this->Query()['limit'] ) )
|
||||
return $this->{'Query'}['limit'];
|
||||
return $this->defaults{'limit'};
|
||||
return 100;
|
||||
#return $this->defaults{'limit'};
|
||||
}
|
||||
|
||||
public static function find( $parameters = null, $options = null ) {
|
||||
$filters = array();
|
||||
$sql = 'SELECT * FROM Filters ';
|
||||
$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 ) {
|
||||
if ( isset($options['order']) ) {
|
||||
$sql .= ' ORDER BY ' . $options['order'];
|
||||
}
|
||||
if ( isset($options['limit']) ) {
|
||||
if ( is_integer($options['limit']) or ctype_digit($options['limit']) ) {
|
||||
$sql .= ' LIMIT ' . $options['limit'];
|
||||
} else {
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Error("Invalid value for limit(".$options['limit'].") passed to Filter::find from $file:$line");
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
$result = dbQuery($sql, $values);
|
||||
$results = $result->fetchALL(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Filter');
|
||||
foreach ( $results as $row => $obj ) {
|
||||
$filters[] = $obj;
|
||||
}
|
||||
return $filters;
|
||||
} # end find()
|
||||
|
||||
public static function find_one( $parameters = array() ) {
|
||||
$results = Filter::find($parameters, array('limit'=>1));
|
||||
if ( ! sizeof($results) ) {
|
||||
return;
|
||||
}
|
||||
return $results[0];
|
||||
} # end find_one()
|
||||
|
||||
public function delete() {
|
||||
dbQuery('DELETE FROM Filters WHERE Id=?', array($this->{'Id'}));
|
||||
} # end function delete()
|
||||
|
||||
public function set( $data ) {
|
||||
foreach ($data as $k => $v) {
|
||||
if ( is_array( $v ) ) {
|
||||
$this->{$k} = $v;
|
||||
} else if ( is_string( $v ) ) {
|
||||
$this->{$k} = trim( $v );
|
||||
} else if ( is_integer( $v ) ) {
|
||||
$this->{$k} = $v;
|
||||
} else if ( is_bool( $v ) ) {
|
||||
$this->{$k} = $v;
|
||||
} else {
|
||||
Error( "Unknown type $k => $v of var " . gettype( $v ) );
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
} # end function set
|
||||
|
||||
public function control($command, $server_id=null) {
|
||||
$Servers = $server_id ? Server::find(array('Id'=>$server_id)) : Server::find();
|
||||
if ( !count($Servers) and !$server_id ) {
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
<?php
|
||||
namespace ZM;
|
||||
require_once('database.php');
|
||||
|
||||
$object_cache = array();
|
||||
|
||||
class ZM_Object {
|
||||
|
||||
public function __construct($IdOrRow = NULL) {
|
||||
$class = get_class($this);
|
||||
global $object_cache;
|
||||
if ( ! isset($object_cache[$class]) )
|
||||
$object_cache[$class] = array();
|
||||
$cache = $object_cache[$class];
|
||||
|
||||
$table = $class::$table;
|
||||
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer($IdOrRow) or ctype_digit($IdOrRow) ) {
|
||||
$row = dbFetchOne("SELECT * FROM `$table` WHERE `Id`=?", NULL, array($IdOrRow));
|
||||
if ( !$row ) {
|
||||
Error("Unable to load $class record for Id=$IdOrRow");
|
||||
}
|
||||
} elseif ( is_array($IdOrRow) ) {
|
||||
$row = $IdOrRow;
|
||||
}
|
||||
} # end if isset($IdOrRow)
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
$cache[$row['Id']] = $this;
|
||||
} else {
|
||||
# Set defaults
|
||||
foreach ( $this->defaults as $k => $v ) $this->{$k} = $v;
|
||||
}
|
||||
}
|
||||
|
||||
public function __call($fn, array $args){
|
||||
if ( count($args) ) {
|
||||
$this->{$fn} = $args[0];
|
||||
}
|
||||
if ( array_key_exists($fn, $this) ) {
|
||||
return $this->{$fn};
|
||||
} else {
|
||||
if ( array_key_exists($fn, $this->defaults) ) {
|
||||
return $this->defaults{$fn};
|
||||
} else {
|
||||
$backTrace = debug_backtrace();
|
||||
Warning("Unknown function call Sensor->$fn from ".print_r($backTrace,true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static function _find($class, $parameters = null, $options = null ) {
|
||||
$table = $class::$table;
|
||||
$filters = array();
|
||||
$sql = "SELECT * FROM `$table` ";
|
||||
$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 ) {
|
||||
if ( isset($options['order']) ) {
|
||||
$sql .= ' ORDER BY ' . $options['order'];
|
||||
}
|
||||
if ( isset($options['limit']) ) {
|
||||
if ( is_integer($options['limit']) or ctype_digit($options['limit']) ) {
|
||||
$sql .= ' LIMIT ' . $options['limit'];
|
||||
} else {
|
||||
Error('Invalid value for limit('.$options['limit'].') passed to '.get_class()."::find from ".print_r($backTrace,true));
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
$rows = dbFetchAll($sql, NULL, $values);
|
||||
$results = array();
|
||||
if ( $rows ) {
|
||||
foreach ( $rows as $row ) {
|
||||
array_push($results , new $class($row));
|
||||
}
|
||||
}
|
||||
return $results;
|
||||
} # end public function find()
|
||||
|
||||
public static function _find_one($class, $parameters = array(), $options = array() ) {
|
||||
global $object_cache;
|
||||
if ( ! isset($object_cache[$class]) )
|
||||
$object_cache[$class] = array();
|
||||
$cache = $object_cache[$class];
|
||||
if (
|
||||
( count($parameters) == 1 ) and
|
||||
isset($parameters['Id']) and
|
||||
isset($cache[$parameters['Id']]) ) {
|
||||
return $cache[$parameters['Id']];
|
||||
}
|
||||
$options['limit'] = 1;
|
||||
$results = ZM_Object::_find($class, $parameters, $options);
|
||||
if ( ! sizeof($results) ) {
|
||||
return;
|
||||
}
|
||||
return $results[0];
|
||||
}
|
||||
|
||||
public static function Objects_Indexed_By_Id($class) {
|
||||
$results = array();
|
||||
foreach ( ZM_Object::_find($class, null, array('order'=>'lower(Name)')) as $Object ) {
|
||||
$results[$Object->Id()] = $Object;
|
||||
}
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function to_json() {
|
||||
$json = array();
|
||||
foreach ($this->defaults as $key => $value) {
|
||||
if ( is_callable(array($this, $key)) ) {
|
||||
$json[$key] = $this->$key();
|
||||
} else if ( array_key_exists($key, $this) ) {
|
||||
$json[$key] = $this->{$key};
|
||||
} else {
|
||||
$json[$key] = $this->defaults{$key};
|
||||
}
|
||||
}
|
||||
return json_encode($json);
|
||||
}
|
||||
|
||||
public function set($data) {
|
||||
foreach ( $data as $k => $v ) {
|
||||
if ( method_exists($this, $k) ) {
|
||||
$this->{$k}($v);
|
||||
} else {
|
||||
if ( is_array($v) ) {
|
||||
# perhaps should turn into a comma-separated string
|
||||
$this->{$k} = implode(',', $v);
|
||||
} else if ( is_string($v) ) {
|
||||
if ( $v == '' and array_key_exists($k, $this->defaults) ) {
|
||||
$this->{$k} = $this->defaults[$k];
|
||||
} else {
|
||||
$this->{$k} = trim($v);
|
||||
}
|
||||
} else if ( is_integer($v) ) {
|
||||
$this->{$k} = $v;
|
||||
} else if ( is_bool($v) ) {
|
||||
$this->{$k} = $v;
|
||||
} else if ( is_null($v) ) {
|
||||
$this->{$k} = $v;
|
||||
} else {
|
||||
Error( "Unknown type $k => $v of var " . gettype( $v ) );
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
} # end if method_exists
|
||||
} # end foreach $data as $k=>$v
|
||||
}
|
||||
|
||||
public function changes( $new_values ) {
|
||||
$changes = array();
|
||||
foreach ( $new_values as $field => $value ) {
|
||||
|
||||
if ( method_exists($this, $field) ) {
|
||||
$old_value = $this->$field();
|
||||
Logger::Debug("Checking method $field () ".print_r($old_value,true)." => " . print_r($value,true));
|
||||
if ( is_array($old_value) ) {
|
||||
$diff = array_recursive_diff($old_value, $value);
|
||||
Logger::Debug("Checking method $field () diff is".print_r($diff,true));
|
||||
if ( count($diff) ) {
|
||||
$changes[$field] = $value;
|
||||
}
|
||||
} else if ( $this->$field() != $value ) {
|
||||
$changes[$field] = $value;
|
||||
}
|
||||
} else if ( array_key_exists($field, $this) ) {
|
||||
Logger::Debug("Checking field $field => ".$this->{$field} . " ?= " .$value);
|
||||
if ( $this->{$field} != $value ) {
|
||||
$changes[$field] = $value;
|
||||
}
|
||||
} else if ( array_key_exists($field, $this->defaults) ) {
|
||||
|
||||
Logger::Debug("Checking default $field => ".$this->defaults[$field] . " " .$value);
|
||||
if ( $this->defaults[$field] != $value ) {
|
||||
$changes[$field] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
#if ( (!array_key_exists($field, $this)) or ( $this->{$field} != $new_values[$field] ) ) {
|
||||
#Logger::Debug("Checking default $field => $default_value changes becaause" . $new_values[$field].' != '.$new_values[$field]);
|
||||
#$changes[$field] = $new_values[$field];
|
||||
##} else if {
|
||||
#Logger::Debug("Checking default $field => $default_value changes becaause " . $new_values[$field].' != '.$new_values[$field]);
|
||||
##array_push( $changes, [$field=>$defaults[$field]] );
|
||||
#}
|
||||
#} else {
|
||||
#Logger::Debug("Checking default $field => $default_value not in new_values");
|
||||
#}
|
||||
} # end foreach default
|
||||
return $changes;
|
||||
} # end public function changes
|
||||
|
||||
public function save($new_values = null) {
|
||||
$class = get_class($this);
|
||||
$table = $class::$table;
|
||||
|
||||
if ( $new_values ) {
|
||||
Logger::Debug("New values" . print_r($new_values,true));
|
||||
$this->set($new_values);
|
||||
}
|
||||
|
||||
if ( $this->Id() ) {
|
||||
$fields = array_keys($this->defaults);
|
||||
$sql = 'UPDATE '.$table.' SET '.implode(', ', array_map(function($field) {return '`'.$field.'`=?';}, $fields )) . ' WHERE Id=?';
|
||||
$values = array_map(function($field){return $this->{$field};}, $fields);
|
||||
$values[] = $this->{'Id'};
|
||||
if ( dbQuery($sql, $values) )
|
||||
return true;
|
||||
} else {
|
||||
$fields = $this->defaults;
|
||||
unset($fields['Id']);
|
||||
|
||||
$sql = 'INSERT INTO '.$table.' ('.implode(', ', array_map(function($field) {return '`'.$field.'`';}, array_keys($fields))).') VALUES ('.implode(', ', array_map(function($field){return '?';}, array_values($fields))).')';
|
||||
$values = array_map(function($field){return $this->{$field};}, array_keys($fields));
|
||||
if ( dbQuery($sql, $values) ) {
|
||||
$this->{'Id'} = dbInsertId();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} // end function save
|
||||
|
||||
public function delete() {
|
||||
$class = get_class($this);
|
||||
$table = $class::$table;
|
||||
dbQuery("DELETE FROM $table WHERE Id=?", array($this->{'Id'}));
|
||||
if ( isset($object_cache[$class]) and isset($object_cache[$class][$this->{'Id'}]) )
|
||||
unset($object_cache[$class][$this->{'Id'}]);
|
||||
}
|
||||
|
||||
} # end class Sensor Action
|
||||
?>
|
|
@ -2,10 +2,11 @@
|
|||
namespace ZM;
|
||||
require_once('database.php');
|
||||
require_once('Event.php');
|
||||
require_once('Object.php');
|
||||
|
||||
$storage_cache = array();
|
||||
class Storage {
|
||||
private $defaults = array(
|
||||
class Storage extends ZM_Object {
|
||||
protected static $table = 'Storage';
|
||||
protected $defaults = array(
|
||||
'Id' => null,
|
||||
'Path' => '',
|
||||
'Name' => '',
|
||||
|
@ -16,31 +17,12 @@ class Storage {
|
|||
'ServerId' => 0,
|
||||
'DoDelete' => 1,
|
||||
);
|
||||
public static function find($parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
public function __construct( $IdOrRow = NULL ) {
|
||||
global $storage_cache;
|
||||
|
||||
$row = NULL;
|
||||
if ( $IdOrRow ) {
|
||||
if ( is_integer($IdOrRow) or is_numeric($IdOrRow) ) {
|
||||
$row = dbFetchOne('SELECT * FROM Storage WHERE Id=?', NULL, array($IdOrRow));
|
||||
if ( ! $row ) {
|
||||
Error('Unable to load Storage record for Id=' . $IdOrRow);
|
||||
}
|
||||
} else if ( is_array($IdOrRow) ) {
|
||||
$row = $IdOrRow;
|
||||
}
|
||||
}
|
||||
if ( $row ) {
|
||||
foreach ($row as $k => $v) {
|
||||
$this->{$k} = $v;
|
||||
}
|
||||
$storage_cache[$row['Id']] = $this;
|
||||
} else {
|
||||
$this->{'Name'} = '';
|
||||
$this->{'Path'} = '';
|
||||
$this->{'Type'} = 'local';
|
||||
}
|
||||
public static function find_one( $parameters = array(), $options = array() ) {
|
||||
return ZM_Object::_find_one(get_class(), $parameters, $options);
|
||||
}
|
||||
|
||||
public function Path() {
|
||||
|
@ -66,93 +48,6 @@ class Storage {
|
|||
return $this->{'Name'};
|
||||
}
|
||||
|
||||
public function __call( $fn, array $args= NULL ) {
|
||||
if ( count($args) ) {
|
||||
$this->{$fn} = $args[0];
|
||||
}
|
||||
if ( array_key_exists($fn, $this) )
|
||||
return $this->{$fn};
|
||||
|
||||
if ( array_key_exists($fn, $this->defaults) )
|
||||
return $this->defaults{$fn};
|
||||
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[0]['file'];
|
||||
$line = $backTrace[0]['line'];
|
||||
Warning("Unknown function call Storage->$fn from $file:$line");
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Warning("Unknown function call Storage->$fn from $file:$line");
|
||||
}
|
||||
|
||||
public static function find_one( $parameters = null, $options = null ) {
|
||||
global $storage_cache;
|
||||
if (
|
||||
( count($parameters) == 1 ) and
|
||||
isset($parameters['Id']) and
|
||||
isset($storage_cache[$parameters['Id']]) ) {
|
||||
return $storage_cache[$parameters['Id']];
|
||||
}
|
||||
|
||||
$results = Storage::find($parameters, $options);
|
||||
if ( count($results) > 1 ) {
|
||||
Error('Storage Returned more than 1');
|
||||
return $results[0];
|
||||
} else if ( count($results) ) {
|
||||
return $results[0];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static function find( $parameters = null, $options = null ) {
|
||||
$sql = 'SELECT * FROM Storage ';
|
||||
$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);
|
||||
} # end if parameters
|
||||
if ( $options ) {
|
||||
if ( isset($options['order']) ) {
|
||||
$sql .= ' ORDER BY ' . $options['order'];
|
||||
} # end if options
|
||||
if ( isset($options['limit']) ) {
|
||||
if ( is_integer($options['limit']) or ctype_digit($options['limit']) ) {
|
||||
$sql .= ' LIMIT ' . $option['limit'];
|
||||
} else {
|
||||
$backTrace = debug_backtrace();
|
||||
$file = $backTrace[1]['file'];
|
||||
$line = $backTrace[1]['line'];
|
||||
Error("Invalid value for limit(".$options['limit'].") passed to Control::find from $file:$line");
|
||||
return array();
|
||||
}
|
||||
} # end if limit
|
||||
} # end if options
|
||||
$storage_areas = array();
|
||||
$result = dbQuery($sql, $values);
|
||||
if ( $result ) {
|
||||
$results = $result->fetchALL();
|
||||
foreach ( $results as $row ) {
|
||||
$storage_areas[] = new Storage($row);
|
||||
}
|
||||
}
|
||||
return $storage_areas;
|
||||
} # end find()
|
||||
|
||||
public function disk_usage_percent() {
|
||||
$path = $this->Path();
|
||||
if ( ! $path ) {
|
||||
|
@ -226,18 +121,5 @@ class Storage {
|
|||
return $this->{'Server'};
|
||||
}
|
||||
|
||||
public function to_json() {
|
||||
$json = array();
|
||||
foreach ($this->defaults as $key => $value) {
|
||||
if ( is_callable(array($this, $key)) ) {
|
||||
$json[$key] = $this->$key();
|
||||
} else if ( array_key_exists($key, $this) ) {
|
||||
$json[$key] = $this->{$key};
|
||||
} else {
|
||||
$json[$key] = $this->defaults{$key};
|
||||
}
|
||||
}
|
||||
return json_encode($json);
|
||||
}
|
||||
} // end class Storage
|
||||
?>
|
||||
|
|
|
@ -51,11 +51,30 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
|||
$_REQUEST['filter']['Query']['sort_asc'] = validStr($_REQUEST['filter']['Query']['sort_asc']);
|
||||
$_REQUEST['filter']['Query']['limit'] = validInt($_REQUEST['filter']['Query']['limit']);
|
||||
if ( $action == 'execute' ) {
|
||||
$tempFilterName = '_TempFilter'.time();
|
||||
$sql .= ' Name = \''.$tempFilterName.'\'';
|
||||
} else {
|
||||
$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
||||
$_REQUEST['filter']['Name'] = '_TempFilter'.time();
|
||||
unset($_REQUEST['Id']);
|
||||
#$tempFilterName = '_TempFilter'.time();
|
||||
#$sql .= ' Name = \''.$tempFilterName.'\'';
|
||||
#} else {
|
||||
#$sql .= ' Name = '.dbEscape($_REQUEST['filter']['Name']);
|
||||
}
|
||||
|
||||
$_REQUEST['filter']['AutoCopy'] = empty($_REQUEST['filter']['AutoCopy']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoMove'] = empty($_REQUEST['filter']['AutoMove']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoArchive'] = empty($_REQUEST['filter']['AutoArchive']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoVideo'] = empty($_REQUEST['filter']['AutoVideo']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoUpload'] = empty($_REQUEST['filter']['AutoUpload']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoEmail'] = empty($_REQUEST['filter']['AutoEmail']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoMessage'] = empty($_REQUEST['filter']['AutoMessage']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoExecute'] = empty($_REQUEST['filter']['AutoExecute']) ? 0 : 1;
|
||||
$_REQUEST['filter']['AutoDelete'] = empty($_REQUEST['filter']['AutoDelete']) ? 0 : 1;
|
||||
$_REQUEST['filter']['UpdateDiskSpace'] = empty($_REQUEST['filter']['UpdateDiskSpace']) ? 0 : 1;
|
||||
$_REQUEST['filter']['Background'] = empty($_REQUEST['filter']['Background']) ? 0 : 1;
|
||||
$_REQUEST['filter']['Concurrent'] = empty($_REQUEST['filter']['Concurrent']) ? 0 : 1;
|
||||
$changes = $filter->changes($_REQUEST['filter']);
|
||||
ZM\Logger::Debug("Changes: " . print_r($changes,true));
|
||||
|
||||
if ( 0 ) {
|
||||
$sql .= ', Query = '.dbEscape(jsonEncode($_REQUEST['filter']['Query']));
|
||||
$sql .= ', AutoArchive = '.(!empty($_REQUEST['filter']['AutoArchive']) ? 1 : 0);
|
||||
$sql .= ', AutoVideo = '. ( !empty($_REQUEST['filter']['AutoVideo']) ? 1 : 0);
|
||||
|
@ -73,17 +92,25 @@ if ( isset($_REQUEST['object']) and ( $_REQUEST['object'] == 'filter' ) ) {
|
|||
$sql .= ', UpdateDiskSpace = '. ( !empty($_REQUEST['filter']['UpdateDiskSpace']) ? 1 : 0);
|
||||
$sql .= ', Background = '. ( !empty($_REQUEST['filter']['Background']) ? 1 : 0);
|
||||
$sql .= ', Concurrent = '. ( !empty($_REQUEST['filter']['Concurrent']) ? 1 : 0);
|
||||
}
|
||||
|
||||
if ( $_REQUEST['Id'] and ( $action == 'Save' ) ) {
|
||||
if ( 0 ) {
|
||||
dbQuery('UPDATE Filters SET '.$sql.' WHERE Id=?', array($_REQUEST['Id']));
|
||||
}
|
||||
$filter->save($changes);
|
||||
if ( $filter->Background() )
|
||||
$filter->control('stop');
|
||||
} else {
|
||||
# COuld be execute
|
||||
if ( 0 ) {
|
||||
dbQuery('INSERT INTO Filters SET'.$sql);
|
||||
$_REQUEST['Id'] = dbInsertId();
|
||||
$filter = new ZM\Filter($_REQUEST['Id']);
|
||||
}
|
||||
if ( !empty($_REQUEST['filter']['Background']) )
|
||||
$filter->save($changes);
|
||||
}
|
||||
if ( $filter->Background() )
|
||||
$filter->control('start');
|
||||
|
||||
if ( $action == 'execute' ) {
|
||||
|
|
|
@ -2518,4 +2518,45 @@ function format_duration($time, $separator=':') {
|
|||
return sprintf('%02d%s%02d%s%02d', floor($time/3600), $separator, ($time/60)%60, $separator, $time%60);
|
||||
}
|
||||
|
||||
function array_recursive_diff($aArray1, $aArray2) {
|
||||
$aReturn = array();
|
||||
|
||||
foreach ($aArray1 as $mKey => $mValue) {
|
||||
if ( array_key_exists($mKey, $aArray2) ) {
|
||||
if ( is_array($mValue) ) {
|
||||
$aRecursiveDiff = array_recursive_diff($mValue, $aArray2[$mKey]);
|
||||
if ( count($aRecursiveDiff) ) {
|
||||
$aReturn[$mKey] = $aRecursiveDiff;
|
||||
}
|
||||
} else {
|
||||
if ( $mValue != $aArray2[$mKey] ) {
|
||||
$aReturn[$mKey] = $mValue;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$aReturn[$mKey] = $mValue;
|
||||
}
|
||||
}
|
||||
# Now check for keys in array2 that are not in array1
|
||||
foreach ($aArray2 as $mKey => $mValue) {
|
||||
if ( array_key_exists($mKey, $aArray1) ) {
|
||||
# Already checked it... I think.
|
||||
#if ( is_array($mValue) ) {
|
||||
#$aRecursiveDiff = array_recursive_diff($mValue, $aArray2[$mKey]);
|
||||
#if ( count($aRecursiveDiff) ) {
|
||||
#$aReturn[$mKey] = $aRecursiveDiff;
|
||||
#}
|
||||
#} else {
|
||||
#if ( $mValue != $aArray2[$mKey] ) {
|
||||
#$aReturn[$mKey] = $mValue;
|
||||
#}
|
||||
#}
|
||||
} else {
|
||||
$aReturn[$mKey] = $mValue;
|
||||
}
|
||||
}
|
||||
|
||||
return $aReturn;
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
|
@ -132,6 +132,7 @@ $SLANG = array(
|
|||
'AttrMaxScore' => 'Max. Score',
|
||||
'AttrMonitorId' => 'Monitor Id',
|
||||
'AttrMonitorName' => 'Monitor Name',
|
||||
'AttrSecondaryStorageArea' => 'Secondary Storage Area',
|
||||
'AttrStorageArea' => 'Storage Area',
|
||||
'AttrFilterServer' => 'Server Filter is Running On',
|
||||
'AttrMonitorServer' => 'Server Monitor is Running On',
|
||||
|
@ -356,6 +357,7 @@ $SLANG = array(
|
|||
'FilterArchiveEvents' => 'Archive all matches',
|
||||
'FilterUpdateDiskSpace' => 'Update used disk space',
|
||||
'FilterDeleteEvents' => 'Delete all matches',
|
||||
'FilterCopyEvents' => 'Copy all matches',
|
||||
'FilterMoveEvents' => 'Move all matches',
|
||||
'FilterEmailEvents' => 'Email details of all matches',
|
||||
'FilterExecuteEvents' => 'Execute command on all matches',
|
||||
|
|
|
@ -134,7 +134,11 @@ if ( ! $Event->Id() ) {
|
|||
<span id="dataDuration" title="<?php echo translate('Duration') ?>"><?php echo $Event->Length().'s' ?></span>
|
||||
<span id="dataFrames" title="<?php echo translate('AttrFrames').'/'.translate('AttrAlarmFrames') ?>"><?php echo $Event->Frames() ?>/<?php echo $Event->AlarmFrames() ?></span>
|
||||
<span id="dataScore" title="<?php echo translate('AttrTotalScore').'/'.translate('AttrAvgScore').'/'.translate('AttrMaxScore') ?>"><?php echo $Event->TotScore() ?>/<?php echo $Event->AvgScore() ?>/<?php echo $Event->MaxScore() ?></span>
|
||||
<span id="Storage"> <?php echo human_filesize($Event->DiskSpace(null)) . ' on ' . $Event->Storage()->Name() ?></span>
|
||||
<span id="Storage">
|
||||
<?php echo
|
||||
human_filesize($Event->DiskSpace(null)) . ' on ' . $Event->Storage()->Name().
|
||||
( $Event->SecondaryStorageId() ? ', ' . $Event->SecondaryStorage()->Name() :'' )
|
||||
?></span>
|
||||
<div id="closeWindow"><a href="#" onclick="<?php echo $popup ? 'window.close()' : 'window.history.back();return false;' ?>"><?php echo $popup ? translate('Close') : translate('Back') ?></a></div>
|
||||
</div>
|
||||
<div id="menuBar1">
|
||||
|
|
|
@ -22,36 +22,35 @@ if ( !canView('Events') ) {
|
|||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
require_once 'includes/Filter.php';
|
||||
require_once('includes/Object.php');
|
||||
require_once('includes/Storage.php');
|
||||
require_once('includes/Filter.php');
|
||||
parseSort();
|
||||
|
||||
$filterNames = array(''=>translate('ChooseFilter'));
|
||||
$filter = NULL;
|
||||
|
||||
foreach ( dbFetchAll('SELECT * FROM Filters ORDER BY Name') as $row ) {
|
||||
$filterNames[$row['Id']] = $row['Id'] . ' ' . $row['Name'];
|
||||
if ( $row['Background'] )
|
||||
$filterNames[$row['Id']] .= '*';
|
||||
if ( $row['Concurrent'] )
|
||||
$filterNames[$row['Id']] .= '&';
|
||||
foreach ( ZM\Filter::find(null,array('order'=>'lower(Name)')) as $Filter ) {
|
||||
$filterNames[$Filter->Id()] = $Filter->Id() . ' ' . $Filter->Name();
|
||||
if ( $Filter->Background() )
|
||||
$filterNames[$Filter->Id()] .= '*';
|
||||
if ( $Filter->Concurrent() )
|
||||
$filterNames[$Filter->Id()] .= '&';
|
||||
|
||||
if ( isset($_REQUEST['Id']) && $_REQUEST['Id'] == $row['Id'] ) {
|
||||
$filter = new ZM\Filter($row);
|
||||
if ( isset($_REQUEST['Id']) && ($_REQUEST['Id'] == $Filter->Id()) ) {
|
||||
$filter = $Filter;
|
||||
}
|
||||
}
|
||||
if ( !$filter ) {
|
||||
$filter = new ZM\Filter();
|
||||
}
|
||||
|
||||
if ( isset($_REQUEST['sort_field']) && isset($_REQUEST['filter']) ) {
|
||||
$_REQUEST['filter']['Query']['sort_field'] = $_REQUEST['sort_field'];
|
||||
$_REQUEST['filter']['Query']['sort_asc'] = $_REQUEST['sort_asc'];
|
||||
$_REQUEST['filter']['Query']['limit'] = $_REQUEST['limit'];
|
||||
}
|
||||
ZM\Logger::Debug("Query: " . $filter->Query_json());
|
||||
ZM\Logger::Debug("Query: " . print_r($filter->Query(), true));
|
||||
|
||||
if ( isset($_REQUEST['filter']) ) {
|
||||
$filter->set($_REQUEST['filter']);
|
||||
# Update our filter object with whatever changes we have made before saving
|
||||
#$filter->set($_REQUEST['filter']);
|
||||
}
|
||||
|
||||
$conjunctionTypes = getFilterQueryConjunctionTypes();
|
||||
|
@ -98,6 +97,7 @@ $attrTypes = array(
|
|||
'DiskSpace' => translate('AttrDiskSpace'),
|
||||
'SystemLoad' => translate('AttrSystemLoad'),
|
||||
'StorageId' => translate('AttrStorageArea'),
|
||||
'SecondaryStorageId' => translate('AttrSecondaryStorageArea'),
|
||||
'ServerId' => translate('AttrMonitorServer'),
|
||||
'FilterServerId' => translate('AttrFilterServer'),
|
||||
'MonitorServerId' => translate('AttrMonitorServer'),
|
||||
|
@ -127,27 +127,24 @@ $archiveTypes = array(
|
|||
|
||||
$focusWindow = true;
|
||||
|
||||
$storageareas = array('' => 'All');
|
||||
//$storageareas[0] = 'Default ' . ZM_DIR_EVENTS;
|
||||
foreach ( dbFetchAll('SELECT Id,Name FROM Storage ORDER BY lower(Name) ASC') as $storage ) {
|
||||
$storageareas[$storage['Id']] = $storage['Name'];
|
||||
}
|
||||
$storageareas = array('' => 'All') + ZM\ZM_Object::Objects_Indexed_By_Id('ZM\Storage');
|
||||
|
||||
$weekdays = array();
|
||||
for ( $i = 0; $i < 7; $i++ ) {
|
||||
$weekdays[$i] = strftime('%A', mktime(12, 0, 0, 1, $i+1, 2001));
|
||||
}
|
||||
$states = array();
|
||||
foreach ( dbFetchAll('SELECT Id, Name FROM States ORDER BY lower(Name) ASC') as $state_row ) {
|
||||
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `States` ORDER BY lower(`Name`) ASC') as $state_row ) {
|
||||
$states[$state_row['Id']] = validHtmlStr($state_row['Name']);
|
||||
}
|
||||
$servers = array();
|
||||
$servers['ZM_SERVER_ID'] = 'Current Server';
|
||||
$servers['NULL'] = 'No Server';
|
||||
foreach ( dbFetchAll('SELECT Id, Name FROM Servers ORDER BY lower(Name) ASC') as $server ) {
|
||||
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Servers` ORDER BY lower(`Name`) ASC') as $server ) {
|
||||
$servers[$server['Id']] = validHtmlStr($server['Name']);
|
||||
}
|
||||
$monitors = array();
|
||||
foreach ( dbFetchAll('SELECT Id, Name FROM Monitors ORDER BY Name ASC') as $monitor ) {
|
||||
foreach ( dbFetchAll('SELECT `Id`, `Name` FROM `Monitors` ORDER BY lower(`Name`) ASC') as $monitor ) {
|
||||
if ( visibleMonitor($monitor['Id']) ) {
|
||||
$monitors[$monitor['Name']] = validHtmlStr($monitor['Name']);
|
||||
}
|
||||
|
@ -273,7 +270,7 @@ for ( $i=0; $i < count($terms); $i++ ) {
|
|||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $servers, $term['val']); ?></td>
|
||||
<?php
|
||||
} elseif ( $term['attr'] == 'StorageId' ) {
|
||||
} elseif ( ($term['attr'] == 'StorageId') || ($term['attr'] == 'SecondaryStorageId') ) {
|
||||
?>
|
||||
<td><?php echo htmlSelect("filter[Query][terms][$i][op]", $opTypes, $term['op']); ?></td>
|
||||
<td><?php echo htmlSelect("filter[Query][terms][$i][val]", $storageareas, $term['val']); ?></td>
|
||||
|
@ -391,7 +388,13 @@ if ( ZM_OPT_MESSAGE ) {
|
|||
<label><?php echo translate('FilterDeleteEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoDelete]" value="1"<?php if ( $filter->AutoDelete() ) { ?> checked="checked"<?php } ?> data-on-click-this="updateButtons"/>
|
||||
</p>
|
||||
<p><label><?php echo translate('FilterMoveEvents') ?></label>
|
||||
<p>
|
||||
<label><?php echo translate('FilterCopyEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoCopy]" value="1"<?php if ( $filter->AutoCopy() ) { ?> checked="checked"<?php } ?> data-on-click-this="click_autocopy"/>
|
||||
<?php echo htmlSelect('filter[AutoCopyTo]', $storageareas, $filter->AutoCopyTo(), $filter->AutoCopy() ? null : array('style'=>'display:none;')); ?>
|
||||
</p>
|
||||
<p>
|
||||
<label><?php echo translate('FilterMoveEvents') ?></label>
|
||||
<input type="checkbox" name="filter[AutoMove]" value="1"<?php if ( $filter->AutoMove() ) { ?> checked="checked"<?php } ?> data-on-click-this="click_automove"/>
|
||||
<?php echo htmlSelect('filter[AutoMoveTo]', $storageareas, $filter->AutoMoveTo(), $filter->AutoMove() ? null : array('style'=>'display:none;')); ?>
|
||||
</p>
|
||||
|
|
|
@ -72,6 +72,15 @@ function click_automove(element) {
|
|||
}
|
||||
}
|
||||
|
||||
function click_autocopy(element) {
|
||||
updateButtons(this);
|
||||
if ( this.checked ) {
|
||||
$j(this.form.elements['filter[AutoCopyTo]']).css('display', 'inline');
|
||||
} else {
|
||||
this.form.elements['filter[AutoCopyTo]'].hide();
|
||||
}
|
||||
}
|
||||
|
||||
function checkValue( element ) {
|
||||
var rows = $j(element).closest('tbody').children();
|
||||
parseRows(rows);
|
||||
|
@ -200,10 +209,10 @@ function parseRows(rows) {
|
|||
}
|
||||
var serverVal = inputTds.eq(4).children().val();
|
||||
inputTds.eq(4).html(serverSelect).children().val(serverVal).chosen({width: "101%"});
|
||||
} else if ( attr == 'StorageId' ) { //Choose by storagearea
|
||||
} else if ( (attr == 'StorageId') || (attr == 'SecondaryStorageId') ) { //Choose by storagearea
|
||||
var storageSelect = $j('<select></select>').attr('name', queryPrefix + rowNum + '][val]').attr('id', queryPrefix + rowNum + '][val]');
|
||||
for ( key in storageareas ) {
|
||||
storageSelect.append('<option value="' + key + '">' + storageareas[key] + '</option>');
|
||||
storageSelect.append('<option value="' + key + '">' + storageareas[key].Name + '</option>');
|
||||
}
|
||||
var storageVal = inputTds.eq(4).children().val();
|
||||
inputTds.eq(4).html(storageSelect).children().val(storageVal).chosen({width: "101%"});
|
||||
|
|
Loading…
Reference in New Issue