Merge branch 'master' into fix_token_auth_sessions
This commit is contained in:
commit
0ec6e8d635
|
@ -562,8 +562,8 @@ sub CopyTo {
|
||||||
return 'Old Storage path changed, Event has moved somewhere else.';
|
return 'Old Storage path changed, Event has moved somewhere else.';
|
||||||
}
|
}
|
||||||
|
|
||||||
$$self{Storage} = $NewStorage;
|
$NewPath .= $self->Relative_Path();
|
||||||
( $NewPath ) = ( $self->Path(undef) =~ /^(.*)$/ ); # De-taint
|
$NewPath = ( $NewPath =~ /^(.*)$/ ); # De-taint
|
||||||
if ( $NewPath eq $OldPath ) {
|
if ( $NewPath eq $OldPath ) {
|
||||||
$ZoneMinder::Database::dbh->commit();
|
$ZoneMinder::Database::dbh->commit();
|
||||||
return "New path and old path are the same! $NewPath";
|
return "New path and old path are the same! $NewPath";
|
||||||
|
@ -685,7 +685,7 @@ sub MoveTo {
|
||||||
|
|
||||||
# Succeeded in copying all files, so we may now update the Event.
|
# Succeeded in copying all files, so we may now update the Event.
|
||||||
$$self{StorageId} = $$NewStorage{Id};
|
$$self{StorageId} = $$NewStorage{Id};
|
||||||
$$self{Storage} = $NewStorage;
|
$self->Storage($NewStorage);
|
||||||
$error .= $self->save();
|
$error .= $self->save();
|
||||||
if ( $error ) {
|
if ( $error ) {
|
||||||
$ZoneMinder::Database::dbh->commit();
|
$ZoneMinder::Database::dbh->commit();
|
||||||
|
|
|
@ -68,7 +68,7 @@ void zmLoadConfig() {
|
||||||
if ( ! staticConfig.SERVER_NAME.empty() ) {
|
if ( ! staticConfig.SERVER_NAME.empty() ) {
|
||||||
|
|
||||||
Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() );
|
Debug( 1, "Fetching ZM_SERVER_ID For Name = %s", staticConfig.SERVER_NAME.c_str() );
|
||||||
std::string sql = stringtf("SELECT Id FROM Servers WHERE Name='%s'", staticConfig.SERVER_NAME.c_str() );
|
std::string sql = stringtf("SELECT `Id` FROM `Servers` WHERE `Name`='%s'", staticConfig.SERVER_NAME.c_str() );
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( dbrow.fetch( sql.c_str() ) ) {
|
if ( dbrow.fetch( sql.c_str() ) ) {
|
||||||
staticConfig.SERVER_ID = atoi(dbrow[0]);
|
staticConfig.SERVER_ID = atoi(dbrow[0]);
|
||||||
|
@ -79,7 +79,7 @@ void zmLoadConfig() {
|
||||||
} // end if has SERVER_NAME
|
} // end if has SERVER_NAME
|
||||||
} else if ( staticConfig.SERVER_NAME.empty() ) {
|
} else if ( staticConfig.SERVER_NAME.empty() ) {
|
||||||
Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID );
|
Debug( 1, "Fetching ZM_SERVER_NAME For Id = %d", staticConfig.SERVER_ID );
|
||||||
std::string sql = stringtf("SELECT Name FROM Servers WHERE Id='%d'", staticConfig.SERVER_ID );
|
std::string sql = stringtf("SELECT `Name` FROM `Servers` WHERE `Id`='%d'", staticConfig.SERVER_ID );
|
||||||
|
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( dbrow.fetch( sql.c_str() ) ) {
|
if ( dbrow.fetch( sql.c_str() ) ) {
|
||||||
|
|
|
@ -44,9 +44,9 @@
|
||||||
bool EventStream::loadInitialEventData(int monitor_id, time_t event_time) {
|
bool EventStream::loadInitialEventData(int monitor_id, time_t event_time) {
|
||||||
static char sql[ZM_SQL_SML_BUFSIZ];
|
static char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql), "SELECT Id FROM Events WHERE "
|
snprintf(sql, sizeof(sql), "SELECT `Id` FROM `Events` WHERE "
|
||||||
"MonitorId = %d AND unix_timestamp(EndTime) > %ld "
|
"`MonitorId` = %d AND unix_timestamp(`EndTime`) > %ld "
|
||||||
"ORDER BY Id ASC LIMIT 1", monitor_id, event_time);
|
"ORDER BY `Id` ASC LIMIT 1", monitor_id, event_time);
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
|
@ -115,9 +115,9 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT MonitorId, StorageId, Frames, unix_timestamp( StartTime ) AS StartTimestamp, "
|
"SELECT `MonitorId`, `StorageId`, `Frames`, unix_timestamp( `StartTime` ) AS StartTimestamp, "
|
||||||
"(SELECT max(Delta)-min(Delta) FROM Frames WHERE EventId=Events.Id) AS Duration, "
|
"(SELECT max(`Delta`)-min(`Delta`) FROM `Frames` WHERE `EventId`=`Events.Id`) AS Duration, "
|
||||||
"DefaultVideo, Scheme, SaveJPEGs FROM Events WHERE Id = %" PRIu64, event_id);
|
"`DefaultVideo`, `Scheme`, `SaveJPEGs` FROM `Events` WHERE `Id` = %" PRIu64, event_id);
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
|
@ -210,8 +210,8 @@ bool EventStream::loadEventData(uint64_t event_id) {
|
||||||
Debug(3, "fps set by frame_count(%d)/duration(%f)",
|
Debug(3, "fps set by frame_count(%d)/duration(%f)",
|
||||||
event_data->frame_count, event_data->duration);
|
event_data->frame_count, event_data->duration);
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql), "SELECT FrameId, unix_timestamp(`TimeStamp`), Delta "
|
snprintf(sql, sizeof(sql), "SELECT `FrameId`, unix_timestamp(`TimeStamp`), `Delta` "
|
||||||
"FROM Frames WHERE EventId = %" PRIu64 " ORDER BY FrameId ASC", event_id);
|
"FROM `Frames` WHERE `EventId` = %" PRIu64 " ORDER BY `FrameId` ASC", event_id);
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
exit(mysql_errno(&dbconn));
|
exit(mysql_errno(&dbconn));
|
||||||
|
@ -542,11 +542,11 @@ void EventStream::checkEventLoaded() {
|
||||||
|
|
||||||
if ( curr_frame_id <= 0 ) {
|
if ( curr_frame_id <= 0 ) {
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT Id FROM Events WHERE MonitorId = %ld AND Id < %" PRIu64 " ORDER BY Id DESC LIMIT 1",
|
"SELECT `Id` FROM `Events` WHERE `MonitorId` = %ld AND `Id` < %" PRIu64 " ORDER BY `Id` DESC LIMIT 1",
|
||||||
event_data->monitor_id, event_data->event_id);
|
event_data->monitor_id, event_data->event_id);
|
||||||
} else if ( (unsigned int)curr_frame_id > event_data->frame_count ) {
|
} else if ( (unsigned int)curr_frame_id > event_data->frame_count ) {
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT Id FROM Events WHERE MonitorId = %ld AND Id > %" PRIu64 " ORDER BY Id ASC LIMIT 1",
|
"SELECT `Id` FROM `Events` WHERE `MonitorId` = %ld AND `Id` > %" PRIu64 " ORDER BY `Id` ASC LIMIT 1",
|
||||||
event_data->monitor_id, event_data->event_id);
|
event_data->monitor_id, event_data->event_id);
|
||||||
} else {
|
} else {
|
||||||
// No event change required
|
// No event change required
|
||||||
|
|
|
@ -46,7 +46,7 @@ Group::Group(unsigned int p_id) {
|
||||||
|
|
||||||
if ( p_id ) {
|
if ( p_id ) {
|
||||||
char sql[ZM_SQL_SML_BUFSIZ];
|
char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
snprintf(sql, sizeof(sql), "SELECT Id, ParentId, Name FROM Group WHERE Id=%d", p_id);
|
snprintf(sql, sizeof(sql), "SELECT `Id`, `ParentId`, `Name` FROM `Group` WHERE `Id`=%d", p_id);
|
||||||
Debug(2,"Loading Group for %d using %s", p_id, sql);
|
Debug(2,"Loading Group for %d using %s", p_id, sql);
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( !dbrow.fetch(sql) ) {
|
if ( !dbrow.fetch(sql) ) {
|
||||||
|
|
|
@ -68,19 +68,19 @@
|
||||||
// This is the official SQL (and ordering of the fields) to load a Monitor.
|
// This is the official SQL (and ordering of the fields) to load a Monitor.
|
||||||
// It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended
|
// It will be used whereever a Monitor dbrow is needed. WHERE conditions can be appended
|
||||||
std::string load_monitor_sql =
|
std::string load_monitor_sql =
|
||||||
"SELECT Id, Name, ServerId, StorageId, Type, Function+0, Enabled, LinkedMonitors, "
|
"SELECT `Id`, `Name`, `ServerId`, `StorageId`, `Type`, `Function`+0, `Enabled`, `LinkedMonitors`, "
|
||||||
"AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS,"
|
"`AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`,"
|
||||||
"Device, Channel, Format, V4LMultiBuffer, V4LCapturesPerFrame, " // V4L Settings
|
"`Device`, `Channel`, `Format`, `V4LMultiBuffer`, `V4LCapturesPerFrame`, " // V4L Settings
|
||||||
"Protocol, Method, Options, User, Pass, Host, Port, Path, Width, Height, Colours, Palette, Orientation+0, Deinterlacing, "
|
"`Protocol`, `Method`, `Options`, `User`, `Pass`, `Host`, `Port`, `Path`, `Width`, `Height`, `Colours`, `Palette`, `Orientation`+0, `Deinterlacing`, "
|
||||||
"DecoderHWAccelName, DecoderHWAccelDevice, RTSPDescribe, "
|
"`DecoderHWAccelName`, `DecoderHWAccelDevice`, `RTSPDescribe`, "
|
||||||
"SaveJPEGs, VideoWriter, EncoderParameters, "
|
"`SaveJPEGs`, `VideoWriter`, `EncoderParameters`, "
|
||||||
//" OutputCodec, Encoder, OutputContainer, "
|
//" OutputCodec, Encoder, OutputContainer, "
|
||||||
"RecordAudio, "
|
"`RecordAudio`, "
|
||||||
"Brightness, Contrast, Hue, Colour, "
|
"`Brightness`, `Contrast`, `Hue`, `Colour`, "
|
||||||
"EventPrefix, LabelFormat, LabelX, LabelY, LabelSize,"
|
"`EventPrefix`, `LabelFormat`, `LabelX`, `LabelY`, `LabelSize`,"
|
||||||
"ImageBufferCount, WarmupCount, PreEventCount, PostEventCount, StreamReplayBuffer, AlarmFrameCount, "
|
"`ImageBufferCount`, `WarmupCount`, `PreEventCount`, `PostEventCount`, `StreamReplayBuffer`, `AlarmFrameCount`, "
|
||||||
"SectionLength, MinSectionLength, FrameSkip, MotionFrameSkip, "
|
"`SectionLength`, `MinSectionLength`, `FrameSkip`, `MotionFrameSkip`, "
|
||||||
"FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, Exif, SignalCheckPoints, SignalCheckColour FROM Monitors";
|
"`FPSReportInterval`, `RefBlendPerc`, `AlarmRefBlendPerc`, `TrackMotion`, `Exif`, `SignalCheckPoints`, `SignalCheckColour` FROM `Monitors`";
|
||||||
|
|
||||||
std::string CameraType_Strings[] = {
|
std::string CameraType_Strings[] = {
|
||||||
"Local",
|
"Local",
|
||||||
|
@ -1136,7 +1136,7 @@ void Monitor::DumpZoneImage(const char *zone_string) {
|
||||||
} else {
|
} else {
|
||||||
Debug(3, "Trying to load from event");
|
Debug(3, "Trying to load from event");
|
||||||
// Grab the most revent event image
|
// Grab the most revent event image
|
||||||
std::string sql = stringtf("SELECT MAX(Id) FROM Events WHERE MonitorId=%d AND Frames > 0", id);
|
std::string sql = stringtf("SELECT MAX(`Id`) FROM `Events` WHERE `MonitorId`=%d AND `Frames` > 0", id);
|
||||||
zmDbRow eventid_row;
|
zmDbRow eventid_row;
|
||||||
if ( eventid_row.fetch(sql.c_str()) ) {
|
if ( eventid_row.fetch(sql.c_str()) ) {
|
||||||
uint64_t event_id = atoll(eventid_row[0]);
|
uint64_t event_id = atoll(eventid_row[0]);
|
||||||
|
@ -1803,12 +1803,12 @@ void Monitor::Reload() {
|
||||||
static char sql[ZM_SQL_MED_BUFSIZ];
|
static char sql[ZM_SQL_MED_BUFSIZ];
|
||||||
// This seems to have fallen out of date.
|
// This seems to have fallen out of date.
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT Function+0, Enabled, LinkedMonitors, EventPrefix, LabelFormat, "
|
"SELECT `Function`+0, `Enabled`, `LinkedMonitors`, `EventPrefix`, `LabelFormat`, "
|
||||||
"LabelX, LabelY, LabelSize, WarmupCount, PreEventCount, PostEventCount, "
|
"`LabelX`, `LabelY`, `LabelSize`, `WarmupCount`, `PreEventCount`, `PostEventCount`, "
|
||||||
"AlarmFrameCount, SectionLength, MinSectionLength, FrameSkip, "
|
"`AlarmFrameCount`, `SectionLength`, `MinSectionLength`, `FrameSkip`, "
|
||||||
"MotionFrameSkip, AnalysisFPSLimit, AnalysisUpdateDelay, MaxFPS, AlarmMaxFPS, "
|
"`MotionFrameSkip`, `AnalysisFPSLimit`, `AnalysisUpdateDelay`, `MaxFPS`, `AlarmMaxFPS`, "
|
||||||
"FPSReportInterval, RefBlendPerc, AlarmRefBlendPerc, TrackMotion, "
|
"`FPSReportInterval`, `RefBlendPerc`, `AlarmRefBlendPerc`, `TrackMotion`, "
|
||||||
"SignalCheckColour FROM Monitors WHERE Id = '%d'", id);
|
"`SignalCheckColour` FROM `Monitors` WHERE `Id` = '%d'", id);
|
||||||
|
|
||||||
zmDbRow *row = zmDbFetchOne(sql);
|
zmDbRow *row = zmDbFetchOne(sql);
|
||||||
if ( !row ) {
|
if ( !row ) {
|
||||||
|
@ -2865,8 +2865,8 @@ std::vector<Group *> Monitor::Groups() {
|
||||||
// At the moment, only load groups once.
|
// At the moment, only load groups once.
|
||||||
if ( !groups.size() ) {
|
if ( !groups.size() ) {
|
||||||
std::string sql = stringtf(
|
std::string sql = stringtf(
|
||||||
"SELECT Id,ParentId,Name FROM Groups WHERE Groups.Id IN "
|
"SELECT `Id`, `ParentId`, `Name` FROM `Groups` WHERE `Groups.Id` IN "
|
||||||
"(SELECT GroupId FROM Groups_Monitors WHERE MonitorId=%d)",id);
|
"(SELECT `GroupId` FROM `Groups_Monitors` WHERE `MonitorId`=%d)",id);
|
||||||
MYSQL_RES *result = zmDbFetch(sql.c_str());
|
MYSQL_RES *result = zmDbFetch(sql.c_str());
|
||||||
if ( !result ) {
|
if ( !result ) {
|
||||||
Error("Can't load groups: %s", mysql_error(&dbconn));
|
Error("Can't load groups: %s", mysql_error(&dbconn));
|
||||||
|
|
|
@ -62,7 +62,7 @@ Storage::Storage( unsigned int p_id ) {
|
||||||
|
|
||||||
if ( p_id ) {
|
if ( p_id ) {
|
||||||
char sql[ZM_SQL_SML_BUFSIZ];
|
char sql[ZM_SQL_SML_BUFSIZ];
|
||||||
snprintf(sql, sizeof(sql), "SELECT Id, Name, Path, Type, Scheme FROM Storage WHERE Id=%d", p_id);
|
snprintf(sql, sizeof(sql), "SELECT `Id`, `Name`, `Path`, `Type`, `Scheme` FROM `Storage` WHERE `Id`=%d", p_id);
|
||||||
Debug(2,"Loading Storage for %d using %s", p_id, sql );
|
Debug(2,"Loading Storage for %d using %s", p_id, sql );
|
||||||
zmDbRow dbrow;
|
zmDbRow dbrow;
|
||||||
if ( !dbrow.fetch(sql) ) {
|
if ( !dbrow.fetch(sql) ) {
|
||||||
|
|
|
@ -99,8 +99,8 @@ User *zmLoadUser( const char *username, const char *password ) {
|
||||||
|
|
||||||
|
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds"
|
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`"
|
||||||
" FROM Users where Username = '%s' and Enabled = 1", safer_username );
|
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", safer_username );
|
||||||
|
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
|
@ -162,8 +162,8 @@ User *zmLoadTokenUser (std::string jwt_token_str, bool use_remote_addr ) {
|
||||||
if (username != "") {
|
if (username != "") {
|
||||||
char sql[ZM_SQL_MED_BUFSIZ] = "";
|
char sql[ZM_SQL_MED_BUFSIZ] = "";
|
||||||
snprintf(sql, sizeof(sql),
|
snprintf(sql, sizeof(sql),
|
||||||
"SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds, TokenMinExpiry"
|
"SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds`, `TokenMinExpiry`"
|
||||||
" FROM Users WHERE Username = '%s' and Enabled = 1", username.c_str() );
|
" FROM `Users` WHERE `Username` = '%s' AND `Enabled` = 1", username.c_str() );
|
||||||
|
|
||||||
if ( mysql_query(&dbconn, sql) ) {
|
if ( mysql_query(&dbconn, sql) ) {
|
||||||
Error("Can't run query: %s", mysql_error(&dbconn));
|
Error("Can't run query: %s", mysql_error(&dbconn));
|
||||||
|
@ -228,7 +228,7 @@ User *zmLoadAuthUser( const char *auth, bool use_remote_addr ) {
|
||||||
|
|
||||||
Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
|
Debug( 1, "Attempting to authenticate user from auth string '%s'", auth );
|
||||||
char sql[ZM_SQL_SML_BUFSIZ] = "";
|
char sql[ZM_SQL_SML_BUFSIZ] = "";
|
||||||
snprintf( sql, sizeof(sql), "SELECT Id, Username, Password, Enabled, Stream+0, Events+0, Control+0, Monitors+0, System+0, MonitorIds FROM Users WHERE Enabled = 1" );
|
snprintf( sql, sizeof(sql), "SELECT `Id`, `Username`, `Password`, `Enabled`, `Stream`+0, `Events`+0, `Control`+0, `Monitors`+0, `System`+0, `MonitorIds` FROM `Users` WHERE `Enabled` = 1" );
|
||||||
|
|
||||||
if ( mysql_query( &dbconn, sql ) ) {
|
if ( mysql_query( &dbconn, sql ) ) {
|
||||||
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
Error( "Can't run query: %s", mysql_error( &dbconn ) );
|
||||||
|
|
|
@ -21,38 +21,38 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$localSocketFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'w.sock';
|
$localSocketFile = ZM_PATH_SOCKS.'/zms-'.sprintf('%06d',$_REQUEST['connkey']).'w.sock';
|
||||||
if ( file_exists( $localSocketFile ) ) {
|
if ( file_exists($localSocketFile) ) {
|
||||||
ZM\Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
ZM\Warning("sock file $localSocketFile already exists?! Is someone else talking to zms?");
|
||||||
// They could be. We can maybe have concurrent requests from a browser.
|
// They could be. We can maybe have concurrent requests from a browser.
|
||||||
}
|
}
|
||||||
if ( !socket_bind( $socket, $localSocketFile ) ) {
|
if ( !socket_bind($socket, $localSocketFile) ) {
|
||||||
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()) );
|
ajaxError("socket_bind( $localSocketFile ) failed: ".socket_strerror(socket_last_error()));
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( $_REQUEST['command'] ) {
|
switch ( $_REQUEST['command'] ) {
|
||||||
case CMD_VARPLAY :
|
case CMD_VARPLAY :
|
||||||
ZM\Logger::Debug( 'Varplaying to '.$_REQUEST['rate'] );
|
ZM\Logger::Debug('Varplaying to '.$_REQUEST['rate']);
|
||||||
$msg = pack( 'lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768 );
|
$msg = pack('lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['rate']+32768);
|
||||||
break;
|
break;
|
||||||
case CMD_ZOOMIN :
|
case CMD_ZOOMIN :
|
||||||
ZM\Logger::Debug( 'Zooming to '.$_REQUEST['x'].','.$_REQUEST['y'] );
|
ZM\Logger::Debug('Zooming to '.$_REQUEST['x'].','.$_REQUEST['y']);
|
||||||
$msg = pack( 'lcnn', MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
|
$msg = pack('lcnn', MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y']);
|
||||||
break;
|
break;
|
||||||
case CMD_PAN :
|
case CMD_PAN :
|
||||||
ZM\Logger::Debug( 'Panning to '.$_REQUEST['x'].','.$_REQUEST['y'] );
|
ZM\Logger::Debug('Panning to '.$_REQUEST['x'].','.$_REQUEST['y']);
|
||||||
$msg = pack( 'lcnn', MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y'] );
|
$msg = pack('lcnn', MSG_CMD, $_REQUEST['command'], $_REQUEST['x'], $_REQUEST['y']);
|
||||||
break;
|
break;
|
||||||
case CMD_SCALE :
|
case CMD_SCALE :
|
||||||
ZM\Logger::Debug( 'Scaling to '.$_REQUEST['scale'] );
|
ZM\Logger::Debug('Scaling to '.$_REQUEST['scale']);
|
||||||
$msg = pack( 'lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['scale'] );
|
$msg = pack('lcn', MSG_CMD, $_REQUEST['command'], $_REQUEST['scale']);
|
||||||
break;
|
break;
|
||||||
case CMD_SEEK :
|
case CMD_SEEK :
|
||||||
ZM\Logger::Debug( 'Seeking to '.$_REQUEST['offset'] );
|
ZM\Logger::Debug('Seeking to '.$_REQUEST['offset']);
|
||||||
$msg = pack( 'lcN', MSG_CMD, $_REQUEST['command'], $_REQUEST['offset'] );
|
$msg = pack('lcN', MSG_CMD, $_REQUEST['command'], $_REQUEST['offset']);
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
ZM\Logger::Debug('Sending command ' . $_REQUEST['command']);
|
ZM\Logger::Debug('Sending command ' . $_REQUEST['command']);
|
||||||
$msg = pack( 'lc', MSG_CMD, $_REQUEST['command'] );
|
$msg = pack('lc', MSG_CMD, $_REQUEST['command']);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,8 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
// Pi can take up to 3 seconds for zms to start up.
|
// Pi can take up to 3 seconds for zms to start up.
|
||||||
$max_socket_tries = 1000;
|
$max_socket_tries = 1000;
|
||||||
// FIXME This should not exceed web_ajax_timeout
|
// FIXME This should not exceed web_ajax_timeout
|
||||||
while ( !file_exists($remSockFile) && $max_socket_tries-- ) { //sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
while ( !file_exists($remSockFile) && $max_socket_tries-- ) {
|
||||||
|
//sometimes we are too fast for our own good, if it hasn't been setup yet give it a second.
|
||||||
// WHY? We will just send another one...
|
// WHY? We will just send another one...
|
||||||
// ANSWER: Because otherwise we get a log of errors logged
|
// ANSWER: Because otherwise we get a log of errors logged
|
||||||
|
|
||||||
|
@ -71,27 +72,27 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
if ( !file_exists($remSockFile) ) {
|
if ( !file_exists($remSockFile) ) {
|
||||||
ajaxError("Socket $remSockFile does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/latest/faq.html#why-can-t-i-see-streamed-images-when-i-can-see-stills-in-the-zone-window-etc for more information.");
|
ajaxError("Socket $remSockFile does not exist. This file is created by zms, and since it does not exist, either zms did not run, or zms exited early. Please check your zms logs and ensure that CGI is enabled in apache and check that the PATH_ZMS is set correctly. Make sure that ZM is actually recording. If you are trying to view a live stream and the capture process (zmc) is not running then zms will exit. Please go to http://zoneminder.readthedocs.io/en/latest/faq.html#why-can-t-i-see-streamed-images-when-i-can-see-stills-in-the-zone-window-etc for more information.");
|
||||||
} else {
|
} else {
|
||||||
if ( !@socket_sendto( $socket, $msg, strlen($msg), 0, $remSockFile ) ) {
|
if ( !@socket_sendto($socket, $msg, strlen($msg), 0, $remSockFile) ) {
|
||||||
ajaxError( "socket_sendto( $remSockFile ) failed: ".socket_strerror(socket_last_error()) );
|
ajaxError("socket_sendto( $remSockFile ) failed: ".socket_strerror(socket_last_error()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rSockets = array( $socket );
|
$rSockets = array($socket);
|
||||||
$wSockets = NULL;
|
$wSockets = NULL;
|
||||||
$eSockets = NULL;
|
$eSockets = NULL;
|
||||||
|
|
||||||
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
$timeout = MSG_TIMEOUT - ( time() - $start_time );
|
||||||
|
|
||||||
$numSockets = socket_select( $rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000 );
|
$numSockets = socket_select($rSockets, $wSockets, $eSockets, intval($timeout/1000), ($timeout%1000)*1000);
|
||||||
|
|
||||||
if ( $numSockets === false ) {
|
if ( $numSockets === false ) {
|
||||||
ZM\Error('socket_select failed: ' . socket_strerror(socket_last_error()) );
|
ZM\Error('socket_select failed: ' . socket_strerror(socket_last_error()));
|
||||||
ajaxError( 'socket_select failed: '.socket_strerror(socket_last_error()) );
|
ajaxError('socket_select failed: '.socket_strerror(socket_last_error()));
|
||||||
} else if ( $numSockets < 0 ) {
|
} else if ( $numSockets < 0 ) {
|
||||||
ZM\Error( "Socket closed $remSockFile" );
|
ZM\Error("Socket closed $remSockFile");
|
||||||
ajaxError( "Socket closed $remSockFile" );
|
ajaxError("Socket closed $remSockFile");
|
||||||
} else if ( $numSockets == 0 ) {
|
} else if ( $numSockets == 0 ) {
|
||||||
ZM\Error( "Timed out waiting for msg $remSockFile" );
|
ZM\Error("Timed out waiting for msg $remSockFile");
|
||||||
socket_set_nonblock($socket);
|
socket_set_nonblock($socket);
|
||||||
#ajaxError("Timed out waiting for msg $remSockFile");
|
#ajaxError("Timed out waiting for msg $remSockFile");
|
||||||
} else if ( $numSockets > 0 ) {
|
} else if ( $numSockets > 0 ) {
|
||||||
|
@ -101,7 +102,7 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( $nbytes = @socket_recvfrom( $socket, $msg, MSG_DATA_SIZE, 0, $remSockFile ) ) {
|
switch( $nbytes = @socket_recvfrom($socket, $msg, MSG_DATA_SIZE, 0, $remSockFile) ) {
|
||||||
case -1 :
|
case -1 :
|
||||||
ajaxError("socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()));
|
ajaxError("socket_recvfrom( $remSockFile ) failed: ".socket_strerror(socket_last_error()));
|
||||||
break;
|
break;
|
||||||
|
@ -157,7 +158,7 @@ if ( sem_acquire($semaphore,1) !== false ) {
|
||||||
}
|
}
|
||||||
sem_release($semaphore);
|
sem_release($semaphore);
|
||||||
} else {
|
} else {
|
||||||
ZM\Logger::Debug("Couldn't get semaphore");
|
ZM\Logger::Debug('Couldn\'t get semaphore');
|
||||||
ajaxResponse(array());
|
ajaxResponse(array());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
define( 'DB_LOG_OFF', 0 );
|
define('DB_LOG_OFF', 0);
|
||||||
define( 'DB_LOG_ONLY', 1 );
|
define('DB_LOG_ONLY', 1);
|
||||||
define( 'DB_LOG_DEBUG', 2 );
|
define('DB_LOG_DEBUG', 2);
|
||||||
|
|
||||||
$GLOBALS['dbLogLevel'] = DB_LOG_OFF;
|
$GLOBALS['dbLogLevel'] = DB_LOG_OFF;
|
||||||
|
|
||||||
|
@ -29,10 +29,10 @@ $GLOBALS['dbConn'] = false;
|
||||||
function dbConnect() {
|
function dbConnect() {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
|
|
||||||
if (strpos(ZM_DB_HOST, ':')) {
|
if ( strpos(ZM_DB_HOST, ':') ) {
|
||||||
// Host variable may carry a port or socket.
|
// Host variable may carry a port or socket.
|
||||||
list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2);
|
list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2);
|
||||||
if (ctype_digit($portOrSocket)) {
|
if ( ctype_digit($portOrSocket) ) {
|
||||||
$socket = ':host='.$host . ';port='.$portOrSocket;
|
$socket = ':host='.$host . ';port='.$portOrSocket;
|
||||||
} else {
|
} else {
|
||||||
$socket = ':unix_socket='.$portOrSocket;
|
$socket = ':unix_socket='.$portOrSocket;
|
||||||
|
@ -43,22 +43,22 @@ function dbConnect() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$dbOptions = null;
|
$dbOptions = null;
|
||||||
if ( defined( 'ZM_DB_SSL_CA_CERT' ) and ZM_DB_SSL_CA_CERT ) {
|
if ( defined('ZM_DB_SSL_CA_CERT') and ZM_DB_SSL_CA_CERT ) {
|
||||||
$dbOptions = array(
|
$dbOptions = array(
|
||||||
PDO::MYSQL_ATTR_SSL_CA => ZM_DB_SSL_CA_CERT,
|
PDO::MYSQL_ATTR_SSL_CA => ZM_DB_SSL_CA_CERT,
|
||||||
PDO::MYSQL_ATTR_SSL_KEY => ZM_DB_SSL_CLIENT_KEY,
|
PDO::MYSQL_ATTR_SSL_KEY => ZM_DB_SSL_CLIENT_KEY,
|
||||||
PDO::MYSQL_ATTR_SSL_CERT => ZM_DB_SSL_CLIENT_CERT,
|
PDO::MYSQL_ATTR_SSL_CERT => ZM_DB_SSL_CLIENT_CERT,
|
||||||
);
|
);
|
||||||
$dbConn = new PDO( ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS, $dbOptions );
|
$dbConn = new PDO(ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS, $dbOptions);
|
||||||
} else {
|
} else {
|
||||||
$dbConn = new PDO( ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS );
|
$dbConn = new PDO(ZM_DB_TYPE . $socket . ';dbname='.ZM_DB_NAME, ZM_DB_USER, ZM_DB_PASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
$dbConn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
|
||||||
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
$dbConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
} catch(PDOException $ex ) {
|
} catch(PDOException $ex ) {
|
||||||
echo 'Unable to connect to ZM db.' . $ex->getMessage();
|
echo 'Unable to connect to ZM db.' . $ex->getMessage();
|
||||||
error_log('Unable to connect to ZM DB ' . $ex->getMessage() );
|
error_log('Unable to connect to ZM DB ' . $ex->getMessage());
|
||||||
$dbConn = null;
|
$dbConn = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,15 +89,15 @@ function dbDebug() {
|
||||||
dbLogDebug();
|
dbLogDebug();
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbLog( $sql, $update=false ) {
|
function dbLog($sql, $update=false) {
|
||||||
global $dbLogLevel;
|
global $dbLogLevel;
|
||||||
$noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG);
|
$noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG);
|
||||||
if ( $dbLogLevel > DB_LOG_OFF )
|
if ( $dbLogLevel > DB_LOG_OFF )
|
||||||
ZM\Logger::Debug( "SQL-LOG: $sql".($noExecute?" (not executed)":"") );
|
ZM\Logger::Debug( "SQL-LOG: $sql".($noExecute?' (not executed)':'') );
|
||||||
return( $noExecute );
|
return( $noExecute );
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbError( $sql ) {
|
function dbError($sql) {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
$error = $dbConn->errorInfo();
|
$error = $dbConn->errorInfo();
|
||||||
if ( ! $error[0] )
|
if ( ! $error[0] )
|
||||||
|
@ -110,37 +110,37 @@ function dbError( $sql ) {
|
||||||
|
|
||||||
function dbEscape( $string ) {
|
function dbEscape( $string ) {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
if ( version_compare( phpversion(), '4.3.0', '<') )
|
if ( version_compare(phpversion(), '4.3.0', '<'))
|
||||||
if ( get_magic_quotes_gpc() )
|
if ( get_magic_quotes_gpc() )
|
||||||
return( $dbConn->quote( stripslashes( $string ) ) );
|
return $dbConn->quote(stripslashes($string));
|
||||||
else
|
else
|
||||||
return( $dbConn->quote( $string ) );
|
return $dbConn->quote($string);
|
||||||
else
|
else
|
||||||
if ( get_magic_quotes_gpc() )
|
if ( get_magic_quotes_gpc() )
|
||||||
return( $dbConn->quote( stripslashes( $string ) ) );
|
return $dbConn->quote(stripslashes($string));
|
||||||
else
|
else
|
||||||
return( $dbConn->quote( $string ) );
|
return $dbConn->quote($string);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbQuery( $sql, $params=NULL ) {
|
function dbQuery($sql, $params=NULL) {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
if ( dbLog( $sql, true ) )
|
if ( dbLog($sql, true) )
|
||||||
return;
|
return;
|
||||||
$result = NULL;
|
$result = NULL;
|
||||||
try {
|
try {
|
||||||
if ( isset($params) ) {
|
if ( isset($params) ) {
|
||||||
if ( ! $result = $dbConn->prepare( $sql ) ) {
|
if ( ! $result = $dbConn->prepare($sql) ) {
|
||||||
ZM\Error("SQL: Error preparing $sql: " . $pdo->errorInfo);
|
ZM\Error("SQL: Error preparing $sql: " . $pdo->errorInfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! $result->execute( $params ) ) {
|
if ( ! $result->execute($params) ) {
|
||||||
ZM\Error("SQL: Error executing $sql: " . implode(',', $result->errorInfo() ) );
|
ZM\Error("SQL: Error executing $sql: " . implode(',', $result->errorInfo()));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ( defined('ZM_DB_DEBUG') ) {
|
if ( defined('ZM_DB_DEBUG') ) {
|
||||||
ZM\Logger::Debug("SQL: $sql values:" . ($params?implode(',',$params):'') );
|
ZM\Logger::Debug("SQL: $sql values:" . ($params?implode(',',$params):''));
|
||||||
}
|
}
|
||||||
$result = $dbConn->query($sql);
|
$result = $dbConn->query($sql);
|
||||||
if ( ! $result ) {
|
if ( ! $result ) {
|
||||||
|
@ -150,24 +150,24 @@ function dbQuery( $sql, $params=NULL ) {
|
||||||
}
|
}
|
||||||
if ( defined('ZM_DB_DEBUG') ) {
|
if ( defined('ZM_DB_DEBUG') ) {
|
||||||
if ( $params )
|
if ( $params )
|
||||||
ZM\Logger::Debug("SQL: $sql" . implode(',',$params) . ' rows: '.$result->rowCount() );
|
ZM\Logger::Debug("SQL: $sql" . implode(',',$params) . ' rows: '.$result->rowCount());
|
||||||
else
|
else
|
||||||
ZM\Logger::Debug("SQL: $sql: rows:" . $result->rowCount() );
|
ZM\Logger::Debug("SQL: $sql: rows:" . $result->rowCount());
|
||||||
}
|
}
|
||||||
} catch(PDOException $e) {
|
} catch(PDOException $e) {
|
||||||
ZM\Error( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):'') );
|
ZM\Error("SQL-ERR '".$e->getMessage()."', statement was '".$sql."' params:" . ($params?implode(',',$params):''));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchOne( $sql, $col=false, $params=NULL ) {
|
function dbFetchOne($sql, $col=false, $params=NULL) {
|
||||||
$result = dbQuery( $sql, $params );
|
$result = dbQuery($sql, $params);
|
||||||
if ( ! $result ) {
|
if ( !$result ) {
|
||||||
ZM\Error( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) );
|
ZM\Error("SQL-ERR dbFetchOne no result, statement was '".$sql."'".($params ? 'params: ' . join(',',$params) : ''));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ( ! $result->rowCount() ) {
|
if ( !$result->rowCount() ) {
|
||||||
# No rows is not an error
|
# No rows is not an error
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -185,103 +185,103 @@ function dbFetchOne( $sql, $col=false, $params=NULL ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchAll( $sql, $col=false, $params=NULL ) {
|
function dbFetchAll($sql, $col=false, $params=NULL) {
|
||||||
$result = dbQuery( $sql, $params );
|
$result = dbQuery($sql, $params);
|
||||||
if ( ! $result ) {
|
if ( ! $result ) {
|
||||||
ZM\Error( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) );
|
ZM\Error("SQL-ERR dbFetchAll no result, statement was '".$sql."'".($params ? 'params: '.join(',', $params) : ''));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbRows = array();
|
$dbRows = array();
|
||||||
while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) )
|
while ( $dbRow = $result->fetch(PDO::FETCH_ASSOC) )
|
||||||
$dbRows[] = $col?$dbRow[$col]:$dbRow;
|
$dbRows[] = $col ? $dbRow[$col] : $dbRow;
|
||||||
return $dbRows;
|
return $dbRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchAssoc( $sql, $indexCol, $dataCol=false ) {
|
function dbFetchAssoc($sql, $indexCol, $dataCol=false) {
|
||||||
$result = dbQuery( $sql );
|
$result = dbQuery($sql);
|
||||||
|
|
||||||
$dbRows = array();
|
$dbRows = array();
|
||||||
while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) )
|
while( $dbRow = $result->fetch(PDO::FETCH_ASSOC) )
|
||||||
$dbRows[$dbRow[$indexCol]] = $dataCol?$dbRow[$dataCol]:$dbRow;
|
$dbRows[$dbRow[$indexCol]] = $dataCol ? $dbRow[$dataCol] : $dbRow;
|
||||||
return( $dbRows );
|
return $dbRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetch( $sql, $col=false ) {
|
function dbFetch($sql, $col=false) {
|
||||||
return( dbFetchAll( $sql, $col ) );
|
return dbFetchAll($sql, $col);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchNext( $result, $col=false ) {
|
function dbFetchNext($result, $col=false) {
|
||||||
if ( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) )
|
if ( $dbRow = $result->fetch(PDO::FETCH_ASSOC) )
|
||||||
return( $col?$dbRow[$col]:$dbRow );
|
return $col ? $dbRow[$col] : $dbRow;
|
||||||
return( false );
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbNumRows( $sql ) {
|
function dbNumRows( $sql ) {
|
||||||
$result = dbQuery( $sql );
|
$result = dbQuery($sql);
|
||||||
return( $result->rowCount() );
|
return $result->rowCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbInsertId() {
|
function dbInsertId() {
|
||||||
global $dbConn;
|
global $dbConn;
|
||||||
return( $dbConn->lastInsertId() );
|
return $dbConn->lastInsertId();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEnumValues( $table, $column ) {
|
function getEnumValues($table, $column) {
|
||||||
$row = dbFetchOne( "describe $table $column" );
|
$row = dbFetchOne("DESCRIBE `$table` `$column`");
|
||||||
preg_match_all( "/'([^']+)'/", $row['Type'], $matches );
|
preg_match_all("/'([^']+)'/", $row['Type'], $matches);
|
||||||
return( $matches[1] );
|
return $matches[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSetValues( $table, $column ) {
|
function getSetValues($table, $column) {
|
||||||
return( getEnumValues( $table, $column ) );
|
return getEnumValues($table, $column);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUniqueValues( $table, $column, $asString=1 ) {
|
function getUniqueValues($table, $column, $asString=1) {
|
||||||
$values = array();
|
$values = array();
|
||||||
$sql = "select distinct $column from $table where (not isnull($column) and $column != '') order by $column";
|
$sql = "SELECT DISTINCT `$column` FROM `$table` WHERE (NOT isnull(`$column`) AND `$column` != '') ORDER BY `$column`";
|
||||||
foreach( dbFetchAll( $sql ) as $row ) {
|
foreach ( dbFetchAll($sql) as $row ) {
|
||||||
if ( $asString )
|
if ( $asString )
|
||||||
$values[$row[$column]] = $row[$column];
|
$values[$row[$column]] = $row[$column];
|
||||||
else
|
else
|
||||||
$values[] = $row[$column];
|
$values[] = $row[$column];
|
||||||
}
|
}
|
||||||
return( $values );
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTableColumns( $table, $asString=1 ) {
|
function getTableColumns( $table, $asString=1 ) {
|
||||||
$columns = array();
|
$columns = array();
|
||||||
$sql = "describe $table";
|
$sql = "DESCRIBE `$table`";
|
||||||
foreach( dbFetchAll( $sql ) as $row ) {
|
foreach ( dbFetchAll($sql) as $row ) {
|
||||||
if ( $asString )
|
if ( $asString )
|
||||||
$columns[$row['Field']] = $row['Type'];
|
$columns[$row['Field']] = $row['Type'];
|
||||||
else
|
else
|
||||||
$columns[] = $row['Type'];
|
$columns[] = $row['Type'];
|
||||||
}
|
}
|
||||||
return( $columns );
|
return $columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTableAutoInc( $table ) {
|
function getTableAutoInc( $table ) {
|
||||||
$row = dbFetchOne( 'show table status where Name=?', NULL, array($table) );
|
$row = dbFetchOne('SHOW TABLE status WHERE Name=?', NULL, array($table));
|
||||||
return( $row['Auto_increment'] );
|
return $row['Auto_increment'];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTableDescription( $table, $asString=1 ) {
|
function getTableDescription( $table, $asString=1 ) {
|
||||||
$columns = array();
|
$columns = array();
|
||||||
foreach( dbFetchAll( "describe $table" ) as $row ) {
|
foreach( dbFetchAll("DESCRIBE `$table`") as $row ) {
|
||||||
$desc = array(
|
$desc = array(
|
||||||
'name' => $row['Field'],
|
'name' => $row['Field'],
|
||||||
'required' => ($row['Null']=='NO')?true:false,
|
'required' => ($row['Null']=='NO')?true:false,
|
||||||
'default' => $row['Default'],
|
'default' => $row['Default'],
|
||||||
'db' => $row,
|
'db' => $row,
|
||||||
);
|
);
|
||||||
if ( preg_match( "/^varchar\((\d+)\)$/", $row['Type'], $matches ) ) {
|
if ( preg_match('/^varchar\((\d+)\)$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'text';
|
$desc['type'] = 'text';
|
||||||
$desc['typeAttrib'] = 'varchar';
|
$desc['typeAttrib'] = 'varchar';
|
||||||
$desc['maxLength'] = $matches[1];
|
$desc['maxLength'] = $matches[1];
|
||||||
} elseif ( preg_match( "/^(\w+)?text$/", $row['Type'], $matches ) ) {
|
} elseif ( preg_match('/^(\w+)?text$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'text';
|
$desc['type'] = 'text';
|
||||||
if (!empty($matches[1]) )
|
if ( !empty($matches[1]) )
|
||||||
$desc['typeAttrib'] = $matches[1];
|
$desc['typeAttrib'] = $matches[1];
|
||||||
switch ( $matches[1] ) {
|
switch ( $matches[1] ) {
|
||||||
case 'tiny' :
|
case 'tiny' :
|
||||||
|
@ -295,15 +295,15 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
//$desc['minLength'] = -128;
|
//$desc['minLength'] = -128;
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
ZM\Error( "Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" );
|
ZM\Error("Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} elseif ( preg_match( "/^(enum|set)\((.*)\)$/", $row['Type'], $matches ) ) {
|
} elseif ( preg_match('/^(enum|set)\((.*)\)$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'text';
|
$desc['type'] = 'text';
|
||||||
$desc['typeAttrib'] = $matches[1];
|
$desc['typeAttrib'] = $matches[1];
|
||||||
preg_match_all( "/'([^']+)'/", $matches[2], $matches );
|
preg_match_all("/'([^']+)'/", $matches[2], $matches);
|
||||||
$desc['values'] = $matches[1];
|
$desc['values'] = $matches[1];
|
||||||
} elseif ( preg_match( "/^(\w+)?int\(\d+\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) {
|
} elseif ( preg_match('/^(\w+)?int\(\d+\)(?:\s+(unsigned))?$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'integer';
|
$desc['type'] = 'integer';
|
||||||
switch ( $matches[1] ) {
|
switch ( $matches[1] ) {
|
||||||
case 'tiny' :
|
case 'tiny' :
|
||||||
|
@ -327,7 +327,7 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
//$desc['maxValue'] = 127;
|
//$desc['maxValue'] = 127;
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
ZM\Error( "Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" );
|
ZM\Error("Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( !empty($matches[1]) )
|
if ( !empty($matches[1]) )
|
||||||
|
@ -336,7 +336,7 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
$desc['maxValue'] += (-$desc['minValue']);
|
$desc['maxValue'] += (-$desc['minValue']);
|
||||||
$desc['minValue'] = 0;
|
$desc['minValue'] = 0;
|
||||||
}
|
}
|
||||||
} elseif ( preg_match( "/^(?:decimal|numeric)\((\d+)(?:,(\d+))?\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) {
|
} elseif ( preg_match('/^(?:decimal|numeric)\((\d+)(?:,(\d+))?\)(?:\s+(unsigned))?$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'fixed';
|
$desc['type'] = 'fixed';
|
||||||
$desc['range'] = $matches[1];
|
$desc['range'] = $matches[1];
|
||||||
if ( isset($matches[2]) )
|
if ( isset($matches[2]) )
|
||||||
|
@ -344,7 +344,7 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
else
|
else
|
||||||
$desc['precision'] = 0;
|
$desc['precision'] = 0;
|
||||||
$desc['unsigned'] = ( isset($matches[3]) && $matches[3] == 'unsigned' );
|
$desc['unsigned'] = ( isset($matches[3]) && $matches[3] == 'unsigned' );
|
||||||
} elseif ( preg_match( "/^(datetime|timestamp|date|time)$/", $row['Type'], $matches ) ) {
|
} elseif ( preg_match('/^(datetime|timestamp|date|time)$/', $row['Type'], $matches) ) {
|
||||||
$desc['type'] = 'datetime';
|
$desc['type'] = 'datetime';
|
||||||
switch ( $desc['typeAttrib'] = $matches[1] ) {
|
switch ( $desc['typeAttrib'] = $matches[1] ) {
|
||||||
case 'datetime' :
|
case 'datetime' :
|
||||||
|
@ -362,7 +362,7 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZM\Error( "Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'" );
|
ZM\Error("Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $asString )
|
if ( $asString )
|
||||||
|
@ -370,15 +370,6 @@ function getTableDescription( $table, $asString=1 ) {
|
||||||
else
|
else
|
||||||
$columns[] = $desc;
|
$columns[] = $desc;
|
||||||
}
|
}
|
||||||
return( $columns );
|
return $columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
function dbFetchMonitor( $mid ) {
|
|
||||||
return( dbFetchOne( 'select * from Monitors where Id = ?', NULL, array($mid) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
function dbFetchGroup( $gid ) {
|
|
||||||
return( dbFetchOne( 'select * from Groups where Id = ?', NULL, array($gid) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -23,34 +23,34 @@ if ( !canEdit('Monitors') ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$monitor = dbFetchMonitor($_REQUEST['mid']);
|
$monitor = ZM\Monitor::find_one(array('Id'=>$_REQUEST['mid']));
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, translate('Function').' - '.validHtmlStr($monitor['Name']));
|
xhtmlHeaders(__FILE__, translate('Function').' - '.validHtmlStr($monitor->Name()));
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<h2><?php echo translate('Function').' - '.validHtmlStr($monitor['Name']) ?></h2>
|
<h2><?php echo translate('Function').' - '.validHtmlStr($monitor->Name()) ?></h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||||
<input type="hidden" name="view" value="function"/>
|
<input type="hidden" name="view" value="function"/>
|
||||||
<input type="hidden" name="action" value="function"/>
|
<input type="hidden" name="action" value="function"/>
|
||||||
<input type="hidden" name="mid" value="<?php echo $monitor['Id'] ?>"/>
|
<input type="hidden" name="mid" value="<?php echo $monitor->Id() ?>"/>
|
||||||
<p>
|
<p>
|
||||||
<select name="newFunction">
|
<select name="newFunction">
|
||||||
<?php
|
<?php
|
||||||
foreach ( getEnumValues('Monitors', 'Function') as $optFunction ) {
|
foreach ( getEnumValues('Monitors', 'Function') as $optFunction ) {
|
||||||
?>
|
?>
|
||||||
<option value="<?php echo $optFunction ?>"<?php if ( $optFunction == $monitor['Function'] ) { ?> selected="selected"<?php } ?>><?php echo translate('Fn'.$optFunction) ?></option>
|
<option value="<?php echo $optFunction ?>"<?php if ( $optFunction == $monitor->Function() ) { ?> selected="selected"<?php } ?>><?php echo translate('Fn'.$optFunction) ?></option>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
</select>
|
</select>
|
||||||
<label for="newEnabled"><?php echo translate('Enabled') ?></label>
|
<label for="newEnabled"><?php echo translate('Enabled') ?></label>
|
||||||
<input type="checkbox" name="newEnabled" id="newEnabled" value="1"<?php if ( !empty($monitor['Enabled']) ) { ?> checked="checked"<?php } ?>/>
|
<input type="checkbox" name="newEnabled" id="newEnabled" value="1"<?php if ( !empty($monitor->Enabled()) ) { ?> checked="checked"<?php } ?>/>
|
||||||
</p>
|
</p>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<button type="submit" value="Save"><?php echo translate('Save') ?></button>
|
<button type="submit" value="Save"><?php echo translate('Save') ?></button>
|
||||||
|
|
|
@ -19,23 +19,21 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
if ( !canView( 'Monitors' ) )
|
if ( !canView('Monitors') ) {
|
||||||
{
|
$view = 'error';
|
||||||
$view = "error";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$mid = validInt($_REQUEST['mid']);
|
$mid = validInt($_REQUEST['mid']);
|
||||||
$zid = !empty($_REQUEST['zid'])?validInt($_REQUEST['zid']):0;
|
$zid = !empty($_REQUEST['zid'])?validInt($_REQUEST['zid']):0;
|
||||||
|
|
||||||
|
|
||||||
if ( $zid > 0 ) {
|
if ( $zid > 0 ) {
|
||||||
$newZone = dbFetchOne( 'SELECT * FROM Zones WHERE MonitorId = ? AND Id = ?', NULL, array( $mid, $zid) );
|
$newZone = dbFetchOne('SELECT * FROM Zones WHERE MonitorId = ? AND Id = ?', NULL, array($mid, $zid));
|
||||||
} else {
|
} else {
|
||||||
$view = "error";
|
$view = 'error';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$monitor = dbFetchMonitor ( $mid );
|
$monitor = ZM\Monitor::find_one($mid);
|
||||||
// Only allow certain filename characters (not including a period) to prevent directory traversal.
|
// Only allow certain filename characters (not including a period) to prevent directory traversal.
|
||||||
$plugin = preg_replace('/[^-a-zA-Z0-9]/', '', $_REQUEST['pl']);
|
$plugin = preg_replace('/[^-a-zA-Z0-9]/', '', $_REQUEST['pl']);
|
||||||
|
|
||||||
|
@ -104,7 +102,7 @@ function pLang($name)
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<h2><?php echo translate('Monitor') ?> <?php echo $monitor['Name'] ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo validHtmlStr($plugin) ?></h2>
|
<h2><?php echo translate('Monitor') ?> <?php echo $monitor->Name() ?> - <?php echo translate('Zone') ?> <?php echo $newZone['Name'] ?> - <?php echo translate('Plugin') ?> <?php echo validHtmlStr($plugin) ?></h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<form name="pluginForm" id="pluginForm" method="post" action="?">
|
<form name="pluginForm" id="pluginForm" method="post" action="?">
|
||||||
|
@ -115,16 +113,14 @@ function pLang($name)
|
||||||
<input type="hidden" name="pl" value="<?php echo validHtmlStr($plugin) ?>"/>
|
<input type="hidden" name="pl" value="<?php echo validHtmlStr($plugin) ?>"/>
|
||||||
|
|
||||||
<div id="settingsPanel">
|
<div id="settingsPanel">
|
||||||
<table id="pluginSettings" cellspacing="0">
|
<table id="pluginSettings">
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php
|
<?php
|
||||||
foreach($pluginOptions as $name => $popt)
|
foreach($pluginOptions as $name => $popt) {
|
||||||
{
|
?>
|
||||||
?>
|
|
||||||
<tr><th scope="row"><?php echo pLang($name) ?></th>
|
<tr><th scope="row"><?php echo pLang($name) ?></th>
|
||||||
<?php
|
<?php
|
||||||
switch($popt['Type'])
|
switch($popt['Type']) {
|
||||||
{
|
|
||||||
case "checkbox":
|
case "checkbox":
|
||||||
echo "CHECKBOX";
|
echo "CHECKBOX";
|
||||||
break;
|
break;
|
||||||
|
@ -134,8 +130,7 @@ foreach($pluginOptions as $name => $popt)
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<select name="pluginOpt[<?php echo $popt['Name'] ?>]" id="pluginOpt[<?php echo $popt['Name'] ?>]">
|
<select name="pluginOpt[<?php echo $popt['Name'] ?>]" id="pluginOpt[<?php echo $popt['Name'] ?>]">
|
||||||
<?php
|
<?php
|
||||||
foreach($pchoices as $pchoice)
|
foreach($pchoices as $pchoice) {
|
||||||
{
|
|
||||||
$psel="";
|
$psel="";
|
||||||
if($popt['Value']==$pchoice)
|
if($popt['Value']==$pchoice)
|
||||||
$psel="selected";
|
$psel="selected";
|
||||||
|
|
|
@ -18,30 +18,29 @@
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
//
|
//
|
||||||
|
|
||||||
if ( !canView( 'Control' ) )
|
if ( !canView('Control') ) {
|
||||||
{
|
$view = 'error';
|
||||||
$view = "error";
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$monitor = dbFetchMonitor( $_REQUEST['mid'] );
|
$monitor = ZM\Monitor::find_one(array('Id'=>$_REQUEST['mid']));
|
||||||
|
|
||||||
$zmuCommand = getZmuCommand( " -m ".escapeshellarg($_REQUEST['mid'])." -B -C -H -O" );
|
$zmuCommand = getZmuCommand(' -m '.escapeshellarg($_REQUEST['mid']).' -B -C -H -O');
|
||||||
$zmuOutput = exec( $zmuCommand );
|
$zmuOutput = exec( $zmuCommand );
|
||||||
list( $brightness, $contrast, $hue, $colour ) = explode( ' ', $zmuOutput );
|
list($brightness, $contrast, $hue, $colour) = explode(' ', $zmuOutput);
|
||||||
|
|
||||||
$monitor['Brightness'] = $brightness;
|
$monitor->Brightness() = $brightness;
|
||||||
$monitor['Contrast'] = $contrast;
|
$monitor->Contrast() = $contrast;
|
||||||
$monitor['Hue'] = $hue;
|
$monitor->Hue() = $hue;
|
||||||
$monitor['Colour'] = $colour;
|
$monitor->Colour() = $colour;
|
||||||
|
|
||||||
$focusWindow = true;
|
$focusWindow = true;
|
||||||
|
|
||||||
xhtmlHeaders(__FILE__, validHtmlStr($monitor['Name'])." - ".translate('Settings') );
|
xhtmlHeaders(__FILE__, validHtmlStr($monitor->Name()).' - '.translate('Settings'));
|
||||||
?>
|
?>
|
||||||
<body>
|
<body>
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<div id="header">
|
<div id="header">
|
||||||
<h2><?php echo validHtmlStr($monitor['Name']) ?> - <?php echo translate('Settings') ?></h2>
|
<h2><?php echo validHtmlStr($monitor->Name()) ?> - <?php echo translate('Settings') ?></h2>
|
||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<form name="contentForm" id="contentForm" method="post" action="?">
|
<form name="contentForm" id="contentForm" method="post" action="?">
|
||||||
|
@ -52,24 +51,25 @@ xhtmlHeaders(__FILE__, validHtmlStr($monitor['Name'])." - ".translate('Settings'
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Brightness') ?></th>
|
<th scope="row"><?php echo translate('Brightness') ?></th>
|
||||||
<td><input type="text" name="newBrightness" value="<?php echo $monitor['Brightness'] ?>" size="8"<?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td><input type="number" name="newBrightness" value="<?php echo $monitor->Brightness() ?>" <?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Contrast') ?></th>
|
<th scope="row"><?php echo translate('Contrast') ?></th>
|
||||||
<td><input type="text" name="newContrast" value="<?php echo $monitor['Contrast'] ?>" size="8"<?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td><input type="number" name="newContrast" value="<?php echo $monitor->Contrast() ?>" <?php echo canView('Control') ? '' : ' disabled="disabled"' ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Hue') ?></th>
|
<th scope="row"><?php echo translate('Hue') ?></th>
|
||||||
<td><input type="text" name="newHue" value="<?php echo $monitor['Hue'] ?>" size="8"<?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td><input type="number" name="newHue" value="<?php echo $monitor->Hue() ?>" <?php echo canView('Control') ? '' : ' disabled="disabled"' ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="row"><?php echo translate('Colour') ?></th>
|
<th scope="row"><?php echo translate('Colour') ?></th>
|
||||||
<td><input type="text" name="newColour" value="<?php echo $monitor['Colour'] ?>" size="8"<?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/></td>
|
<td><input type="number" name="newColour" value="<?php echo $monitor->Colour() ?>" <?php echo canView('Control') ? '' : ' disabled="disabled"' ?>/></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div id="contentButtons">
|
<div id="contentButtons">
|
||||||
<input type="submit" value="<?php echo translate('Save') ?>"<?php if ( !canView( 'Control' ) ) { ?> disabled="disabled"<?php } ?>/><input type="button" value="<?php echo translate('Close') ?>" data-on-click="closeWindow"/>
|
<button type="submit" value="Save"<?php echo canView('Control') ? '' : ' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
|
||||||
|
<button type="button" value="Close" data-on-click="closeWindow"/><?php echo translate('Close') ?></button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue