2013-03-17 07:45:21 +08:00
< ? php
//
// ZoneMinder web action file, $Date$, $Revision$
// Copyright (C) 2001-2008 Philip Coombes
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
2016-12-26 23:23:16 +08:00
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2013-03-17 07:45:21 +08:00
//
2015-08-30 03:13:15 +08:00
// PP - POST request handler for PHP which does not need extensions
// credit: http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/
2015-09-25 03:44:35 +08:00
2015-08-30 03:13:15 +08:00
function do_post_request ( $url , $data , $optional_headers = null )
{
$params = array ( 'http' => array (
'method' => 'POST' ,
'content' => $data
));
if ( $optional_headers !== null ) {
$params [ 'http' ][ 'header' ] = $optional_headers ;
}
$ctx = stream_context_create ( $params );
$fp = @ fopen ( $url , 'rb' , false , $ctx );
if ( ! $fp ) {
throw new Exception ( " Problem with $url , $php_errormsg " );
}
$response = @ stream_get_contents ( $fp );
if ( $response === false ) {
throw new Exception ( " Problem reading data from $url , $php_errormsg " );
}
return $response ;
}
2013-03-17 07:45:21 +08:00
function getAffectedIds ( $name )
{
$names = $name . " s " ;
$ids = array ();
if ( isset ( $_REQUEST [ $names ]) || isset ( $_REQUEST [ $name ]) )
{
if ( isset ( $_REQUEST [ $names ]) )
$ids = validInt ( $_REQUEST [ $names ]);
else if ( isset ( $_REQUEST [ $name ]) )
$ids [] = validInt ( $_REQUEST [ $name ]);
}
return ( $ids );
}
if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS && empty ( $user ) && ! empty ( $_REQUEST [ 'auth' ]) )
{
if ( $authUser = getAuthUser ( $_REQUEST [ 'auth' ] ) )
{
userLogin ( $authUser [ 'Username' ], $authUser [ 'Password' ], true );
}
}
if ( ! empty ( $action ) )
{
2015-09-25 23:11:15 +08:00
if ( $action == " login " && isset ( $_REQUEST [ 'username' ]) && ( ZM_AUTH_TYPE == " remote " || isset ( $_REQUEST [ 'password' ]) ) )
{
// if true, a popup will display after login
2015-09-25 03:44:35 +08:00
// PP - lets validate reCaptcha if it exists
if ( defined ( 'ZM_OPT_USE_GOOG_RECAPTCHA' )
&& defined ( 'ZM_OPT_GOOG_RECAPTCHA_SECRETKEY' )
&& defined ( 'ZM_OPT_GOOG_RECAPTCHA_SITEKEY' )
&& ZM_OPT_USE_GOOG_RECAPTCHA && ZM_OPT_GOOG_RECAPTCHA_SECRETKEY
&& ZM_OPT_GOOG_RECAPTCHA_SITEKEY )
2015-08-30 01:29:52 +08:00
{
2015-08-30 03:13:15 +08:00
$url = 'https://www.google.com/recaptcha/api/siteverify' ;
$fields = array (
'secret' => ZM_OPT_GOOG_RECAPTCHA_SECRETKEY ,
'response' => $_REQUEST [ 'g-recaptcha-response' ],
'remoteip' => $_SERVER [ 'REMOTE_ADDR' ]
);
2015-09-01 08:39:28 +08:00
$res = do_post_request ( $url , http_build_query ( $fields ));
2015-09-25 03:44:35 +08:00
$responseData = json_decode ( $res , true );
// PP - credit: https://github.com/google/recaptcha/blob/master/src/ReCaptcha/Response.php
// if recaptcha resulted in error, we might have to deny login
if ( isset ( $responseData [ 'success' ]) && $responseData [ 'success' ] == false )
2015-09-01 08:39:28 +08:00
{
2015-09-25 03:44:35 +08:00
// PP - before we deny auth, let's make sure the error was not 'invalid secret'
// because that means the user did not configure the secret key correctly
// in this case, we prefer to let him login in and display a message to correct
// the key. Unfortunately, there is no way to check for invalid site key in code
// as it produces the same error as when you don't answer a recaptcha
if ( isset ( $responseData [ 'error-codes' ]) && is_array ( $responseData [ 'error-codes' ]))
{
if ( ! in_array ( 'invalid-input-secret' , $responseData [ 'error-codes' ]))
{
2015-09-25 23:11:15 +08:00
Error ( " reCaptcha authentication failed " );
2015-09-25 03:44:35 +08:00
userLogout ();
$view = 'login' ;
$refreshParent = true ;
}
else
{
//Let them login but show an error
2015-09-25 23:11:15 +08:00
echo '<script type="text/javascript">alert("' . translate ( 'RecaptchaWarning' ) . '"); </script>' ;
Error ( " Invalid recaptcha secret detected " );
2015-09-25 03:44:35 +08:00
}
}
2015-08-30 03:13:15 +08:00
}
2015-08-30 01:29:52 +08:00
}
2015-09-25 23:11:15 +08:00
}
2015-08-30 01:29:52 +08:00
2013-03-17 07:45:21 +08:00
// General scope actions
if ( $action == " login " && isset ( $_REQUEST [ 'username' ]) && ( ZM_AUTH_TYPE == " remote " || isset ( $_REQUEST [ 'password' ]) ) )
{
$username = validStr ( $_REQUEST [ 'username' ] );
$password = isset ( $_REQUEST [ 'password' ]) ? validStr ( $_REQUEST [ 'password' ]) : '' ;
userLogin ( $username , $password );
}
elseif ( $action == " logout " )
{
userLogout ();
$refreshParent = true ;
$view = 'none' ;
}
elseif ( $action == " bandwidth " && isset ( $_REQUEST [ 'newBandwidth' ]) )
{
$_COOKIE [ 'zmBandwidth' ] = validStr ( $_REQUEST [ 'newBandwidth' ]);
setcookie ( " zmBandwidth " , validStr ( $_REQUEST [ 'newBandwidth' ]), time () + 3600 * 24 * 30 * 12 * 10 );
$refreshParent = true ;
}
// Event scope actions, view permissions only required
if ( canView ( 'Events' ) )
{
if ( $action == " filter " )
{
if ( ! empty ( $_REQUEST [ 'subaction' ]) )
{
if ( $_REQUEST [ 'subaction' ] == " addterm " )
$_REQUEST [ 'filter' ] = addFilterTerm ( $_REQUEST [ 'filter' ], $_REQUEST [ 'line' ] );
elseif ( $_REQUEST [ 'subaction' ] == " delterm " )
$_REQUEST [ 'filter' ] = delFilterTerm ( $_REQUEST [ 'filter' ], $_REQUEST [ 'line' ] );
}
elseif ( canEdit ( 'Events' ) )
{
if ( ! empty ( $_REQUEST [ 'execute' ]) )
$tempFilterName = " _TempFilter " . time ();
if ( isset ( $tempFilterName ) )
$filterName = $tempFilterName ;
elseif ( ! empty ( $_REQUEST [ 'newFilterName' ]) )
$filterName = $_REQUEST [ 'newFilterName' ];
if ( ! empty ( $filterName ) )
{
$_REQUEST [ 'filter' ][ 'sort_field' ] = validStr ( $_REQUEST [ 'sort_field' ]);
$_REQUEST [ 'filter' ][ 'sort_asc' ] = validStr ( $_REQUEST [ 'sort_asc' ]);
$_REQUEST [ 'filter' ][ 'limit' ] = validInt ( $_REQUEST [ 'limit' ]);
2013-10-18 03:54:17 +08:00
$sql = " replace into Filters set Name = " . dbEscape ( $filterName ) . " , Query = " . dbEscape ( jsonEncode ( $_REQUEST [ 'filter' ]));
2016-05-27 23:11:30 +08:00
if ( ! empty ( $_REQUEST [ 'AutoArchive' ]) )
$sql .= " , AutoArchive = " . dbEscape ( $_REQUEST [ 'AutoArchive' ]);
if ( ! empty ( $_REQUEST [ 'AutoVideo' ]) )
$sql .= " , AutoVideo = " . dbEscape ( $_REQUEST [ 'AutoVideo' ]);
if ( ! empty ( $_REQUEST [ 'AutoUpload' ]) )
$sql .= " , AutoUpload = " . dbEscape ( $_REQUEST [ 'AutoUpload' ]);
if ( ! empty ( $_REQUEST [ 'AutoEmail' ]) )
$sql .= " , AutoEmail = " . dbEscape ( $_REQUEST [ 'AutoEmail' ]);
if ( ! empty ( $_REQUEST [ 'AutoMessage' ]) )
$sql .= " , AutoMessage = " . dbEscape ( $_REQUEST [ 'AutoMessage' ]);
if ( ! empty ( $_REQUEST [ 'AutoExecute' ]) && ! empty ( $_REQUEST [ 'AutoExecuteCmd' ]) )
$sql .= " , AutoExecute = " . dbEscape ( $_REQUEST [ 'AutoExecute' ]) . " , AutoExecuteCmd = " . dbEscape ( $_REQUEST [ 'AutoExecuteCmd' ]);
if ( ! empty ( $_REQUEST [ 'AutoDelete' ]) )
$sql .= " , AutoDelete = " . dbEscape ( $_REQUEST [ 'AutoDelete' ]);
2013-03-17 07:45:21 +08:00
if ( ! empty ( $_REQUEST [ 'background' ]) )
2013-10-18 03:54:17 +08:00
$sql .= " , Background = " . dbEscape ( $_REQUEST [ 'background' ]);
2013-03-17 07:45:21 +08:00
dbQuery ( $sql );
$refreshParent = true ;
}
}
}
}
// Event scope actions, edit permissions required
if ( canEdit ( 'Events' ) )
{
if ( $action == " rename " && isset ( $_REQUEST [ 'eventName' ]) && ! empty ( $_REQUEST [ 'eid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Events SET Name=? WHERE Id=?' , array ( $_REQUEST [ 'eventName' ], $_REQUEST [ 'eid' ] ) );
2013-03-17 07:45:21 +08:00
}
else if ( $action == " eventdetail " )
{
if ( ! empty ( $_REQUEST [ 'eid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?' , array ( $_REQUEST [ 'newEvent' ][ 'Cause' ], $_REQUEST [ 'newEvent' ][ 'Notes' ], $_REQUEST [ 'eid' ] ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
else
{
foreach ( getAffectedIds ( 'markEid' ) as $markEid )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?' , array ( $_REQUEST [ 'newEvent' ][ 'Cause' ], $_REQUEST [ 'newEvent' ][ 'Notes' ], $markEid ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
}
}
elseif ( $action == " archive " || $action == " unarchive " )
{
$archiveVal = ( $action == " archive " ) ? 1 : 0 ;
if ( ! empty ( $_REQUEST [ 'eid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Events SET Archived=? WHERE Id=?' , array ( $archiveVal , $_REQUEST [ 'eid' ]) );
2013-03-17 07:45:21 +08:00
}
else
{
foreach ( getAffectedIds ( 'markEid' ) as $markEid )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Events SET Archived=? WHERE Id=?' , array ( $archiveVal , $markEid ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
}
}
elseif ( $action == " delete " )
{
foreach ( getAffectedIds ( 'markEid' ) as $markEid )
{
deleteEvent ( $markEid );
$refreshParent = true ;
}
if ( ! empty ( $_REQUEST [ 'fid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'DELETE FROM Filters WHERE Name=?' , array ( $_REQUEST [ 'fid' ] ) );
2013-03-17 07:45:21 +08:00
//$refreshParent = true;
}
}
}
// Monitor control actions, require a monitor id and control view permissions for that monitor
if ( ! empty ( $_REQUEST [ 'mid' ]) && canView ( 'Control' , $_REQUEST [ 'mid' ] ) )
{
require_once ( 'control_functions.php' );
2015-12-09 22:23:36 +08:00
require_once ( 'Monitor.php' );
2013-03-17 07:45:21 +08:00
$mid = validInt ( $_REQUEST [ 'mid' ]);
if ( $action == " control " )
{
2015-12-09 22:23:36 +08:00
$monitor = new Monitor ( $mid );
2013-03-17 07:45:21 +08:00
$ctrlCommand = buildControlCommand ( $monitor );
2015-12-09 22:23:36 +08:00
sendControlCommand ( $monitor -> Id (), $ctrlCommand );
2013-03-17 07:45:21 +08:00
}
elseif ( $action == " settings " )
{
2014-06-06 03:14:12 +08:00
$args = " -m " . escapeshellarg ( $mid );
$args .= " -B " . escapeshellarg ( $_REQUEST [ 'newBrightness' ]);
$args .= " -C " . escapeshellarg ( $_REQUEST [ 'newContrast' ]);
$args .= " -H " . escapeshellarg ( $_REQUEST [ 'newHue' ]);
$args .= " -O " . escapeshellarg ( $_REQUEST [ 'newColour' ]);
$zmuCommand = getZmuCommand ( $args );
$zmuOutput = exec ( $zmuCommand );
2013-03-17 07:45:21 +08:00
list ( $brightness , $contrast , $hue , $colour ) = explode ( ' ' , $zmuOutput );
2014-06-06 03:14:12 +08:00
dbQuery ( " update Monitors set Brightness = ?, Contrast = ?, Hue = ?, Colour = ? where Id = ? " , array ( $brightness , $contrast , $hue , $colour , $mid ));
2013-03-17 07:45:21 +08:00
}
}
// Control capability actions, require control edit permissions
if ( canEdit ( 'Control' ) )
{
if ( $action == " controlcap " )
{
if ( ! empty ( $_REQUEST [ 'cid' ]) )
{
2013-11-05 01:43:34 +08:00
$control = dbFetchOne ( " select * from Controls where Id = ? " , NULL , array ( $_REQUEST [ 'cid' ]) );
2013-03-17 07:45:21 +08:00
}
else
{
$control = array ();
}
// Define a field type for anything that's not simple text equivalent
$types = array (
// Empty
);
$columns = getTableColumns ( 'Controls' );
foreach ( $columns as $name => $type )
{
if ( preg_match ( '/^(Can|Has)/' , $name ) )
{
$types [ $name ] = 'toggle' ;
}
}
$changes = getFormChanges ( $control , $_REQUEST [ 'newControl' ], $types , $columns );
if ( count ( $changes ) )
{
if ( ! empty ( $_REQUEST [ 'cid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Controls set " . implode ( " , " , $changes ) . " where Id = ? " , array ( $_REQUEST [ 'cid' ]) );
2013-03-17 07:45:21 +08:00
}
else
{
dbQuery ( " insert into Controls set " . implode ( " , " , $changes ) );
//$_REQUEST['cid'] = dbInsertId();
}
$refreshParent = true ;
}
$view = 'none' ;
}
elseif ( $action == " delete " )
{
if ( isset ( $_REQUEST [ 'markCids' ]) )
{
foreach ( $_REQUEST [ 'markCids' ] as $markCid )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from Controls where Id = ? " , array ( $markCid ) );
dbQuery ( " update Monitors set Controllable = 0, ControlId = 0 where ControlId = ? " , array ( $markCid ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
}
}
}
// Monitor edit actions, require a monitor id and edit permissions for that monitor
if ( ! empty ( $_REQUEST [ 'mid' ]) && canEdit ( 'Monitors' , $_REQUEST [ 'mid' ] ) )
{
$mid = validInt ( $_REQUEST [ 'mid' ]);
if ( $action == " function " )
{
2013-11-05 01:43:34 +08:00
$monitor = dbFetchOne ( " SELECT * FROM Monitors WHERE Id=? " , NULL , array ( $mid ) );
2013-03-17 07:45:21 +08:00
$newFunction = validStr ( $_REQUEST [ 'newFunction' ]);
2016-10-12 00:10:47 +08:00
# Because we use a checkbox, it won't get passed in the request. So not being in _REQUEST means 0
$newEnabled = ( ! isset ( $_REQUEST [ 'newEnabled' ] ) or $_REQUEST [ 'newEnabled' ] != '1' ) ? '0' : '1' ;
2013-03-17 07:45:21 +08:00
$oldFunction = $monitor [ 'Function' ];
$oldEnabled = $monitor [ 'Enabled' ];
if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Monitors set Function=?, Enabled=? where Id=? " , array ( $newFunction , $newEnabled , $mid ) );
2013-03-17 07:45:21 +08:00
$monitor [ 'Function' ] = $newFunction ;
$monitor [ 'Enabled' ] = $newEnabled ;
//if ( $cookies ) session_write_close();
if ( daemonCheck () )
{
$restart = ( $oldFunction == 'None' ) || ( $newFunction == 'None' ) || ( $newEnabled != $oldEnabled );
zmaControl ( $monitor , " stop " );
zmcControl ( $monitor , $restart ? " restart " : " " );
zmaControl ( $monitor , " start " );
}
$refreshParent = true ;
}
}
elseif ( $action == " zone " && isset ( $_REQUEST [ 'zid' ] ) )
{
$zid = validInt ( $_REQUEST [ 'zid' ]);
2013-11-05 01:43:34 +08:00
$monitor = dbFetchOne ( " SELECT * FROM Monitors WHERE Id=? " , NULL , array ( $mid ) );
2013-03-17 07:45:21 +08:00
if ( ! empty ( $zid ) )
{
2013-12-18 03:58:06 +08:00
$zone = dbFetchOne ( " SELECT * FROM Zones WHERE MonitorId=? AND Id=? " , NULL , array ( $mid , $zid ) );
2013-03-17 07:45:21 +08:00
}
else
{
$zone = array ();
}
if ( $_REQUEST [ 'newZone' ][ 'Units' ] == 'Percent' )
{
$_REQUEST [ 'newZone' ][ 'MinAlarmPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MinAlarmPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
$_REQUEST [ 'newZone' ][ 'MaxAlarmPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MaxAlarmPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
if ( isset ( $_REQUEST [ 'newZone' ][ 'MinFilterPixels' ]) )
$_REQUEST [ 'newZone' ][ 'MinFilterPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MinFilterPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
if ( isset ( $_REQUEST [ 'newZone' ][ 'MaxFilterPixels' ]) )
$_REQUEST [ 'newZone' ][ 'MaxFilterPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MaxFilterPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
if ( isset ( $_REQUEST [ 'newZone' ][ 'MinBlobPixels' ]) )
$_REQUEST [ 'newZone' ][ 'MinBlobPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MinBlobPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
if ( isset ( $_REQUEST [ 'newZone' ][ 'MaxBlobPixels' ]) )
$_REQUEST [ 'newZone' ][ 'MaxBlobPixels' ] = intval (( $_REQUEST [ 'newZone' ][ 'MaxBlobPixels' ] * $_REQUEST [ 'newZone' ][ 'Area' ]) / 100 );
}
unset ( $_REQUEST [ 'newZone' ][ 'Points' ] );
$types = array ();
$changes = getFormChanges ( $zone , $_REQUEST [ 'newZone' ], $types );
if ( count ( $changes ) )
{
if ( $zid > 0 )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " UPDATE Zones SET " . implode ( " , " , $changes ) . " WHERE MonitorId=? AND Id=? " , array ( $mid , $zid ) );
2013-03-17 07:45:21 +08:00
}
else
{
2013-11-05 01:43:34 +08:00
dbQuery ( " INSERT INTO Zones SET MonitorId=?, " . implode ( " , " , $changes ), array ( $mid ) );
2013-03-17 07:45:21 +08:00
}
//if ( $cookies ) session_write_close();
if ( daemonCheck () )
{
2015-08-27 15:45:12 +08:00
if ( $_REQUEST [ 'newZone' ][ 'Type' ] == 'Privacy' )
{
zmaControl ( $monitor , " stop " );
zmcControl ( $monitor , " restart " );
zmaControl ( $monitor , " start " );
}
else
{
zmaControl ( $mid , " restart " );
}
}
if ( $_REQUEST [ 'newZone' ][ 'Type' ] == 'Privacy' && $monitor [ 'Controllable' ] ) {
require_once ( 'control_functions.php' );
sendControlCommand ( $mid , 'quit' );
}
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
$view = 'none' ;
}
elseif ( $action == " plugin " && isset ( $_REQUEST [ 'pl' ]))
{
2013-11-05 01:43:34 +08:00
$sql = " SELECT * FROM PluginsConfig WHERE MonitorId=? AND ZoneId=? AND pluginName=? " ;
$pconfs = dbFetchAll ( $sql , NULL , array ( $mid , $_REQUEST [ 'zid' ], $_REQUEST [ 'pl' ] ) );
2013-03-17 07:45:21 +08:00
$changes = 0 ;
foreach ( $pconfs as $pconf )
{
$value = $_REQUEST [ 'pluginOpt' ][ $pconf [ 'Name' ]];
if ( array_key_exists ( $pconf [ 'Name' ], $_REQUEST [ 'pluginOpt' ]) && ( $pconf [ 'Value' ] != $value ))
{
2013-11-05 01:43:34 +08:00
dbQuery ( " UPDATE PluginsConfig SET Value=? WHERE id=? " , array ( $value , $pconf [ 'Id' ] ) );
2013-03-17 07:45:21 +08:00
$changes ++ ;
}
}
if ( $changes > 0 )
{
if ( daemonCheck () )
{
zmaControl ( $mid , " restart " );
}
$refreshParent = true ;
}
$view = 'none' ;
}
elseif ( $action == " sequence " && isset ( $_REQUEST [ 'smid' ]) )
{
$smid = validInt ( $_REQUEST [ 'smid' ]);
2013-11-05 01:43:34 +08:00
$monitor = dbFetchOne ( " select * from Monitors where Id = ? " , NULL , array ( $mid ) );
$smonitor = dbFetchOne ( " select * from Monitors where Id = ? " , NULL , array ( $smid ) );
2013-03-17 07:45:21 +08:00
2013-11-05 01:43:34 +08:00
dbQuery ( " update Monitors set Sequence=? where Id=? " , array ( $smonitor [ 'Sequence' ], $monitor [ 'Id' ] ) );
dbQuery ( " update Monitors set Sequence=? WHERE Id=? " , array ( $monitor [ 'Sequence' ], $smonitor [ 'Id' ] ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
fixSequences ();
}
if ( $action == " delete " )
{
if ( isset ( $_REQUEST [ 'markZids' ]) )
{
$deletedZid = 0 ;
foreach ( $_REQUEST [ 'markZids' ] as $markZid )
{
2015-08-27 16:12:54 +08:00
$zone = dbFetchOne ( " select * from Zones where Id=? " , NULL , array ( $markZid ) );
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from Zones WHERE MonitorId=? AND Id=? " , array ( $mid , $markZid ) );
2013-03-17 07:45:21 +08:00
$deletedZid = 1 ;
}
if ( $deletedZid )
{
//if ( $cookies )
//session_write_close();
if ( daemonCheck () )
2015-08-27 16:12:54 +08:00
if ( $zone [ 'Type' ] == 'Privacy' )
{
zmaControl ( $mid , " stop " );
zmcControl ( $mid , " restart " );
zmaControl ( $mid , " start " );
}
else
{
zmaControl ( $mid , " restart " );
}
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
}
}
}
// Monitor edit actions, monitor id derived, require edit permissions for that monitor
if ( canEdit ( 'Monitors' ) )
{
if ( $action == " monitor " )
{
if ( ! empty ( $_REQUEST [ 'mid' ]) )
{
$mid = validInt ( $_REQUEST [ 'mid' ]);
2013-11-05 01:43:34 +08:00
$monitor = dbFetchOne ( " select * from Monitors where Id = ? " , NULL , array ( $mid ) );
2013-03-17 07:45:21 +08:00
if ( ZM_OPT_X10 )
{
2013-11-05 01:43:34 +08:00
$x10Monitor = dbFetchOne ( " select * from TriggersX10 where MonitorId=? " , NULL , array ( $mid ) );
2013-03-17 07:45:21 +08:00
if ( ! $x10Monitor )
$x10Monitor = array ();
}
}
else
{
$monitor = array ();
if ( ZM_OPT_X10 )
{
$x10Monitor = array ();
}
}
// Define a field type for anything that's not simple text equivalent
$types = array (
'Triggers' => 'set' ,
'Controllable' => 'toggle' ,
'TrackMotion' => 'toggle' ,
'Enabled' => 'toggle' ,
2015-08-19 02:39:55 +08:00
'DoNativeMotDet' => 'toggle' ,
2015-08-21 23:32:50 +08:00
'Exif' => 'toggle' ,
'RTSPDescribe' => 'toggle' ,
Feature h264 videostorage (#1882)
* Moved writing of configure options from Controller to Model. Fixes #191.
* Initial commit for saving events as videos :)
* Add zm_video.cpp to autotools
* Add zm_video.h to autotools
* Search for MP4V2 header file 3 times: mp4v2/mp4v2.h, mp4v2.h, mp4.h
* Fix serve memory leak
* Few minor code improvements
* Added the ability to override preset, tune, profile and few other improvements
* Correctly write SPS & PPS from x264 encoder headers
* Remove unnessecary SPS & PPS writing code
* Imported missing files from master to feature-h264-videostorage
* Audio support including fixes for dts/pts, split on keyframe and update to mkv extension to prevent ffmpeg problems writing rtsp audio to mp4 containter (header problem)
* Updates to make gcc happy
* Add html5 video control to timeline and event to support mkv playback
* Add zm_videostore.cpp to CMakeLists.txt
* Remove Modern Branch for now
* Fix minor bug
* Option handled added in master, removing duplicate declaration
* Add CaptureandRecord from zm_camera.h
* Putting placeholder in for CaptureAndRecord function
* Removed duplicate code and brackets
* add digest auth file for cmake
Conflicts:
src/CMakeLists.txt
* Add web dir back into Makefile.am
Revert "Removed web from SUBDIRS in Makefile.am"
This reverts commit d9bbcdf3a94cba4d8955fcd03bd965ed2772f34d.
* Add CaptureAndRecord to vlc, still need to make it record
* Resolve SegFault on videostore
* Swap to mp4 container
* mp4 changes
* spaces to tabs, hide video stuff if video writer is turned off
* Make timeline open event.mp4 instead of mkv
* Missed mkv in timeline.js
* Fix some issues from the merge conflict
* Resolve post merge build issues with braces
* Fix whitespace
* Update Jpeg and Video options for passthrough options
* Whitespace fix zm_camera.h
* Fix array mkssing comma
* Add support for Jpeg save options for h264 branch snapshot. Might remove altogether if snapshots not needed
* Update VideoStoreData memory size comment
* Change from config.use_mkv_storage to per monitor option VideoWriter from video branch
* Fix bracket issues post merge
* Clean up comments and add av_free_packet
* Convert from event_directory to event file as per Video branch
* Testing videojs for video playback
* Fixed a missing bracket post merge and also SQL_values now used for EventID and Monitors
* bring recent improvements in ffmpeg capture function into captureandrecord
* Remove pict from writeAudioFramePacket as not used
* Add translate options for h264 Storage options in Monitor and update en_gb file
* Cherry-Pick from iconnor - make it compile on ubuntu 15.04. Which is libav 56.1.0
Conflicts:
src/zm_ffmpeg.cpp
src/zm_remote_camera_rtsp.cpp
Conflicts:
distros/ubuntu1204/changelog
* Clean up videostore code and remove lots of unused code
* proof of concept for dynamic/automatic video rotation using video-js plugin zoomrotate
Conflicts:
web/skins/classic/views/event.php
* removed redundant field in sql query
Conflicts:
web/skins/classic/views/event.php
* local storage of video js plugin
* Beautify!
Make the code somewhat readable.
* added missing videojs.zoomrotate.js file
added missing videojs.zoomrotate.js file
* Typo
added missing "
* Added missing brackets
* fix to display thumbnails when only storing snapshot.jpg
* added control for video playback rate
Conflicts:
web/skins/classic/views/event.php
* dynamically create jpegs from video file for viewing in browser
* fix timeline view for SaveJPEGs monitors (without enabled VideoWriter)
* only expose monitor info which are being used in client
* fix segmentation fault in zma with ubuntu 14.04 and ffmpeg 2.5.8 (gcc 4.8)
when libx264 is not installed
* better way of detecting showing image or video in timeline and event view
instead of Monitor.VideoWriter, Event.DefaultVideo is used, so even if
VideoWriter/SaveJPEG option is changed, a valid image or video will always be
displayed for historical events in both timeline and event view
this also fixes loading videos in timeline view
* Fixes problem of crashing zmc when bad packet arrives causing av_interleaved_write_frame() to return non-zero (-22). Prefilters common packet issues. Add metadata title to generated video file
* Remove syslog.h
* fixed SaveJPEGs are not working
which is caused in errors introduced when merging with master
* Update README.md
* Fix build warnings specific to h264 branch, unused FrameImg, unused ret and int64_t snprintf issues
* Fix PRId64 issue in travis, builds locally fine, but I can see a gcc version issue here
* Fix PRId64 issue in travis, another try
* Try "STDC_FORMAT_MACROS" to see if that helps Travis on gcc 4.6.3
* Revert space removal around PRId64
* video branch ffmpeg 2.9 fixes
ffmpeg 2.9 patched removed SSE2 CPU
* Add FFMPEGInit back
* use webvvt to overlay timestamp (honoring Monitor.LabelFormat) to videos in timeline and event
also fixed bug which prevented seeking in timeline video preview
* ffmpeg 3.0 API build failure fixes
* Update README.md
* merge all the commits from the messed up iconnor_video branch
* fix whitespace
* revert
* whitespace fixes
* spelling fix
* put back some text
* add these back
* fix spelling mistake
* Steal some packet dumping routines from ffmpeg. Convert them to use our logging routines
* add a test and error message if the codec is not h264
* these have been removed in master
* add a view to check auth and just send the video
* add some comments, and dump filename and AVFormatContext on failure to write header
* add the toggle for RecordAudio so that the checkbox works to turn off Audio
* Must init videoStore in constuctor
* more debug and comments, return checking
* Fix dropped part of sql query.
* fix extra else and some whitespace
* Fix missing } from merge that was preventing building.
* fix tabs
* get rid of use of separator, just use \n
* Restore lost fixes for deprecation
* Why are these failing
* Respect record_audio flag when setting up video file so dont try and initiliase mp4 with unsupported audio
* Forgot that I was trying to solve case of stream is true and record_audio
is false.
* Pass swscale_ctx back in to getCachedContext or it will create new
context every frame and leak memory like a mofo.
* Add libx264-dev and libmp4v2-dev to build requires to save hassle of
ensuring they are installed before build.
* Merge my Rotation/Orientation work and fixes for bad h264 streams
* need arpa/inet for reverse lookups
* pull in the new byte range code for viewing videos
* Move our recording flag deeper into closeevent
* add braces and only call closeEvent if there is an event
* deprecate the z_frame_rate stuff which is deprecated in ffmpeg
* remark out some debugging
* fix for video on stream 1
* fix audio_stream to audio_st
* Ignore bad decodes
* fix problems with content-length causing viewing to not work in chrome/android
* change logic of sending file contents to handle an off by one and be more readable
* Some fixes pointed out by Maxim Romanov. Also simply the loading of events to not join the Monitors table
* fix to sql for timeline
* added RecordAudio to sql in README
* Use sub queries instead of joins to fix errors when using new mysql defaults.
* fix sql queries
* Dockerfile to build feature-h264-videostorage
* Must cast codec
* add php-acpu as a dependency
* require php5-acpu
* fix typo
* remove extra /
* Add a line for out-of-tree builds to do api/lib/Cake/bootstrap.php
* delete merge conflict files
* delete merge conflict files
2017-05-16 10:02:48 +08:00
'RecordAudio' => 'toggle' ,
2013-03-17 07:45:21 +08:00
);
$columns = getTableColumns ( 'Monitors' );
$changes = getFormChanges ( $monitor , $_REQUEST [ 'newMonitor' ], $types , $columns );
if ( count ( $changes ) )
{
if ( ! empty ( $_REQUEST [ 'mid' ]) )
{
$mid = validInt ( $_REQUEST [ 'mid' ]);
2013-11-05 01:43:34 +08:00
dbQuery ( " update Monitors set " . implode ( " , " , $changes ) . " where Id =? " , array ( $mid ) );
2013-03-17 07:45:21 +08:00
if ( isset ( $changes [ 'Name' ]) )
{
2014-06-06 03:21:28 +08:00
$saferOldName = basename ( $monitor [ 'Name' ] );
$saferNewName = basename ( $_REQUEST [ 'newMonitor' ][ 'Name' ] );
rename ( ZM_DIR_EVENTS . " / " . $saferOldName , ZM_DIR_EVENTS . " / " . $saferNewName );
2013-03-17 07:45:21 +08:00
}
if ( isset ( $changes [ 'Width' ]) || isset ( $changes [ 'Height' ]) )
{
$newW = $_REQUEST [ 'newMonitor' ][ 'Width' ];
$newH = $_REQUEST [ 'newMonitor' ][ 'Height' ];
$newA = $newW * $newH ;
$oldW = $monitor [ 'Width' ];
$oldH = $monitor [ 'Height' ];
$oldA = $oldW * $oldH ;
2013-11-05 01:43:34 +08:00
$zones = dbFetchAll ( " select * from Zones where MonitorId=? " , NULL , array ( $mid ) );
2013-03-17 07:45:21 +08:00
foreach ( $zones as $zone )
{
$newZone = $zone ;
$points = coordsToPoints ( $zone [ 'Coords' ] );
for ( $i = 0 ; $i < count ( $points ); $i ++ )
{
$points [ $i ][ 'x' ] = intval (( $points [ $i ][ 'x' ] * ( $newW - 1 )) / ( $oldW - 1 ));
$points [ $i ][ 'y' ] = intval (( $points [ $i ][ 'y' ] * ( $newH - 1 )) / ( $oldH - 1 ));
}
$newZone [ 'Coords' ] = pointsToCoords ( $points );
$newZone [ 'Area' ] = intval ( round (( $zone [ 'Area' ] * $newA ) / $oldA ));
$newZone [ 'MinAlarmPixels' ] = intval ( round (( $newZone [ 'MinAlarmPixels' ] * $newA ) / $oldA ));
$newZone [ 'MaxAlarmPixels' ] = intval ( round (( $newZone [ 'MaxAlarmPixels' ] * $newA ) / $oldA ));
$newZone [ 'MinFilterPixels' ] = intval ( round (( $newZone [ 'MinFilterPixels' ] * $newA ) / $oldA ));
$newZone [ 'MaxFilterPixels' ] = intval ( round (( $newZone [ 'MaxFilterPixels' ] * $newA ) / $oldA ));
$newZone [ 'MinBlobPixels' ] = intval ( round (( $newZone [ 'MinBlobPixels' ] * $newA ) / $oldA ));
$newZone [ 'MaxBlobPixels' ] = intval ( round (( $newZone [ 'MaxBlobPixels' ] * $newA ) / $oldA ));
$changes = getFormChanges ( $zone , $newZone , $types );
if ( count ( $changes ) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Zones set " . implode ( " , " , $changes ) . " WHERE MonitorId=? AND Id=? " , array ( $mid , $zone [ 'Id' ] ) );
2013-03-17 07:45:21 +08:00
}
}
}
}
elseif ( ! $user [ 'MonitorIds' ] )
{
2013-11-05 01:43:34 +08:00
# FIXME This is actually a race condition. Should lock the table.
2013-03-17 07:45:21 +08:00
$maxSeq = dbFetchOne ( " select max(Sequence) as MaxSequence from Monitors " , " MaxSequence " );
$changes [] = " Sequence = " . ( $maxSeq + 1 );
dbQuery ( " insert into Monitors set " . implode ( " , " , $changes ) );
$mid = dbInsertId ();
$zoneArea = $_REQUEST [ 'newMonitor' ][ 'Width' ] * $_REQUEST [ 'newMonitor' ][ 'Height' ];
2013-11-05 01:43:34 +08:00
dbQuery ( " insert into Zones set MonitorId = ?, Name = 'All', Type = 'Active', Units = 'Percent', NumCoords = 4, Coords = ?, Area=?, AlarmRGB = 0xff0000, CheckMethod = 'Blobs', MinPixelThreshold = 25, MinAlarmPixels=?, MaxAlarmPixels=?, FilterX = 3, FilterY = 3, MinFilterPixels=?, MaxFilterPixels=?, MinBlobPixels=?, MinBlobs = 1 " , array ( $mid , sprintf ( " %d,%d %d,%d %d,%d %d,%d " , 0 , 0 , $_REQUEST [ 'newMonitor' ][ 'Width' ] - 1 , 0 , $_REQUEST [ 'newMonitor' ][ 'Width' ] - 1 , $_REQUEST [ 'newMonitor' ][ 'Height' ] - 1 , 0 , $_REQUEST [ 'newMonitor' ][ 'Height' ] - 1 ), $zoneArea , intval (( $zoneArea * 3 ) / 100 ), intval (( $zoneArea * 75 ) / 100 ), intval (( $zoneArea * 3 ) / 100 ), intval (( $zoneArea * 75 ) / 100 ), intval (( $zoneArea * 2 ) / 100 ) ) );
2013-03-17 07:45:21 +08:00
//$view = 'none';
mkdir ( ZM_DIR_EVENTS . '/' . $mid , 0755 );
2014-06-06 03:20:04 +08:00
$saferName = basename ( $_REQUEST [ 'newMonitor' ][ 'Name' ]);
symlink ( $mid , ZM_DIR_EVENTS . '/' . $saferName );
2013-03-17 07:45:21 +08:00
if ( isset ( $_COOKIE [ 'zmGroup' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " UPDATE Groups SET MonitorIds = concat(MonitorIds,', " . $mid . " ') WHERE Id=? " , array ( $_COOKIE [ 'zmGroup' ]) );
2013-03-17 07:45:21 +08:00
}
}
$restart = true ;
}
if ( ZM_OPT_X10 )
{
$x10Changes = getFormChanges ( $x10Monitor , $_REQUEST [ 'newX10Monitor' ] );
if ( count ( $x10Changes ) )
{
if ( $x10Monitor && isset ( $_REQUEST [ 'newX10Monitor' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update TriggersX10 set " . implode ( " , " , $x10Changes ) . " where MonitorId=? " , array ( $mid ) );
2013-03-17 07:45:21 +08:00
}
elseif ( ! $user [ 'MonitorIds' ] )
{
if ( ! $x10Monitor )
{
2017-03-29 08:03:46 +08:00
dbQuery ( " insert into TriggersX10 set MonitorId = ?, " . implode ( " , " , $x10Changes ), array ( $mid ) );
2013-03-17 07:45:21 +08:00
}
else
{
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from TriggersX10 where MonitorId = ? " , array ( $mid ) );
2013-03-17 07:45:21 +08:00
}
}
$restart = true ;
}
}
if ( $restart )
{
2013-11-05 01:43:34 +08:00
$monitor = dbFetchOne ( " select * from Monitors where Id = ? " , NULL , array ( $mid ) );
2014-04-26 10:23:36 +08:00
//fixDevices();
2013-03-17 07:45:21 +08:00
//if ( $cookies )
//session_write_close();
if ( daemonCheck () )
{
zmaControl ( $monitor , " stop " );
zmcControl ( $monitor , " restart " );
zmaControl ( $monitor , " start " );
}
2015-01-08 05:56:10 +08:00
if ( $monitor [ 'Controllable' ] ) {
require_once ( 'control_functions.php' );
sendControlCommand ( $mid , 'quit' );
}
2013-03-17 07:45:21 +08:00
//daemonControl( 'restart', 'zmwatch.pl' );
$refreshParent = true ;
}
$view = 'none' ;
}
if ( $action == " delete " )
{
if ( isset ( $_REQUEST [ 'markMids' ]) && ! $user [ 'MonitorIds' ] )
{
foreach ( $_REQUEST [ 'markMids' ] as $markMid )
{
if ( canEdit ( 'Monitors' , $markMid ) )
{
2013-11-05 01:43:34 +08:00
if ( $monitor = dbFetchOne ( " select * from Monitors where Id = ? " , NULL , array ( $markMid ) ) )
2013-03-17 07:45:21 +08:00
{
if ( daemonCheck () )
{
zmaControl ( $monitor , " stop " );
zmcControl ( $monitor , " stop " );
}
// This is the important stuff
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from Monitors where Id = ? " , array ( $markMid ) );
dbQuery ( " delete from Zones where MonitorId = ? " , array ( $markMid ) );
2013-03-17 07:45:21 +08:00
if ( ZM_OPT_X10 )
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from TriggersX10 where MonitorId=? " , array ( $markMid ) );
2013-03-17 07:45:21 +08:00
fixSequences ();
// If fast deletes are on, then zmaudit will clean everything else up later
// If fast deletes are off and there are lots of events then this step may
// well time out before completing, in which case zmaudit will still tidy up
if ( ! ZM_OPT_FAST_DELETE )
{
2015-02-07 00:50:07 +08:00
// Slight hack, we maybe should load *, but we happen to know that the deleteEvent function uses Id and StartTime.
$markEids = dbFetchAll ( " SELECT Id,StartTime FROM Events WHERE MonitorId=? " , NULL , array ( $markMid ) );
2013-03-17 07:45:21 +08:00
foreach ( $markEids as $markEid )
2015-02-07 00:50:07 +08:00
deleteEvent ( $markEid , $markMid );
2013-03-17 07:45:21 +08:00
2014-06-06 03:23:15 +08:00
deletePath ( ZM_DIR_EVENTS . " / " . basename ( $monitor [ 'Name' ]) );
deletePath ( ZM_DIR_EVENTS . " / " . $monitor [ 'Id' ] ); // I'm trusting the Id.
2013-03-17 07:45:21 +08:00
}
}
}
}
}
}
}
// Device view actions
if ( canEdit ( 'Devices' ) )
{
if ( $action == " device " )
{
if ( ! empty ( $_REQUEST [ 'command' ]) )
{
setDeviceStatusX10 ( $_REQUEST [ 'key' ], $_REQUEST [ 'command' ] );
}
elseif ( isset ( $_REQUEST [ 'newDevice' ] ) )
{
if ( isset ( $_REQUEST [ 'did' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Devices set Name=?, KeyString=? where Id=? " , array ( $_REQUEST [ 'newDevice' ][ 'Name' ], $_REQUEST [ 'newDevice' ][ 'KeyString' ], $_REQUEST [ 'did' ]) );
2013-03-17 07:45:21 +08:00
}
else
{
2013-11-05 01:43:34 +08:00
dbQuery ( " insert into Devices set Name=?, KeyString=? " , array ( $_REQUEST [ 'newDevice' ][ 'Name' ], $_REQUEST [ 'newDevice' ][ 'KeyString' ] ) );
2013-03-17 07:45:21 +08:00
}
$refreshParent = true ;
$view = 'none' ;
}
}
elseif ( $action == " delete " )
{
if ( isset ( $_REQUEST [ 'markDids' ]) )
{
foreach ( $_REQUEST [ 'markDids' ] as $markDid )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from Devices where Id=? " , array ( $markDid ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
}
}
}
2015-08-16 00:56:51 +08:00
// Group view actions
2015-08-16 02:22:13 +08:00
if ( canView ( 'Groups' ) && $action == " setgroup " ) {
if ( ! empty ( $_REQUEST [ 'gid' ]) ) {
setcookie ( " zmGroup " , validInt ( $_REQUEST [ 'gid' ]), time () + 3600 * 24 * 30 * 12 * 10 );
} else {
setcookie ( " zmGroup " , " " , time () - 3600 * 24 * 2 );
}
$refreshParent = true ;
}
// Group edit actions
2015-08-16 03:03:11 +08:00
if ( canEdit ( 'Groups' ) ) {
if ( $action == " group " ) {
# Should probably verfy that each monitor id is a valid monitor, that we have access to. HOwever at the moment, you have to have System permissions to do this
$monitors = empty ( $_POST [ 'newGroup' ][ 'MonitorIds' ] ) ? NULL : implode ( ',' , $_POST [ 'newGroup' ][ 'MonitorIds' ]);
if ( ! empty ( $_POST [ 'gid' ]) ) {
dbQuery ( " UPDATE Groups SET Name=?, MonitorIds=? WHERE Id=? " , array ( $_POST [ 'newGroup' ][ 'Name' ], $monitors , $_POST [ 'gid' ]) );
} else {
dbQuery ( " INSERT INTO Groups SET Name=?, MonitorIds=? " , array ( $_POST [ 'newGroup' ][ 'Name' ], $monitors ) );
}
$view = 'none' ;
}
if ( ! empty ( $_REQUEST [ 'gid' ]) && $action == " delete " ) {
dbQuery ( " delete from Groups where Id = ? " , array ( $_REQUEST [ 'gid' ]) );
if ( isset ( $_COOKIE [ 'zmGroup' ]) )
{
if ( $_REQUEST [ 'gid' ] == $_COOKIE [ 'zmGroup' ] )
{
unset ( $_COOKIE [ 'zmGroup' ] );
setcookie ( " zmGroup " , " " , time () - 3600 * 24 * 2 );
$refreshParent = true ;
}
}
2015-08-16 02:22:13 +08:00
}
$refreshParent = true ;
}
2013-03-17 07:45:21 +08:00
// System edit actions
if ( canEdit ( 'System' ) )
{
2015-12-09 23:43:23 +08:00
if ( isset ( $_REQUEST [ 'object' ] ) and ( $_REQUEST [ 'object' ] == 'server' ) ) {
2015-07-09 23:41:46 +08:00
2015-09-16 05:26:31 +08:00
if ( $action == " Save " ) {
2015-07-09 23:41:46 +08:00
if ( ! empty ( $_REQUEST [ 'id' ]) )
$dbServer = dbFetchOne ( " SELECT * FROM Servers WHERE Id=? " , NULL , array ( $_REQUEST [ 'id' ]) );
else
$dbServer = array ();
$types = array ();
$changes = getFormChanges ( $dbServer , $_REQUEST [ 'newServer' ], $types );
if ( count ( $changes ) ) {
if ( ! empty ( $_REQUEST [ 'id' ]) ) {
dbQuery ( " UPDATE Servers SET " . implode ( " , " , $changes ) . " WHERE Id = ? " , array ( $_REQUEST [ 'id' ]) );
} else {
dbQuery ( " INSERT INTO Servers set " . implode ( " , " , $changes ) );
}
$refreshParent = true ;
}
$view = 'none' ;
} else if ( $action == 'delete' ) {
if ( ! empty ( $_REQUEST [ 'markIds' ]) ) {
foreach ( $_REQUEST [ 'markIds' ] as $Id )
dbQuery ( " DELETE FROM Servers WHERE Id=? " , array ( $Id ) );
}
$refreshParent = true ;
2015-09-16 20:38:53 +08:00
} else {
Error ( " Unknown action $action in saving Server " );
2015-07-09 23:41:46 +08:00
}
} else if ( $action == " version " && isset ( $_REQUEST [ 'option' ]) )
2013-03-17 07:45:21 +08:00
{
$option = $_REQUEST [ 'option' ];
switch ( $option )
{
case 'go' :
{
// Ignore this, the caller will open the page itself
break ;
}
case 'ignore' :
{
dbQuery ( " update Config set Value = ' " . ZM_DYN_LAST_VERSION . " ' where Name = 'ZM_DYN_CURR_VERSION' " );
break ;
}
case 'hour' :
case 'day' :
case 'week' :
{
$nextReminder = time ();
if ( $option == 'hour' )
{
$nextReminder += 60 * 60 ;
}
elseif ( $option == 'day' )
{
$nextReminder += 24 * 60 * 60 ;
}
elseif ( $option == 'week' )
{
$nextReminder += 7 * 24 * 60 * 60 ;
}
dbQuery ( " update Config set Value = ' " . $nextReminder . " ' where Name = 'ZM_DYN_NEXT_REMINDER' " );
break ;
}
case 'never' :
{
dbQuery ( " update Config set Value = '0' where Name = 'ZM_CHECK_FOR_UPDATES' " );
break ;
}
}
}
if ( $action == " donate " && isset ( $_REQUEST [ 'option' ]) )
{
$option = $_REQUEST [ 'option' ];
switch ( $option )
{
case 'go' :
{
// Ignore this, the caller will open the page itself
break ;
}
case 'hour' :
case 'day' :
case 'week' :
case 'month' :
{
$nextReminder = time ();
if ( $option == 'hour' )
{
$nextReminder += 60 * 60 ;
}
elseif ( $option == 'day' )
{
$nextReminder += 24 * 60 * 60 ;
}
elseif ( $option == 'week' )
{
$nextReminder += 7 * 24 * 60 * 60 ;
}
elseif ( $option == 'month' )
{
$nextReminder += 30 * 24 * 60 * 60 ;
}
dbQuery ( " update Config set Value = ' " . $nextReminder . " ' where Name = 'ZM_DYN_DONATE_REMINDER_TIME' " );
break ;
}
case 'never' :
case 'already' :
{
dbQuery ( " update Config set Value = '0' where Name = 'ZM_DYN_SHOW_DONATE_REMINDER' " );
break ;
}
}
}
if ( $action == " options " && isset ( $_REQUEST [ 'tab' ]) )
{
$configCat = $configCats [ $_REQUEST [ 'tab' ]];
$changed = false ;
foreach ( $configCat as $name => $value )
{
unset ( $newValue );
if ( $value [ 'Type' ] == " boolean " && empty ( $_REQUEST [ 'newConfig' ][ $name ]) )
$newValue = 0 ;
elseif ( isset ( $_REQUEST [ 'newConfig' ][ $name ]) )
$newValue = preg_replace ( " / \r \n / " , " \n " , stripslashes ( $_REQUEST [ 'newConfig' ][ $name ] ) );
if ( isset ( $newValue ) && ( $newValue != $value [ 'Value' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( 'UPDATE Config SET Value=? WHERE Name=?' , array ( $newValue , $name ) );
2013-03-17 07:45:21 +08:00
$changed = true ;
}
}
if ( $changed )
{
switch ( $_REQUEST [ 'tab' ] )
{
case " system " :
case " config " :
case " paths " :
$restartWarning = true ;
break ;
case " web " :
case " tools " :
break ;
case " logging " :
case " network " :
case " mail " :
case " upload " :
$restartWarning = true ;
break ;
case " highband " :
case " medband " :
case " lowband " :
break ;
}
}
loadConfig ( false );
}
elseif ( $action == " user " )
{
if ( ! empty ( $_REQUEST [ 'uid' ]) )
2013-11-05 01:43:34 +08:00
$dbUser = dbFetchOne ( " SELECT * FROM Users WHERE Id=? " , NULL , array ( $_REQUEST [ 'uid' ]) );
2013-03-17 07:45:21 +08:00
else
$dbUser = array ();
$types = array ();
$changes = getFormChanges ( $dbUser , $_REQUEST [ 'newUser' ], $types );
if ( $_REQUEST [ 'newUser' ][ 'Password' ] )
2013-10-18 03:54:17 +08:00
$changes [ 'Password' ] = " Password = password( " . dbEscape ( $_REQUEST [ 'newUser' ][ 'Password' ]) . " ) " ;
2013-03-17 07:45:21 +08:00
else
unset ( $changes [ 'Password' ] );
if ( count ( $changes ) )
{
if ( ! empty ( $_REQUEST [ 'uid' ]) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Users set " . implode ( " , " , $changes ) . " where Id = ? " , array ( $_REQUEST [ 'uid' ]) );
2013-03-17 07:45:21 +08:00
}
else
{
2013-11-05 01:43:34 +08:00
dbQuery ( " insert into Users set " . implode ( " , " , $changes ) );
2013-03-17 07:45:21 +08:00
}
$refreshParent = true ;
if ( $dbUser [ 'Username' ] == $user [ 'Username' ] )
userLogin ( $dbUser [ 'Username' ], $dbUser [ 'Password' ] );
}
$view = 'none' ;
}
elseif ( $action == " state " )
{
if ( ! empty ( $_REQUEST [ 'runState' ]) )
{
//if ( $cookies ) session_write_close();
packageControl ( $_REQUEST [ 'runState' ] );
$refreshParent = true ;
}
}
elseif ( $action == " save " )
{
if ( ! empty ( $_REQUEST [ 'runState' ]) || ! empty ( $_REQUEST [ 'newState' ]) )
{
$sql = " select Id,Function,Enabled from Monitors order by Id " ;
$definitions = array ();
foreach ( dbFetchAll ( $sql ) as $monitor )
{
$definitions [] = $monitor [ 'Id' ] . " : " . $monitor [ 'Function' ] . " : " . $monitor [ 'Enabled' ];
}
$definition = join ( ',' , $definitions );
if ( $_REQUEST [ 'newState' ] )
$_REQUEST [ 'runState' ] = $_REQUEST [ 'newState' ];
2013-11-05 01:43:34 +08:00
dbQuery ( " replace into States set Name=?, Definition=? " , array ( $_REQUEST [ 'runState' ], $definition ) );
2013-03-17 07:45:21 +08:00
}
}
elseif ( $action == " delete " )
{
if ( isset ( $_REQUEST [ 'runState' ]) )
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from States where Name=? " , array ( $_REQUEST [ 'runState' ]) );
2013-03-17 07:45:21 +08:00
if ( isset ( $_REQUEST [ 'markUids' ]) )
{
foreach ( $_REQUEST [ 'markUids' ] as $markUid )
2013-11-05 01:43:34 +08:00
dbQuery ( " delete from Users where Id = ? " , array ( $markUid ) );
2013-03-17 07:45:21 +08:00
if ( $markUid == $user [ 'Id' ] )
userLogout ();
}
}
}
else
{
if ( ZM_USER_SELF_EDIT && $action == " user " )
{
$uid = $user [ 'Id' ];
2013-11-05 01:43:34 +08:00
$dbUser = dbFetchOne ( " select Id, Password, Language from Users where Id = ? " , NULL , array ( $uid ) );
2013-03-17 07:45:21 +08:00
$types = array ();
$changes = getFormChanges ( $dbUser , $_REQUEST [ 'newUser' ], $types );
if ( ! empty ( $_REQUEST [ 'newUser' ][ 'Password' ]) )
2013-10-18 03:54:17 +08:00
$changes [ 'Password' ] = " Password = password( " . dbEscape ( $_REQUEST [ 'newUser' ][ 'Password' ]) . " ) " ;
2013-03-17 07:45:21 +08:00
else
unset ( $changes [ 'Password' ] );
if ( count ( $changes ) )
{
2013-11-05 01:43:34 +08:00
dbQuery ( " update Users set " . implode ( " , " , $changes ) . " where Id=? " , array ( $uid ) );
2013-03-17 07:45:21 +08:00
$refreshParent = true ;
}
$view = 'none' ;
}
}
if ( $action == " reset " )
{
$_SESSION [ 'zmEventResetTime' ] = strftime ( STRF_FMT_DATETIME_DB );
setcookie ( " zmEventResetTime " , $_SESSION [ 'zmEventResetTime' ], time () + 3600 * 24 * 30 * 12 * 10 );
//if ( $cookies ) session_write_close();
}
}
?>