diff --git a/CMakeLists.txt b/CMakeLists.txt index d5f469d34..d17c20e73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -838,14 +838,16 @@ else(zmconfgen_result EQUAL 0) endif(zmconfgen_result EQUAL 0) # Install zm.conf -install(CODE " - if (NOT EXISTS \"${ZM_CONFIG_DIR}/zm.conf\") - file(INSTALL \"${CMAKE_CURRENT_BINARY_DIR}/zm.conf\" DESTINATION \"${ZM_CONFIG_DIR}\") - else (NOT EXISTS \"${ZM_CONFIG_DIR}/zm.conf\") - file(RENAME \"${CMAKE_CURRENT_BINARY_DIR}/zm.conf\" \"${CMAKE_CURRENT_BINARY_DIR}/zm.conf.new\") - file(INSTALL \"${CMAKE_CURRENT_BINARY_DIR}/zm.conf.new\" DESTINATION \"${ZM_CONFIG_DIR}\") - endif() - ") +if (NOT EXISTS "${ZM_CONFIG_DIR}/zm.conf") + message(STATUS "No zm.conf at ${CMAKE_CURRENT_BINARY_DIR}/zm.conf. Will install a new zm.conf") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" DESTINATION "${ZM_CONFIG_DIR}") +else (NOT EXISTS "${ZM_CONFIG_DIR}/zm.conf") + message(STATUS "Found zm.conf at ${CMAKE_CURRENT_BINARY_DIR}/zm.conf. Not overwriting. Installing zm.conf.new instead.") + file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/zm.conf" "${CMAKE_CURRENT_BINARY_DIR}/zm.conf.new") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/zm.conf.new" DESTINATION "${ZM_CONFIG_DIR}") + file(RENAME "${CMAKE_CURRENT_BINARY_DIR}/zm.conf.new" "${CMAKE_CURRENT_BINARY_DIR}/zm.conf") +endif() + #") # Uninstall target diff --git a/web/ajax/event.php b/web/ajax/event.php index a78ccd1a9..5291f0f7a 100644 --- a/web/ajax/event.php +++ b/web/ajax/event.php @@ -6,7 +6,7 @@ if ( empty($_REQUEST['id']) && empty($_REQUEST['eids']) ) { if ( canView( 'Events' ) ) { switch ( $_REQUEST['action'] ) { - case "video" : { + case 'video' : { if ( empty($_REQUEST['videoFormat']) ) { ajaxError( "Video Generation Failure, no format given" ); } elseif ( empty($_REQUEST['rate']) ) { @@ -77,11 +77,9 @@ if ( canView( 'Events' ) ) { } } -if ( canEdit( 'Events' ) ) -{ - switch ( $_REQUEST['action'] ) - { - case "rename" : +if ( canEdit( 'Events' ) ) { + switch ( $_REQUEST['action'] ) { + case 'rename' : { if ( !empty($_REQUEST['eventName']) ) dbQuery( 'UPDATE Events SET Name = ? WHERE Id = ?', array( $_REQUEST['eventName'], $_REQUEST['id'] ) ); @@ -90,24 +88,29 @@ if ( canEdit( 'Events' ) ) ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) ); break; } - case "eventdetail" : + case 'eventdetail' : { dbQuery( 'UPDATE Events SET Cause = ?, Notes = ? WHERE Id = ?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['id'] ) ); ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>true ) ); break; } - case "archive" : - case "unarchive" : + case 'archive' : + case 'unarchive' : { $archiveVal = ($_REQUEST['action'] == "archive")?1:0; dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', array( $archiveVal, $_REQUEST['id']) ); ajaxResponse( array( 'refreshEvent'=>true, 'refreshParent'=>false ) ); break; } - case "delete" : + case 'delete' : { - deleteEvent( $_REQUEST['id'] ); - ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) ); + $Event = new Event( $_REQUEST['id'] ); + if ( ! $Event->Id() ) { + ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true, 'message'=> 'Event not found.' ) ); + } else { + $Event->delete(); + ajaxResponse( array( 'refreshEvent'=>false, 'refreshParent'=>true ) ); + } break; } } diff --git a/web/ajax/status.php b/web/ajax/status.php index 638c5ca85..fbd91cf08 100644 --- a/web/ajax/status.php +++ b/web/ajax/status.php @@ -2,418 +2,395 @@ $statusData = array( "system" => array( - "permission" => "System", - "table" => "Monitors", - "limit" => 1, - "elements" => array( - "MonitorCount" => array( "sql" => "count(*)" ), - "ActiveMonitorCount" => array( "sql" => "count(if(Function != 'None',1,NULL))" ), - "State" => array( "func" => "daemonCheck()?".translate('Running').":".translate('Stopped') ), - "Load" => array( "func" => "getLoad()" ), - "Disk" => array( "func" => "getDiskPercent()" ), + "permission" => "System", + "table" => "Monitors", + "limit" => 1, + "elements" => array( + "MonitorCount" => array( "sql" => "count(*)" ), + "ActiveMonitorCount" => array( "sql" => "count(if(Function != 'None',1,NULL))" ), + "State" => array( "func" => "daemonCheck()?".translate('Running').":".translate('Stopped') ), + "Load" => array( "func" => "getLoad()" ), + "Disk" => array( "func" => "getDiskPercent()" ), ), - ), + ), "monitor" => array( - "permission" => "Monitors", - "table" => "Monitors", - "limit" => 1, - "selector" => "Monitors.Id", - "elements" => array( - "Id" => array( "sql" => "Monitors.Id" ), - "Name" => array( "sql" => "Monitors.Name" ), - "Type" => true, - "Function" => true, - "Enabled" => true, - "LinkedMonitors" => true, - "Triggers" => true, - "Device" => true, - "Channel" => true, - "Format" => true, - "Host" => true, - "Port" => true, - "Path" => true, - "Width" => array( "sql" => "Monitors.Width" ), - "Height" => array( "sql" => "Monitors.Height" ), - "Palette" => true, - "Orientation" => true, - "Brightness" => true, - "Contrast" => true, - "Hue" => true, - "Colour" => true, - "EventPrefix" => true, - "LabelFormat" => true, - "LabelX" => true, - "LabelY" => true, - "LabelSize" => true, - "ImageBufferCount" => true, - "WarmupCount" => true, - "PreEventCount" => true, - "PostEventCount" => true, - "AlarmFrameCount" => true, - "SectionLength" => true, - "FrameSkip" => true, - "MotionFrameSkip" => true, - "MaxFPS" => true, - "AlarmMaxFPS" => true, - "FPSReportInterval" => true, - "RefBlendPerc" => true, - "Controllable" => true, - "ControlId" => true, - "ControlDevice" => true, - "ControlAddress" => true, - "AutoStopTimeout" => true, - "TrackMotion" => true, - "TrackDelay" => true, - "ReturnLocation" => true, - "ReturnDelay" => true, - "DefaultView" => true, - "DefaultRate" => true, - "DefaultScale" => true, - "WebColour" => true, - "Sequence" => true, - "MinEventId" => array( "sql" => "(SELECT min(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), - "MaxEventId" => array( "sql" => "(SELECT max(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), - "TotalEvents" => array( "sql" => "(SELECT count(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), - "Status" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -s" ), - "FrameRate" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -f" ), + "permission" => "Monitors", + "table" => "Monitors", + "limit" => 1, + "selector" => "Monitors.Id", + "elements" => array( + "Id" => array( "sql" => "Monitors.Id" ), + "Name" => array( "sql" => "Monitors.Name" ), + "Type" => true, + "Function" => true, + "Enabled" => true, + "LinkedMonitors" => true, + "Triggers" => true, + "Device" => true, + "Channel" => true, + "Format" => true, + "Host" => true, + "Port" => true, + "Path" => true, + "Width" => array( "sql" => "Monitors.Width" ), + "Height" => array( "sql" => "Monitors.Height" ), + "Palette" => true, + "Orientation" => true, + "Brightness" => true, + "Contrast" => true, + "Hue" => true, + "Colour" => true, + "EventPrefix" => true, + "LabelFormat" => true, + "LabelX" => true, + "LabelY" => true, + "LabelSize" => true, + "ImageBufferCount" => true, + "WarmupCount" => true, + "PreEventCount" => true, + "PostEventCount" => true, + "AlarmFrameCount" => true, + "SectionLength" => true, + "FrameSkip" => true, + "MotionFrameSkip" => true, + "MaxFPS" => true, + "AlarmMaxFPS" => true, + "FPSReportInterval" => true, + "RefBlendPerc" => true, + "Controllable" => true, + "ControlId" => true, + "ControlDevice" => true, + "ControlAddress" => true, + "AutoStopTimeout" => true, + "TrackMotion" => true, + "TrackDelay" => true, + "ReturnLocation" => true, + "ReturnDelay" => true, + "DefaultView" => true, + "DefaultRate" => true, + "DefaultScale" => true, + "WebColour" => true, + "Sequence" => true, + "MinEventId" => array( "sql" => "(SELECT min(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), + "MaxEventId" => array( "sql" => "(SELECT max(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), + "TotalEvents" => array( "sql" => "(SELECT count(Events.Id) FROM Events WHERE Events.MonitorId = Monitors.Id" ), + "Status" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -s" ), + "FrameRate" => array( "zmu" => "-m ".escapeshellarg($_REQUEST['id'][0])." -f" ), ), - ), - "events" => array( - "permission" => "Events", - "table" => "Events", - "selector" => "Events.MonitorId", - "elements" => array( - "Id" => true, - "Name" => true, - "Cause" => true, - "Notes" => true, - "StartTime" => true, - "StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), - "EndTime" => true, - "Width" => true, - "Height" => true, - "Length" => true, - "Frames" => true, - "AlarmFrames" => true, - "TotScore" => true, - "AvgScore" => true, - "MaxScore" => true, - ), - ), - "event" => array( - "permission" => "Events", - "table" => "Events", - "limit" => 1, - "selector" => "Events.Id", - "elements" => array( - "Id" => array( "sql" => "Events.Id" ), - "MonitorId" => true, - "Name" => true, - "Cause" => true, - "StartTime" => true, - "StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), - "EndTime" => true, - "Width" => true, - "Height" => true, - "Length" => true, - "Frames" => true, - "DefaultVideo" => true, - "AlarmFrames" => true, - "TotScore" => true, - "AvgScore" => true, - "MaxScore" => true, - "Archived" => true, - "Videoed" => true, - "Uploaded" => true, - "Emailed" => true, - "Messaged" => true, - "Executed" => true, - "Notes" => true, - "MinFrameId" => array( "sql" => "(SELECT min(Frames.FrameId) FROM Frames WHERE EventId=Events.Id)" ), - "MaxFrameId" => array( "sql" => "(SELECT max(Frames.FrameId) FROM Frames WHERE Events.Id = Frames.EventId)" ), - "MinFrameDelta" => array( "sql" => "(SELECT min(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)" ), - "MaxFrameDelta" => array( "sql" => "(SELECT max(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)" ), - //"Path" => array( "postFunc" => "getEventPath" ), - ), - ), - "frame" => array( - "permission" => "Events", - "table" => "Frames", - "limit" => 1, - "selector" => array( array( "table" => "Events", "join" => "Events.Id = Frames.EventId", "selector"=>"Events.Id" ), "Frames.FrameId" ), - "elements" => array( - //"Id" => array( "sql" => "Frames.FrameId" ), - "FrameId" => true, - "EventId" => true, - "Type" => true, - "TimeStamp" => true, - "TimeStampShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), - "Delta" => true, - "Score" => true, - //"Image" => array( "postFunc" => "getFrameImage" ), - ), - ), - "frameimage" => array( - "permission" => "Events", - "func" => "getFrameImage()" - ), - "nearframe" => array( - "permission" => "Events", - "func" => "getNearFrame()" - ), - "nearevents" => array( - "permission" => "Events", - "func" => "getNearEvents()" - ) -); + ), + "events" => array( + "permission" => "Events", + "table" => "Events", + "selector" => "Events.MonitorId", + "elements" => array( + "Id" => true, + "Name" => true, + "Cause" => true, + "Notes" => true, + "StartTime" => true, + "StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), + "EndTime" => true, + "Width" => true, + "Height" => true, + "Length" => true, + "Frames" => true, + "AlarmFrames" => true, + "TotScore" => true, + "AvgScore" => true, + "MaxScore" => true, + ), + ), + "event" => array( + "permission" => "Events", + "table" => "Events", + "limit" => 1, + "selector" => "Events.Id", + "elements" => array( + "Id" => array( "sql" => "Events.Id" ), + "MonitorId" => true, + "Name" => true, + "Cause" => true, + "StartTime" => true, + "StartTimeShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), + "EndTime" => true, + "Width" => true, + "Height" => true, + "Length" => true, + "Frames" => true, + "DefaultVideo" => true, + "AlarmFrames" => true, + "TotScore" => true, + "AvgScore" => true, + "MaxScore" => true, + "Archived" => true, + "Videoed" => true, + "Uploaded" => true, + "Emailed" => true, + "Messaged" => true, + "Executed" => true, + "Notes" => true, + "MinFrameId" => array( "sql" => "(SELECT min(Frames.FrameId) FROM Frames WHERE EventId=Events.Id)" ), + "MaxFrameId" => array( "sql" => "(SELECT max(Frames.FrameId) FROM Frames WHERE Events.Id = Frames.EventId)" ), + "MinFrameDelta" => array( "sql" => "(SELECT min(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)" ), + "MaxFrameDelta" => array( "sql" => "(SELECT max(Frames.Delta) FROM Frames WHERE Events.Id = Frames.EventId)" ), + //"Path" => array( "postFunc" => "getEventPath" ), + ), + ), + "frame" => array( + "permission" => "Events", + "table" => "Frames", + "limit" => 1, + "selector" => array( array( "table" => "Events", "join" => "Events.Id = Frames.EventId", "selector"=>"Events.Id" ), "Frames.FrameId" ), + "elements" => array( + //"Id" => array( "sql" => "Frames.FrameId" ), + "FrameId" => true, + "EventId" => true, + "Type" => true, + "TimeStamp" => true, + "TimeStampShort" => array( "sql" => "date_format( StartTime, '".MYSQL_FMT_DATETIME_SHORT."' )" ), + "Delta" => true, + "Score" => true, + //"Image" => array( "postFunc" => "getFrameImage" ), + ), + ), + "frameimage" => array( + "permission" => "Events", + "func" => "getFrameImage()" + ), + "nearframe" => array( + "permission" => "Events", + "func" => "getNearFrame()" + ), + "nearevents" => array( + "permission" => "Events", + "func" => "getNearEvents()" + ) + ); -function collectData() -{ - global $statusData; +function collectData() { + global $statusData; - $entitySpec = &$statusData[strtolower(validJsStr($_REQUEST['entity']))]; - #print_r( $entitySpec ); - if ( !canView( $entitySpec['permission'] ) ) - ajaxError( 'Unrecognised action or insufficient permissions' ); + $entitySpec = &$statusData[strtolower(validJsStr($_REQUEST['entity']))]; +#print_r( $entitySpec ); + if ( !canView( $entitySpec['permission'] ) ) + ajaxError( 'Unrecognised action or insufficient permissions' ); - if ( !empty($entitySpec['func']) ) - { - $data = eval( "return( ".$entitySpec['func']." );" ); + if ( !empty($entitySpec['func']) ) { + $data = eval( "return( ".$entitySpec['func']." );" ); + } else { + $data = array(); + $postFuncs = array(); + + $fieldSql = array(); + $joinSql = array(); + $groupSql = array(); + + $elements = &$entitySpec['elements']; + $lc_elements = array_change_key_case( $elements ); + + $id = false; + if ( isset($_REQUEST['id']) ) + if ( !is_array($_REQUEST['id']) ) + $id = array( validJsStr($_REQUEST['id']) ); + else + $id = array_values( $_REQUEST['id'] ); + + if ( !isset($_REQUEST['element']) ) + $_REQUEST['element'] = array_keys( $elements ); + else if ( !is_array($_REQUEST['element']) ) + $_REQUEST['element'] = array( validJsStr($_REQUEST['element']) ); + + if ( isset($entitySpec['selector']) ) { + if ( !is_array($entitySpec['selector']) ) + $entitySpec['selector'] = array( $entitySpec['selector'] ); + foreach( $entitySpec['selector'] as $selector ) + if ( is_array( $selector ) && isset($selector['table']) && isset($selector['join']) ) + $joinSql[] = "left join ".$selector['table']." on ".$selector['join']; } - else - { - $data = array(); - $postFuncs = array(); - $fieldSql = array(); - $joinSql = array(); - $groupSql = array(); - - $elements = &$entitySpec['elements']; - $lc_elements = array_change_key_case( $elements ); - - $id = false; - if ( isset($_REQUEST['id']) ) - if ( !is_array($_REQUEST['id']) ) - $id = array( validJsStr($_REQUEST['id']) ); - else - $id = array_values( $_REQUEST['id'] ); - - if ( !isset($_REQUEST['element']) ) - $_REQUEST['element'] = array_keys( $elements ); - else if ( !is_array($_REQUEST['element']) ) - $_REQUEST['element'] = array( validJsStr($_REQUEST['element']) ); - - if ( isset($entitySpec['selector']) ) - { - if ( !is_array($entitySpec['selector']) ) - $entitySpec['selector'] = array( $entitySpec['selector'] ); - foreach( $entitySpec['selector'] as $selector ) - if ( is_array( $selector ) && isset($selector['table']) && isset($selector['join']) ) - $joinSql[] = "left join ".$selector['table']." on ".$selector['join']; + foreach ( $_REQUEST['element'] as $element ) { + if ( !($elementData = $lc_elements[strtolower($element)]) ) + ajaxError( "Bad ".validJsStr($_REQUEST['entity'])." element ".$element ); + if ( isset($elementData['func']) ) + $data[$element] = eval( "return( ".$elementData['func']." );" ); + else if ( isset($elementData['postFunc']) ) + $postFuncs[$element] = $elementData['postFunc']; + else if ( isset($elementData['zmu']) ) + $data[$element] = exec( escapeshellcmd( getZmuCommand( " ".$elementData['zmu'] ) ) ); + else { + if ( isset($elementData['sql']) ) + $fieldSql[] = $elementData['sql']." as ".$element; + else + $fieldSql[] = $element; + if ( isset($elementData['table']) && isset($elementData['join']) ) { + $joinSql[] = "left join ".$elementData['table']." on ".$elementData['join']; } - - foreach ( $_REQUEST['element'] as $element ) - { - if ( !($elementData = $lc_elements[strtolower($element)]) ) - ajaxError( "Bad ".validJsStr($_REQUEST['entity'])." element ".$element ); - if ( isset($elementData['func']) ) - $data[$element] = eval( "return( ".$elementData['func']." );" ); - else if ( isset($elementData['postFunc']) ) - $postFuncs[$element] = $elementData['postFunc']; - else if ( isset($elementData['zmu']) ) - $data[$element] = exec( escapeshellcmd( getZmuCommand( " ".$elementData['zmu'] ) ) ); - else - { - if ( isset($elementData['sql']) ) - $fieldSql[] = $elementData['sql']." as ".$element; - else - $fieldSql[] = $element; - if ( isset($elementData['table']) && isset($elementData['join']) ) - { - $joinSql[] = "left join ".$elementData['table']." on ".$elementData['join']; - } - if ( isset($elementData['group']) ) - { - $groupSql[] = $elementData['group']; - } - } - } - - if ( count($fieldSql) ) - { - $sql = "select ".join( ", ", $fieldSql )." from ".$entitySpec['table']; - if ( $joinSql ) - $sql .= " ".join( " ", array_unique( $joinSql ) ); - if ( $id && !empty($entitySpec['selector']) ) - { - $index = 0; - $where = array(); - $values = array(); - foreach( $entitySpec['selector'] as $selector ) { - if ( is_array( $selector ) ) { - $where[] = $selector['selector'].' = ?'; - $values[] = validInt($id[$index]); - } else { - $where[] = $selector.' = ?'; - $values[] = validInt($id[$index]); - } - $index++; - } - $sql .= " where ".join( " and ", $where ); - } - if ( $groupSql ) - $sql .= " group by ".join( ",", array_unique( $groupSql ) ); - if ( !empty($_REQUEST['sort']) ) - $sql .= " order by ".$_REQUEST['sort']; - if ( !empty($entitySpec['limit']) ) - $limit = $entitySpec['limit']; - elseif ( !empty($_REQUEST['count']) ) - $limit = validInt($_REQUEST['count']); - $limit_offset=""; - if ( !empty($_REQUEST['offset']) ) - $limit_offset = validInt($_REQUEST['offset']) . ", "; - if ( !empty( $limit ) ) - $sql .= " limit ".$limit_offset.$limit; - if ( isset($limit) && $limit == 1 ) { - if ( $sqlData = dbFetchOne( $sql, NULL, $values ) ) { - foreach ( $postFuncs as $element=>$func ) - $sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' ); - $data = array_merge( $data, $sqlData ); - } - } else { - $count = 0; - foreach( dbFetchAll( $sql, NULL, $values ) as $sqlData ) { - foreach ( $postFuncs as $element=>$func ) - $sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' ); - $data[] = $sqlData; - if ( isset($limi) && ++$count >= $limit ) - break; - } - } + if ( isset($elementData['group']) ) { + $groupSql[] = $elementData['group']; } + } } - #print_r( $data ); - return( $data ); + + if ( count($fieldSql) ) { + $sql = "select ".join( ", ", $fieldSql )." from ".$entitySpec['table']; + if ( $joinSql ) + $sql .= " ".join( " ", array_unique( $joinSql ) ); + if ( $id && !empty($entitySpec['selector']) ) { + $index = 0; + $where = array(); + $values = array(); + foreach( $entitySpec['selector'] as $selector ) { + if ( is_array( $selector ) ) { + $where[] = $selector['selector'].' = ?'; + $values[] = validInt($id[$index]); + } else { + $where[] = $selector.' = ?'; + $values[] = validInt($id[$index]); + } + $index++; + } + $sql .= " where ".join( " and ", $where ); + } + if ( $groupSql ) + $sql .= " GROUP BY ".join( ",", array_unique( $groupSql ) ); + if ( !empty($_REQUEST['sort']) ) + $sql .= " order by ".$_REQUEST['sort']; + if ( !empty($entitySpec['limit']) ) + $limit = $entitySpec['limit']; + elseif ( !empty($_REQUEST['count']) ) + $limit = validInt($_REQUEST['count']); + $limit_offset=""; + if ( !empty($_REQUEST['offset']) ) + $limit_offset = validInt($_REQUEST['offset']) . ", "; + if ( !empty( $limit ) ) + $sql .= " limit ".$limit_offset.$limit; + if ( isset($limit) && $limit == 1 ) { + if ( $sqlData = dbFetchOne( $sql, NULL, $values ) ) { + foreach ( $postFuncs as $element=>$func ) + $sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' ); + $data = array_merge( $data, $sqlData ); + } + } else { + $count = 0; + foreach( dbFetchAll( $sql, NULL, $values ) as $sqlData ) { + foreach ( $postFuncs as $element=>$func ) + $sqlData[$element] = eval( 'return( '.$func.'( $sqlData ) );' ); + $data[] = $sqlData; + if ( isset($limi) && ++$count >= $limit ) + break; + } + } + } + } +#print_r( $data ); + return( $data ); } $data = collectData(); -if ( !isset($_REQUEST['layout']) ) -{ - $_REQUEST['layout'] = "json"; +if ( !isset($_REQUEST['layout']) ) { + $_REQUEST['layout'] = "json"; } -switch( $_REQUEST['layout'] ) -{ - case 'xml NOT CURRENTLY SUPPORTED' : + +switch( $_REQUEST['layout'] ) { + case 'xml NOT CURRENTLY SUPPORTED' : { - header("Content-type: application/xml" ); - echo( ''."\n" ); - echo "<".strtolower($_REQUEST['entity']).">\n"; - foreach ( $data as $key=>$value ) - { - $key = strtolower( $key ); - echo "<$key>".htmlentities($value)."\n"; - } - echo "\n"; - break; + header("Content-type: application/xml" ); + echo( ''."\n" ); + echo "<".strtolower($_REQUEST['entity']).">\n"; + foreach ( $data as $key=>$value ) { + $key = strtolower( $key ); + echo "<$key>".htmlentities($value)."\n"; + } + echo "\n"; + break; } - case 'json' : + case 'json' : { - $response = array( strtolower(validJsStr($_REQUEST['entity'])) => $data ); - if ( isset($_REQUEST['loopback']) ) - $response['loopback'] = validJsStr($_REQUEST['loopback']); - ajaxResponse( $response ); - break; + $response = array( strtolower(validJsStr($_REQUEST['entity'])) => $data ); + if ( isset($_REQUEST['loopback']) ) + $response['loopback'] = validJsStr($_REQUEST['loopback']); + ajaxResponse( $response ); + break; } - case 'text' : + case 'text' : { - header("Content-type: text/plain" ); - echo join( " ", array_values( $data ) ); - break; + header("Content-type: text/plain" ); + echo join( " ", array_values( $data ) ); + break; } } -function getFrameImage() -{ - $eventId = $_REQUEST['id'][0]; - $frameId = $_REQUEST['id'][1]; +function getFrameImage() { + $eventId = $_REQUEST['id'][0]; + $frameId = $_REQUEST['id'][1]; - $sql = 'select * from Frames where EventId = ? and FrameId = ?'; - if ( !($frame = dbFetchOne( $sql, NULL, array( $eventId, $frameId ) )) ) - { - $frame = array(); - $frame['EventId'] = $eventId; - $frame['FrameId'] = $frameId; - $frame['Type'] = "Virtual"; - } - $event = dbFetchOne( 'select * from Events where Id = ?', NULL, array( $frame['EventId'] ) ); - $frame['Image'] = getImageSrc( $event, $frame, SCALE_BASE ); - return( $frame ); + $sql = 'select * from Frames where EventId = ? and FrameId = ?'; + if ( !($frame = dbFetchOne( $sql, NULL, array( $eventId, $frameId ) )) ) { + $frame = array(); + $frame['EventId'] = $eventId; + $frame['FrameId'] = $frameId; + $frame['Type'] = "Virtual"; + } + $event = dbFetchOne( 'select * from Events where Id = ?', NULL, array( $frame['EventId'] ) ); + $frame['Image'] = getImageSrc( $event, $frame, SCALE_BASE ); + return( $frame ); } -function getNearFrame() -{ - $eventId = $_REQUEST['id'][0]; - $frameId = $_REQUEST['id'][1]; +function getNearFrame() { + $eventId = $_REQUEST['id'][0]; + $frameId = $_REQUEST['id'][1]; - $sql = 'select FrameId from Frames where EventId = ? and FrameId <= ? order by FrameId desc limit 1'; - if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId', array( $eventId, $frameId ) ) ) - { - $sql = 'select * from Frames where EventId = ? and FrameId > ? order by FrameId asc limit 1'; - if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId', array( $eventId, $frameId ) ) ) - { - return( array() ); - } + $sql = 'select FrameId from Frames where EventId = ? and FrameId <= ? order by FrameId desc limit 1'; + if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId', array( $eventId, $frameId ) ) ) { + $sql = 'select * from Frames where EventId = ? and FrameId > ? order by FrameId asc limit 1'; + if ( !$nearFrameId = dbFetchOne( $sql, 'FrameId', array( $eventId, $frameId ) ) ) { + return( array() ); } - $_REQUEST['entity'] = "frame"; - $_REQUEST['id'][1] = $nearFrameId; - return( collectData() ); + } + $_REQUEST['entity'] = "frame"; + $_REQUEST['id'][1] = $nearFrameId; + return( collectData() ); } -function getNearEvents() -{ - global $user, $sortColumn, $sortOrder; +function getNearEvents() { + global $user, $sortColumn, $sortOrder; - $eventId = $_REQUEST['id']; - $event = dbFetchOne( 'select * from Events where Id = ?', NULL, array( $eventId ) ); + $eventId = $_REQUEST['id']; + $event = dbFetchOne( 'select * from Events where Id = ?', NULL, array( $eventId ) ); - parseFilter( $_REQUEST['filter'] ); - parseSort(); + parseFilter( $_REQUEST['filter'] ); + parseSort(); - if ( $user['MonitorIds'] ) - $midSql = " and MonitorId in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")"; - else - $midSql = ''; + if ( $user['MonitorIds'] ) + $midSql = " and MonitorId in (".join( ",", preg_split( '/["\'\s]*,["\'\s]*/', $user['MonitorIds'] ) ).")"; + else + $midSql = ''; - $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where ".dbEscape($sortColumn)." ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc'); - $result = dbQuery( $sql ); - while ( $id = dbFetchNext( $result, 'Id' ) ) - { - if ( $id == $eventId ) - { - $prevEvent = dbFetchNext( $result ); - break; - } + $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where ".dbEscape($sortColumn)." ".($sortOrder=='asc'?'<=':'>=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn ".($sortOrder=='asc'?'desc':'asc'); + $result = dbQuery( $sql ); + while ( $id = dbFetchNext( $result, 'Id' ) ) { + if ( $id == $eventId ) { + $prevEvent = dbFetchNext( $result ); + break; } + } - $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder"; - $result = dbQuery( $sql ); - while ( $id = dbFetchNext( $result, 'Id' ) ) - { - if ( $id == $eventId ) - { - $nextEvent = dbFetchNext( $result ); - break; - } + $sql = "select E.Id as Id from Events as E inner join Monitors as M on E.MonitorId = M.Id where $sortColumn ".($sortOrder=='asc'?'>=':'<=')." '".$event[$_REQUEST['sort_field']]."'".$_REQUEST['filter']['sql'].$midSql." order by $sortColumn $sortOrder"; + $result = dbQuery( $sql ); + while ( $id = dbFetchNext( $result, 'Id' ) ) { + if ( $id == $eventId ) { + $nextEvent = dbFetchNext( $result ); + break; } + } - $result = array( 'EventId'=>$eventId ); - $result['PrevEventId'] = empty($prevEvent)?0:$prevEvent['Id']; - $result['NextEventId'] = empty($nextEvent)?0:$nextEvent['Id']; - $result['PrevEventDefVideoPath'] = empty($prevEvent)?0:(getEventDefaultVideoPath($prevEvent)); - $result['NextEventDefVideoPath'] = empty($nextEvent)?0:(getEventDefaultVideoPath($nextEvent)); - return( $result ); + $result = array( 'EventId'=>$eventId ); + $result['PrevEventId'] = empty($prevEvent)?0:$prevEvent['Id']; + $result['NextEventId'] = empty($nextEvent)?0:$nextEvent['Id']; + $result['PrevEventDefVideoPath'] = empty($prevEvent)?0:(getEventDefaultVideoPath($prevEvent)); + $result['NextEventDefVideoPath'] = empty($nextEvent)?0:(getEventDefaultVideoPath($nextEvent)); + return( $result ); } ?> diff --git a/web/includes/Event.php b/web/includes/Event.php index d7842c96b..96d511f81 100644 --- a/web/includes/Event.php +++ b/web/includes/Event.php @@ -126,8 +126,10 @@ class Event { } # ! ZM_OPT_FAST_DELETE } # end Event->delete - public function getStreamSrc( $args, $querySep='&' ) { - return ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'}; + public function getStreamSrc( $args=array(), $querySep='&' ) { + if ( $this->{'DefaultVideo'} ) { + return ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'}; + } $streamSrc = ZM_BASE_URL.ZM_PATH_ZMS; @@ -217,12 +219,13 @@ class Event { return ''; } - $command ='ffmpeg -v 0 -i '.$videoPath.' -vf "select=gte(n\\,'.$frame['FrameId'].'),setpts=PTS-STARTPTS" '.$eventPath.'/'.$captImage; - Logger::Debug( "Running $command" ); + #$command ='ffmpeg -v 0 -i '.$videoPath.' -vf "select=gte(n\\,'.$frame['FrameId'].'),setpts=PTS-STARTPTS" '.$eventPath.'/'.$captImage; + $command ='ffmpeg -ss '. $frame['Delta'] .' -i '.$videoPath.' -frames:v 1 '.$eventPath.'/'.$captImage; + Debug( "Running $command" ); $output = array(); $retval = 0; exec( $command, $output, $retval ); - Logger::Debug("Retval: $retval, output: " . implode("\n", $output)); + Debug("Retval: $retval, output: " . implode("\n", $output)); } else { Error("Can't create frame images from video becuase there is no video file for this event (".$Event->DefaultVideo() ); } diff --git a/web/includes/Frame.php b/web/includes/Frame.php index d31ddf162..eaec94c58 100644 --- a/web/includes/Frame.php +++ b/web/includes/Frame.php @@ -34,7 +34,7 @@ class Frame { return new Event( $this->{'EventId'} ); } public function __call( $fn, array $args){ - if(isset($this->{$fn})){ + if( array_key_exists( $fn, $this ) ) { return $this->{$fn}; #array_unshift($args, $this); #call_user_func_array( $this->{$fn}, $args); @@ -70,7 +70,7 @@ class Frame { } public function getImageSrc( $show='capture' ) { - return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show;; + return $_SERVER['PHP_SELF'].'?view=image&fid='.$this->{'Id'}.'&show='.$show.'&filename='.$this->Event()->MonitorId().'_'.$this->{'EventId'}.'_'.$this->{'FrameId'}.'.jpg'; } // end function getImageSrc public static function find( $parameters = array(), $limit = NULL ) { diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index 6b983018e..9e4c6a95a 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -3,94 +3,238 @@ require_once( 'database.php' ); require_once( 'Server.php' ); class Monitor { - public function __construct( $IdOrRow ) { - $row = NULL; - if ( $IdOrRow ) { - if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) { - $row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) ); - if ( ! $row ) { - Error("Unable to load Server record for Id=" . $IdOrRow ); - } - } elseif ( is_array( $IdOrRow ) ) { - $row = $IdOrRow; - } else { - Error("Unknown argument passed to Monitor Constructor ($IdOrRow)"); - return; - } - } # end if isset($IdOrRow) - if ( $row ) { - foreach ($row as $k => $v) { - $this->{$k} = $v; - } - if ( $this->{'Controllable'} ) { - $s = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $this->{'ControlId'} ) ); - foreach ($s as $k => $v) { - if ( $k == 'Id' ) { - continue; - } - $this->{$k} = $v; - } - } +private $control_fields = array( + 'Name' => '', + 'Type' => 'Local', + 'Protocol' => NULL, + 'CanWake' => '0', + 'CanSleep' => '0', + 'CanReset' => '0', + 'CanZoom' => '0', + 'CanAutoZoom' => '0', + 'CanZoomAbs' => '0', + 'CanZoomRel' => '0', + 'CanZoomCon' => '0', + 'MinZoomRange' => NULL, + 'MaxZoomRange' => NULL, + 'MinZoomStep' => NULL, + 'MaxZoomStep' => NULL, + 'HasZoomSpeed' => '0', + 'MinZoomSpeed' => NULL, + 'MaxZoomSpeed' => NULL, + 'CanFocus' => '0', + 'CanAutoFocus' => '0', + 'CanFocusAbs' => '0', + 'CanFocusRel' => '0', + 'CanFocusCon' => '0', + 'MinFocusRange' => NULL, + 'MaxFocusRange' => NULL, + 'MinFocusStep' => NULL, + 'MaxFocusStep' => NULL, + 'HasFocusSpeed' => '0', + 'MinFocusSpeed' => NULL, + 'MaxFocusSpeed' => NULL, + 'CanIris' => '0', + 'CanAutoIris' => '0', + 'CanIrisAbs' => '0', + 'CanIrisRel' => '0', + 'CanIrisCon' => '0', + 'MinIrisRange' => NULL, + 'MaxIrisRange' => NULL, + 'MinIrisStep' => NULL, + 'MaxIrisStep' => NULL, + 'HasIrisSpeed' => '0', + 'MinIrisSpeed' => NULL, + 'MaxIrisSpeed' => NULL, + 'CanGain' => '0', + 'CanAutoGain' => '0', + 'CanGainAbs' => '0', + 'CanGainRel' => '0', + 'CanGainCon' => '0', + 'MinGainRange' => NULL, + 'MaxGainRange' => NULL, + 'MinGainStep' => NULL, + 'MaxGainStep' => NULL, + 'HasGainSpeed' => '0', + 'MinGainSpeed' => NULL, + 'MaxGainSpeed' => NULL, + 'CanWhite' => '0', + 'CanAutoWhite' => '0', + 'CanWhiteAbs' => '0', + 'CanWhiteRel' => '0', + 'CanWhiteCon' => '0', + 'MinWhiteRange' => NULL, + 'MaxWhiteRange' => NULL, + 'MinWhiteStep' => NULL, + 'MaxWhiteStep' => NULL, + 'HasWhiteSpeed' => '0', + 'MinWhiteSpeed' => NULL, + 'MaxWhiteSpeed' => NULL, + 'HasPresets' => '0', + 'NumPresets' => '0', + 'HasHomePreset' => '0', + 'CanSetPresets' => '0', + 'CanMove' => '0', + 'CanMoveDiag' => '0', + 'CanMoveMap' => '0', + 'CanMoveAbs' => '0', + 'CanMoveRel' => '0', + 'CanMoveCon' => '0', + 'CanPan' => '0', + 'MinPanRange' => NULL, + 'MaxPanRange' => NULL, + 'MinPanStep' => NULL, + 'MaxPanStep' => NULL, + 'HasPanSpeed' => '0', + 'MinPanSpeed' => NULL, + 'MaxPanSpeed' => NULL, + 'HasTurboPan' => '0', + 'TurboPanSpeed' => NULL, + 'CanTilt' => '0', + 'MinTiltRange' => NULL, + 'MaxTiltRange' => NULL, + 'MinTiltStep' => NULL, + 'MaxTiltStep' => NULL, + 'HasTiltSpeed' => '0', + 'MinTiltSpeed' => NULL, + 'MaxTiltSpeed' => NULL, + 'HasTurboTilt' => '0', + 'TurboTiltSpeed' => NULL, + 'CanAutoScan' => '0', + 'NumScanPaths' => '0', +); - } else { - Error("No row for Monitor " . $IdOrRow ); - } - } // end function __construct - public function Server() { - return new Server( $this->{'ServerId'} ); - } - public function __call( $fn, array $args){ - if(isset($this->{$fn})){ - return $this->{$fn}; - #array_unshift($args, $this); - #call_user_func_array( $this->{$fn}, $args); + public function __construct( $IdOrRow = NULL ) { + if ( $IdOrRow ) { + $row = NULL; + if ( is_integer( $IdOrRow ) or is_numeric( $IdOrRow ) ) { + $row = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array( $IdOrRow ) ); + if ( ! $row ) { + Error("Unable to load Server record for Id=" . $IdOrRow ); } - } - public function getStreamSrc( $args, $querySep='&' ) { - if ( isset($this->{'ServerId'}) and $this->{'ServerId'} ) { - $Server = new Server( $this->{'ServerId'} ); - $streamSrc = ZM_BASE_PROTOCOL.'://'.$Server->Hostname().ZM_PATH_ZMS; + } elseif ( is_array( $IdOrRow ) ) { + $row = $IdOrRow; + } else { + Error("Unknown argument passed to Monitor Constructor ($IdOrRow)"); + return; + } + + if ( $row ) { + foreach ($row as $k => $v) { + $this->{$k} = $v; + } + if ( $this->{'Controllable'} ) { + $s = dbFetchOne( 'SELECT * FROM Controls WHERE Id=?', NULL, array( $this->{'ControlId'} ) ); + foreach ($s as $k => $v) { + if ( $k == 'Id' ) { + continue; +# The reason for these is that the name overlaps Monitor fields. + } else if ( $k == 'Protocol' ) { + $this->{'ControlProtocol'} = $v; + } else if ( $k == 'Name' ) { + $this->{'ControlName'} = $v; + } else if ( $k == 'Type' ) { + $this->{'ControlType'} = $v; + } else { + $this->{$k} = $v; + } + } + } + + } else { + Error('No row for Monitor ' . $IdOrRow ); + } + } # end if isset($IdOrRow) + } // end function __construct + public function Server() { + return new Server( $this->{'ServerId'} ); + } + public function __call( $fn, array $args){ + if ( count( $args ) ) { + $this->{$fn} = $args[0]; + } + if ( array_key_exists( $fn, $this ) ) { + return $this->{$fn}; + #array_unshift($args, $this); + #call_user_func_array( $this->{$fn}, $args); } else { - $streamSrc = ZM_BASE_URL.ZM_PATH_ZMS; - } + if ( array_key_exists( $fn, $this->control_fields ) ) { + return $this->control_fields{$fn}; + } else { - $args[] = "monitor=".$this->{'Id'}; + $backTrace = debug_backtrace(); + $file = $backTrace[1]['file']; + $line = $backTrace[1]['line']; + Warning( "Unknown function call Monitor->$fn from $file:$line" ); + } + } + } - if ( ZM_OPT_USE_AUTH ) { - if ( ZM_AUTH_RELAY == "hashed" ) { - $args[] = "auth=".generateAuthHash( ZM_AUTH_HASH_IPS ); - } elseif ( ZM_AUTH_RELAY == "plain" ) { - $args[] = "user=".$_SESSION['username']; - $args[] = "pass=".$_SESSION['password']; - } elseif ( ZM_AUTH_RELAY == "none" ) { - $args[] = "user=".$_SESSION['username']; - } - } - if ( !in_array( "mode=single", $args ) && !empty($GLOBALS['connkey']) ) { - $args[] = "connkey=".$GLOBALS['connkey']; - } - if ( ZM_RAND_STREAM ) { - $args[] = "rand=".time(); - } + public function getStreamSrc( $args, $querySep='&' ) { + if ( isset($this->{'ServerId'}) and $this->{'ServerId'} ) { + $Server = new Server( $this->{'ServerId'} ); + $streamSrc = ZM_BASE_PROTOCOL.'://'.$Server->Hostname().ZM_PATH_ZMS; + } else { + $streamSrc = ZM_BASE_URL.ZM_PATH_ZMS; + } - if ( count($args) ) { - $streamSrc .= "?".join( $querySep, $args ); - } + $args['monitor'] = $this->{'Id'}; - return( $streamSrc ); - } // end function etStreamSrc - public function Width() { - if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) { - return $this->{'Height'}; - } - return $this->{'Width'}; - } - public function Height() { - if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) { - return $this->{'Width'}; - } - return $this->{'Height'}; - } + if ( ZM_OPT_USE_AUTH ) { + if ( ZM_AUTH_RELAY == 'hashed' ) { + $args['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS ); + } elseif ( ZM_AUTH_RELAY == 'plain' ) { + $args['user'] = $_SESSION['username']; + $args['pass'] = $_SESSION['password']; + } elseif ( ZM_AUTH_RELAY == 'none' ) { + $args['user'] = $_SESSION['username']; + } + } + if ( ( (!isset($args['mode'])) or ( $args['mode'] != 'single' ) ) && !empty($GLOBALS['connkey']) ) { + $args['connkey'] = $GLOBALS['connkey']; + } + if ( ZM_RAND_STREAM ) { + $args['rand'] = time(); + } + + if ( count($args) ) { + $streamSrc .= '?'.http_build_query( $args,'', $querySep ); + } + + return( $streamSrc ); + } // end function getStreamSrc + + public function Width() { + if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) { + return $this->{'Height'}; + } + return $this->{'Width'}; + } + + public function Height() { + if ( $this->Orientation() == '90' or $this->Orientation() == '270' ) { + return $this->{'Width'}; + } + return $this->{'Height'}; + } + + public function set( $data ) { + foreach ($data as $k => $v) { + if ( is_array( $v ) ) { + # perhaps should turn into a comma-separated string + $this->{$k} = implode(',',$v); + } else if ( is_string( $v ) ) { + $this->{$k} = trim( $v ); + } else if ( is_integer( $v ) ) { + $this->{$k} = $v; + } else if ( is_bool( $v ) ) { + $this->{$k} = $v; + } else { + Error( "Unknown type $k => $v of var " . gettype( $v ) ); + $this->{$k} = $v; + } + } + } } ?> diff --git a/web/includes/Server.php b/web/includes/Server.php index f303db0e5..fa892f8d9 100644 --- a/web/includes/Server.php +++ b/web/includes/Server.php @@ -47,7 +47,7 @@ class Server { return $this->{'Name'}; } public function __call( $fn, array $args= NULL){ - if(isset($this->{$fn})){ + if( array_key_exists( $fn, $this) ) { return $this->{$fn}; #array_unshift($args, $this); #call_user_func_array( $this->{$fn}, $args); diff --git a/web/includes/Storage.php b/web/includes/Storage.php index 81b9ad48c..940653404 100644 --- a/web/includes/Storage.php +++ b/web/includes/Storage.php @@ -65,6 +65,14 @@ class Storage { } public function disk_usage_percent() { $path = $this->Path(); + if ( ! $path ) { + Warning("Storage::disk_usage_percent: path is empty"); + return 0; + } else if ( ! file_exists( $path ) ) { + Warning("Storage::disk_usage_percent: path $path does not exist"); + return 0; + } + $total = disk_total_space( $path ); if ( ! $total ) { Error("disk_total_space returned false for " . $path ); diff --git a/web/includes/actions.php b/web/includes/actions.php index b751be6fd..d306c3bbc 100644 --- a/web/includes/actions.php +++ b/web/includes/actions.php @@ -23,12 +23,11 @@ // credit: http://wezfurlong.org/blog/2006/nov/http-post-from-php-without-curl/ -function do_post_request($url, $data, $optional_headers = null) -{ +function do_post_request($url, $data, $optional_headers = null) { $params = array('http' => array( - 'method' => 'POST', - 'content' => $data - )); + 'method' => 'POST', + 'content' => $data + )); if ($optional_headers !== null) { $params['http']['header'] = $optional_headers; } @@ -44,991 +43,864 @@ function do_post_request($url, $data, $optional_headers = null) return $response; } -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 ); +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'] ) ) + +if ( !empty($action) ) { + if ( $action == 'login' && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == 'remote' || isset($_REQUEST['password']) ) ) { + // if true, a popup will display after login + // 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) { - userLogin( $authUser['Username'], $authUser['Password'], true ); - } -} - -if ( !empty($action) ) -{ - if ( $action == "login" && isset($_REQUEST['username']) && ( ZM_AUTH_TYPE == "remote" || isset($_REQUEST['password']) ) ) - { - // if true, a popup will display after login - // 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) - { - $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'] - - ); - $res= do_post_request($url, http_build_query($fields)); - $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) - { - // 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'])) - { - Error ("reCaptcha authentication failed"); - userLogout(); - $view='login'; - $refreshParent = true; - } - else - { - //Let them login but show an error - echo ''; - Error ("Invalid recaptcha secret detected"); - - } - } - - } - - } - } - - // 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']); - $sql = "replace into Filters set Name = ".dbEscape($filterName).", Query = ".dbEscape(jsonEncode($_REQUEST['filter'])); - 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']); - if ( !empty($_REQUEST['background']) ) - $sql .= ", Background = ".dbEscape($_REQUEST['background']); - dbQuery( $sql ); - $refreshParent = true; - } - } - } - } - - // Event scope actions, edit permissions required - if ( canEdit( 'Events' ) ) - { - if ( $action == "rename" && isset($_REQUEST['eventName']) && !empty($_REQUEST['eid']) ) - { - dbQuery( 'UPDATE Events SET Name=? WHERE Id=?', array( $_REQUEST['eventName'], $_REQUEST['eid'] ) ); - } - else if ( $action == "eventdetail" ) - { - if ( !empty($_REQUEST['eid']) ) - { - dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['eid'] ) ); - $refreshParent = true; - } - else - { - foreach( getAffectedIds( 'markEid' ) as $markEid ) - { - dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $markEid ) ); - $refreshParent = true; - } - } - } - elseif ( $action == "archive" || $action == "unarchive" ) - { - $archiveVal = ($action == "archive")?1:0; - if ( !empty($_REQUEST['eid']) ) - { - dbQuery( 'UPDATE Events SET Archived=? WHERE Id=?', array( $archiveVal, $_REQUEST['eid']) ); - } - else - { - foreach( getAffectedIds( 'markEid' ) as $markEid ) - { - dbQuery( 'UPDATE Events SET Archived=? WHERE Id=?', array( $archiveVal, $markEid ) ); - $refreshParent = true; - } - } - } - elseif ( $action == "delete" ) - { - foreach( getAffectedIds( 'markEid' ) as $markEid ) - { - deleteEvent( $markEid ); - $refreshParent = true; - } - if ( !empty($_REQUEST['fid']) ) - { - dbQuery( 'DELETE FROM Filters WHERE Name=?', array( $_REQUEST['fid'] ) ); - //$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' ); - require_once( 'Monitor.php' ); - $mid = validInt($_REQUEST['mid']); - if ( $action == "control" ) - { - $monitor = new Monitor( $mid ); - - $ctrlCommand = buildControlCommand( $monitor ); - sendControlCommand( $monitor->Id(), $ctrlCommand ); - } - elseif ( $action == "settings" ) - { - $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 ); - list( $brightness, $contrast, $hue, $colour ) = explode( ' ', $zmuOutput ); - dbQuery( "update Monitors set Brightness = ?, Contrast = ?, Hue = ?, Colour = ? where Id = ?", array($brightness, $contrast, $hue, $colour, $mid)); - } - } - - // Control capability actions, require control edit permissions - if ( canEdit( 'Control' ) ) - { - if ( $action == "controlcap" ) - { - if ( !empty($_REQUEST['cid']) ) - { - $control = dbFetchOne( "select * from Controls where Id = ?", NULL, array($_REQUEST['cid']) ); - } - 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']) ) - { - dbQuery( "update Controls set ".implode( ", ", $changes )." where Id = ?", array($_REQUEST['cid']) ); - } - 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 ) - { - dbQuery( "delete from Controls where Id = ?", array($markCid) ); - dbQuery( "update Monitors set Controllable = 0, ControlId = 0 where ControlId = ?", array($markCid) ); - $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" ) - { - $monitor = dbFetchOne( "SELECT * FROM Monitors WHERE Id=?", NULL, array($mid) ); - - $newFunction = validStr($_REQUEST['newFunction']); - # 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'; - - $oldFunction = $monitor['Function']; - $oldEnabled = $monitor['Enabled']; - if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) - { - dbQuery( "update Monitors set Function=?, Enabled=? where Id=?", array( $newFunction, $newEnabled, $mid ) ); - - $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']); - $monitor = dbFetchOne( "SELECT * FROM Monitors WHERE Id=?", NULL, array($mid) ); - - if ( !empty($zid) ) - { - $zone = dbFetchOne( "SELECT * FROM Zones WHERE MonitorId=? AND Id=?", NULL, array( $mid, $zid ) ); - } - 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 ) - { - dbQuery( "UPDATE Zones SET ".implode( ", ", $changes )." WHERE MonitorId=? AND Id=?", array( $mid, $zid) ); - } - else - { - dbQuery( "INSERT INTO Zones SET MonitorId=?, ".implode( ", ", $changes ), array( $mid ) ); - } - //if ( $cookies ) session_write_close(); - if ( daemonCheck() ) - { - 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' ); - } - $refreshParent = true; - } - $view = 'none'; - } - elseif ( $action == "plugin" && isset($_REQUEST['pl'])) - { - $sql="SELECT * FROM PluginsConfig WHERE MonitorId=? AND ZoneId=? AND pluginName=?"; - $pconfs=dbFetchAll( $sql, NULL, array( $mid, $_REQUEST['zid'], $_REQUEST['pl'] ) ); - $changes=0; - foreach( $pconfs as $pconf ) - { - $value=$_REQUEST['pluginOpt'][$pconf['Name']]; - if(array_key_exists($pconf['Name'], $_REQUEST['pluginOpt']) && ($pconf['Value']!=$value)) - { - dbQuery("UPDATE PluginsConfig SET Value=? WHERE id=?", array( $value, $pconf['Id'] ) ); - $changes++; - } - } - if($changes>0) - { - if ( daemonCheck() ) - { - zmaControl( $mid, "restart" ); - } - $refreshParent = true; - } - $view = 'none'; - } - elseif ( $action == "sequence" && isset($_REQUEST['smid']) ) - { - $smid = validInt($_REQUEST['smid']); - $monitor = dbFetchOne( "select * from Monitors where Id = ?", NULL, array($mid) ); - $smonitor = dbFetchOne( "select * from Monitors where Id = ?", NULL, array($smid) ); - - dbQuery( "update Monitors set Sequence=? where Id=?", array( $smonitor['Sequence'], $monitor['Id'] ) ); - dbQuery( "update Monitors set Sequence=? WHERE Id=?", array( $monitor['Sequence'], $smonitor['Id'] ) ); - + $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'] + ); + $res= do_post_request($url, http_build_query($fields)); + $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) { + // 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'])) { + Error ('reCaptcha authentication failed'); + userLogout(); + $view='login'; $refreshParent = true; - fixSequences(); + } else { + //Let them login but show an error + echo ''; + Error ("Invalid recaptcha secret detected"); + } } - if ( $action == "delete" ) - { - if ( isset($_REQUEST['markZids']) ) - { - $deletedZid = 0; - foreach( $_REQUEST['markZids'] as $markZid ) - { - $zone = dbFetchOne( "select * from Zones where Id=?", NULL, array($markZid) ); - dbQuery( "delete from Zones WHERE MonitorId=? AND Id=?", array( $mid, $markZid) ); - $deletedZid = 1; - } - if ( $deletedZid ) - { - //if ( $cookies ) - //session_write_close(); - if ( daemonCheck() ) - if ( $zone['Type'] == 'Privacy' ) - { - zmaControl( $mid, "stop" ); - zmcControl( $mid, "restart" ); - zmaControl( $mid, "start" ); - } - else - { - zmaControl( $mid, "restart" ); - } - $refreshParent = true; - } - } + } // end if success==false + + } // end if using reCaptcha + + $username = validStr( $_REQUEST['username'] ); + $password = isset($_REQUEST['password'])?validStr($_REQUEST['password']):''; + userLogin( $username, $password ); + $refreshParent = true; + $view = 'console'; + $redirect = true; + } else if ( $action == 'logout' ) { + userLogout(); + $refreshParent = true; + $view = 'none'; + } else if ( $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' ) ) { + $sql = ''; + $endSql = ''; + $filterName = ''; + if ( !empty($_REQUEST['execute']) ) { + // TempFilterName is used in event listing later on + $tempFilterName = $filterName = '_TempFilter'.time(); + } elseif ( !empty($_REQUEST['newFilterName']) ) { + $filterName = $_REQUEST['newFilterName']; } - } - - // 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']); - $monitor = dbFetchOne( "select * from Monitors where Id = ?", NULL, array($mid) ); - - if ( ZM_OPT_X10 ) - { - $x10Monitor = dbFetchOne( "select * from TriggersX10 where MonitorId=?", NULL, array($mid) ); - 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', - 'DoNativeMotDet' => 'toggle', - 'Exif' => 'toggle', - 'RTSPDescribe' => 'toggle', - 'RecordAudio' => 'toggle', - ); - - $columns = getTableColumns( 'Monitors' ); - $changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns ); - - if ( count( $changes ) ) - { - if ( !empty($_REQUEST['mid']) ) - { - $mid = validInt($_REQUEST['mid']); - dbQuery( "update Monitors set ".implode( ", ", $changes )." where Id =?", array($mid) ); - if ( isset($changes['Name']) ) - { - $saferOldName = basename( $monitor['Name'] ); - $saferNewName = basename( $_REQUEST['newMonitor']['Name'] ); - rename( ZM_DIR_EVENTS."/".$saferOldName, ZM_DIR_EVENTS."/".$saferNewName); - } - 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; - - $zones = dbFetchAll( "select * from Zones where MonitorId=?", NULL, array($mid) ); - 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 ) ) - { - dbQuery( "update Zones set ".implode( ", ", $changes )." WHERE MonitorId=? AND Id=?", array( $mid, $zone['Id'] ) ); - } - } - } - } - elseif ( !$user['MonitorIds'] ) - { - # FIXME This is actually a race condition. Should lock the table. - $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']; - 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) ) ); - //$view = 'none'; - mkdir( ZM_DIR_EVENTS.'/'.$mid, 0755 ); - $saferName = basename($_REQUEST['newMonitor']['Name']); - symlink( $mid, ZM_DIR_EVENTS.'/'.$saferName ); - if ( isset($_COOKIE['zmGroup']) ) - { - dbQuery( "UPDATE Groups SET MonitorIds = concat(MonitorIds,',".$mid."') WHERE Id=?", array($_COOKIE['zmGroup']) ); - } - } - $restart = true; - } - - if ( ZM_OPT_X10 ) - { - $x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] ); - - if ( count( $x10Changes ) ) - { - if ( $x10Monitor && isset($_REQUEST['newX10Monitor']) ) - { - dbQuery( "update TriggersX10 set ".implode( ", ", $x10Changes )." where MonitorId=?", array($mid) ); - } - elseif ( !$user['MonitorIds'] ) - { - if ( !$x10Monitor ) - { - dbQuery( "insert into TriggersX10 set MonitorId = ?,".implode( ", ", $x10Changes ), array( $mid ) ); - } - else - { - dbQuery( "delete from TriggersX10 where MonitorId = ?", array($mid) ); - } - } - $restart = true; - } - } - - if ( $restart ) - { - $monitor = dbFetchOne( "select * from Monitors where Id = ?", NULL, array($mid) ); - //fixDevices(); - //if ( $cookies ) - //session_write_close(); - if ( daemonCheck() ) - { - zmaControl( $monitor, "stop" ); - zmcControl( $monitor, "restart" ); - zmaControl( $monitor, "start" ); - } - if ( $monitor['Controllable'] ) { - require_once( 'control_functions.php' ); - sendControlCommand( $mid, 'quit' ); - } - //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 ) ) - { - if ( $monitor = dbFetchOne( "select * from Monitors where Id = ?", NULL, array($markMid) ) ) - { - if ( daemonCheck() ) - { - zmaControl( $monitor, "stop" ); - zmcControl( $monitor, "stop" ); - } - - // This is the important stuff - dbQuery( "delete from Monitors where Id = ?", array($markMid) ); - dbQuery( "delete from Zones where MonitorId = ?", array($markMid) ); - if ( ZM_OPT_X10 ) - dbQuery( "delete from TriggersX10 where MonitorId=?", array($markMid) ); - - 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 ) - { - // 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) ); - foreach( $markEids as $markEid ) - deleteEvent( $markEid, $markMid ); - - deletePath( ZM_DIR_EVENTS."/".basename($monitor['Name']) ); - deletePath( ZM_DIR_EVENTS."/".$monitor['Id'] ); // I'm trusting the Id. - } - } - } - } - } - } - } - - // 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']) ) - { - dbQuery( "update Devices set Name=?, KeyString=? where Id=?", array($_REQUEST['newDevice']['Name'], $_REQUEST['newDevice']['KeyString'], $_REQUEST['did']) ); - } - else - { - dbQuery( "insert into Devices set Name=?, KeyString=?", array( $_REQUEST['newDevice']['Name'], $_REQUEST['newDevice']['KeyString'] ) ); - } - $refreshParent = true; - $view = 'none'; - } - } - elseif ( $action == "delete" ) - { - if ( isset($_REQUEST['markDids']) ) - { - foreach( $_REQUEST['markDids'] as $markDid ) - { - dbQuery( "delete from Devices where Id=?", array($markDid) ); - $refreshParent = true; - } - } - } - } - - // Group view actions - if ( canView( 'Groups' ) && $action == "setgroup" ) { - if ( !empty($_REQUEST['gid']) ) { - setcookie( "zmGroup", validInt($_REQUEST['gid']), time()+3600*24*30*12*10 ); + if ( $filterName ) { + # Replace will teplace any filter with the same Id + # Since we aren't specifying the Id , this is effectively an insert + $sql = 'REPLACE INTO Filters SET Name = '.dbEscape($filterName).','; } else { - setcookie( "zmGroup", "", time()-3600*24*2 ); + $sql = 'UPDATE Filters SET'; + $endSql = 'WHERE Id = '.$_REQUEST['Id']; } - $refreshParent = true; - } - // Group edit actions - 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']) ); + # endSql is only set if ! filterName... so... woulnd't this always be true + if ( !empty($filterName) || $endSql ) { + $_REQUEST['filter']['sort_field'] = validStr($_REQUEST['sort_field']); + $_REQUEST['filter']['sort_asc'] = validStr($_REQUEST['sort_asc']); + $_REQUEST['filter']['limit'] = validInt($_REQUEST['limit']); + $sql .= ' Query = '.dbEscape(jsonEncode($_REQUEST['filter'])); + 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']); + if ( !empty($_REQUEST['background']) ) + $sql .= ', Background = '.dbEscape($_REQUEST['background']); + if ( !empty($_REQUEST['concurrent']) ) + $sql .= ', Concurrent = '.dbEscape($_REQUEST['concurrent']); + $sql .= $endSql; + dbQuery( $sql ); + if ( $filterName ) { + $filter = dbFetchOne( 'SELECT * FROM Filters WHERE Name=?', NULL, array($filterName) ); + if ( $filter ) { + # This won't work yet because refreshparent refreshes the old filter. Need to do a redirect instead of a refresh. + $_REQUEST['Id'] = $filter['Id']; } else { - dbQuery( "INSERT INTO Groups SET Name=?, MonitorIds=?", array( $_POST['newGroup']['Name'], $monitors ) ); + Error("No new Id despite new name"); } - $view = 'none'; + } + $refreshParent = '/index.php?view=filter&Id='.$_REQUEST['Id']; } - 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; - } - } + } // end if canedit events + } // end if action == filter + } // end if canview events + + // Event scope actions, edit permissions required + if ( canEdit( 'Events' ) ) { + if ( $action == 'rename' && isset($_REQUEST['eventName']) && !empty($_REQUEST['eid']) ) { + dbQuery( 'UPDATE Events SET Name=? WHERE Id=?', array( $_REQUEST['eventName'], $_REQUEST['eid'] ) ); + } else if ( $action == 'eventdetail' ) { + if ( !empty($_REQUEST['eid']) ) { + dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $_REQUEST['eid'] ) ); + $refreshParent = true; + } else { + foreach( getAffectedIds( 'markEid' ) as $markEid ) { + dbQuery( 'UPDATE Events SET Cause=?, Notes=? WHERE Id=?', array( $_REQUEST['newEvent']['Cause'], $_REQUEST['newEvent']['Notes'], $markEid ) ); + $refreshParent = true; + } + } + } elseif ( $action == 'archive' || $action == 'unarchive' ) { + $archiveVal = ($action == 'archive')?1:0; + if ( !empty($_REQUEST['eid']) ) { + dbQuery( 'UPDATE Events SET Archived=? WHERE Id=?', array( $archiveVal, $_REQUEST['eid']) ); + } else { + foreach( getAffectedIds( 'markEid' ) as $markEid ) { + dbQuery( 'UPDATE Events SET Archived=? WHERE Id=?', array( $archiveVal, $markEid ) ); + $refreshParent = true; + } + } + } elseif ( $action == 'delete' ) { + foreach( getAffectedIds( 'markEid' ) as $markEid ) { + deleteEvent( $markEid ); + $refreshParent = true; + } + if ( isset( $_REQUEST['object'] ) and ( $_REQUEST['object'] == 'filter' ) ) { + if ( !empty($_REQUEST['Id']) ) { + dbQuery( 'DELETE FROM Filters WHERE Id=?', array( $_REQUEST['Id'] ) ); + //$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' ); + require_once( 'Monitor.php' ); + $mid = validInt($_REQUEST['mid']); + if ( $action == 'control' ) { + $monitor = new Monitor( $mid ); + + $ctrlCommand = buildControlCommand( $monitor ); + sendControlCommand( $monitor->Id(), $ctrlCommand ); + } elseif ( $action == 'settings' ) { + $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 ); + list( $brightness, $contrast, $hue, $colour ) = explode( ' ', $zmuOutput ); + dbQuery( 'UPDATE Monitors SET Brightness = ?, Contrast = ?, Hue = ?, Colour = ? WHERE Id = ?', array($brightness, $contrast, $hue, $colour, $mid)); + } + } + + // Control capability actions, require control edit permissions + if ( canEdit( 'Control' ) ) { + if ( $action == 'controlcap' ) { + if ( !empty($_REQUEST['cid']) ) { + $control = dbFetchOne( 'SELECT * FROM Controls WHERE Id = ?', NULL, array($_REQUEST['cid']) ); + } 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']) ) { + dbQuery( "update Controls set ".implode( ", ", $changes )." where Id = ?", array($_REQUEST['cid']) ); + } 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 ) { + dbQuery( "delete from Controls where Id = ?", array($markCid) ); + dbQuery( "update Monitors set Controllable = 0, ControlId = 0 where ControlId = ?", array($markCid) ); + $refreshParent = true; + } + } } + } - // System edit actions - if ( canEdit( 'System' ) ) - { - if ( isset( $_REQUEST['object'] ) and ( $_REQUEST['object'] == 'server' ) ) { + // 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' ) { + $monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array($mid) ); - if ( $action == "Save" ) { - if ( !empty($_REQUEST['id']) ) - $dbServer = dbFetchOne( "SELECT * FROM Servers WHERE Id=?", NULL, array($_REQUEST['id']) ); - else - $dbServer = array(); + $newFunction = validStr($_REQUEST['newFunction']); + # 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'; + $oldFunction = $monitor['Function']; + $oldEnabled = $monitor['Enabled']; + if ( $newFunction != $oldFunction || $newEnabled != $oldEnabled ) { + dbQuery( 'UPDATE Monitors SET Function=?, Enabled=? WHERE Id=?', array( $newFunction, $newEnabled, $mid ) ); - $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; - } else { - Error( "Unknown action $action in saving Server" ); - } - - } else if ( $action == "version" && isset($_REQUEST['option']) ) - { - $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; - } - } + $monitor['Function'] = $newFunction; + $monitor['Enabled'] = $newEnabled; + if ( daemonCheck() ) { + $restart = ($oldFunction == 'None') || ($newFunction == 'None') || ($newEnabled != $oldEnabled); + zmaControl( $monitor, 'stop' ); + zmcControl( $monitor, $restart?'restart':'' ); + zmaControl( $monitor, 'start' ); } - 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; - } - } + $refreshParent = true; + } + } elseif ( $action == 'zone' && isset( $_REQUEST['zid'] ) ) { + $zid = validInt($_REQUEST['zid']); + $monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id=?', NULL, array($mid) ); + + if ( !empty($zid) ) { + $zone = dbFetchOne( 'SELECT * FROM Zones WHERE MonitorId=? AND Id=?', NULL, array( $mid, $zid ) ); + } 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 ) { + dbQuery( "UPDATE Zones SET ".implode( ", ", $changes )." WHERE MonitorId=? AND Id=?", array( $mid, $zid) ); + } else { + dbQuery( "INSERT INTO Zones SET MonitorId=?, ".implode( ", ", $changes ), array( $mid ) ); } - 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']) ) - { - dbQuery( 'UPDATE Config SET Value=? WHERE Name=?', array( $newValue, $name ) ); - $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']) ) - $dbUser = dbFetchOne( "SELECT * FROM Users WHERE Id=?", NULL, array($_REQUEST['uid']) ); - else - $dbUser = array(); - - $types = array(); - $changes = getFormChanges( $dbUser, $_REQUEST['newUser'], $types ); - - if ( $_REQUEST['newUser']['Password'] ) - $changes['Password'] = "Password = password(".dbEscape($_REQUEST['newUser']['Password']).")"; - else - unset( $changes['Password'] ); - - if ( count( $changes ) ) - { - if ( !empty($_REQUEST['uid']) ) - { - dbQuery( "update Users set ".implode( ", ", $changes )." where Id = ?", array($_REQUEST['uid']) ); - } - else - { - dbQuery( "insert into Users set ".implode( ", ", $changes ) ); - } - $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']; - dbQuery( "replace into States set Name=?, Definition=?", array( $_REQUEST['runState'],$definition) ); - } - } - elseif ( $action == "delete" ) - { - if ( isset($_REQUEST['runState']) ) - dbQuery( "delete from States where Name=?", array($_REQUEST['runState']) ); - - if ( isset($_REQUEST['markUids']) ) - { - foreach( $_REQUEST['markUids'] as $markUid ) - dbQuery( "delete from Users where Id = ?", array($markUid) ); - if ( $markUid == $user['Id'] ) - userLogout(); - } - } - } - else - { - if ( ZM_USER_SELF_EDIT && $action == "user" ) - { - $uid = $user['Id']; - - $dbUser = dbFetchOne( "select Id, Password, Language from Users where Id = ?", NULL, array($uid) ); - - $types = array(); - $changes = getFormChanges( $dbUser, $_REQUEST['newUser'], $types ); - - if ( !empty($_REQUEST['newUser']['Password']) ) - $changes['Password'] = "Password = password(".dbEscape($_REQUEST['newUser']['Password']).")"; - else - unset( $changes['Password'] ); - if ( count( $changes ) ) - { - dbQuery( "update Users set ".implode( ", ", $changes )." where Id=?", array($uid) ); - $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(); + if ( daemonCheck() ) { + 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' ); + } + $refreshParent = true; + } + $view = 'none'; + } elseif ( $action == 'plugin' && isset($_REQUEST['pl'])) { + $sql='SELECT * FROM PluginsConfig WHERE MonitorId=? AND ZoneId=? AND pluginName=?'; + $pconfs=dbFetchAll( $sql, NULL, array( $mid, $_REQUEST['zid'], $_REQUEST['pl'] ) ); + $changes=0; + foreach( $pconfs as $pconf ) { + $value=$_REQUEST['pluginOpt'][$pconf['Name']]; + if(array_key_exists($pconf['Name'], $_REQUEST['pluginOpt']) && ($pconf['Value']!=$value)) { + dbQuery("UPDATE PluginsConfig SET Value=? WHERE id=?", array( $value, $pconf['Id'] ) ); + $changes++; + } + } + if($changes>0) { + if ( daemonCheck() ) { + zmaControl( $mid, 'restart' ); + } + $refreshParent = true; + } + $view = 'none'; + } elseif ( $action == 'sequence' && isset($_REQUEST['smid']) ) { + $smid = validInt($_REQUEST['smid']); + $monitor = dbFetchOne( 'select * from Monitors where Id = ?', NULL, array($mid) ); + $smonitor = dbFetchOne( 'select * from Monitors where Id = ?', NULL, array($smid) ); + + dbQuery( 'update Monitors set Sequence=? where Id=?', array( $smonitor['Sequence'], $monitor['Id'] ) ); + dbQuery( 'update Monitors set Sequence=? WHERE Id=?', array( $monitor['Sequence'], $smonitor['Id'] ) ); + + $refreshParent = true; + fixSequences(); + } elseif ( $action == 'delete' ) { + if ( isset($_REQUEST['markZids']) ) { + $deletedZid = 0; + foreach( $_REQUEST['markZids'] as $markZid ) { + $zone = dbFetchOne( 'select * from Zones where Id=?', NULL, array($markZid) ); + dbQuery( 'delete from Zones WHERE MonitorId=? AND Id=?', array( $mid, $markZid) ); + $deletedZid = 1; + } + if ( $deletedZid ) { + //if ( $cookies ) + //session_write_close(); + if ( daemonCheck() ) { + if ( $zone['Type'] == 'Privacy' ) { + zmaControl( $mid, 'stop' ); + zmcControl( $mid, 'restart' ); + zmaControl( $mid, 'start' ); + } else { + zmaControl( $mid, 'restart' ); + } + } // end if daemonCheck() + $refreshParent = true; + } // end if deletedzid + } // end if isset($_REQUEST['markZids']) + } // end if action + } // end if $mid and canEdit($mid) + + // Monitor edit actions, monitor id derived, require edit permissions for that monitor + if ( canEdit( 'Monitors' ) ) { + if ( $action == 'monitor' ) { + $mid = 0; + if ( !empty($_REQUEST['mid']) ) { + $mid = validInt($_REQUEST['mid']); + $monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id = ?', NULL, array($mid) ); + + if ( ZM_OPT_X10 ) { + $x10Monitor = dbFetchOne( 'SELECT * FROM TriggersX10 WHERE MonitorId=?', NULL, array($mid) ); + 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', + 'DoNativeMotDet' => 'toggle', + 'Exif' => 'toggle', + 'RTSPDescribe' => 'toggle', + 'RecordAudio' => 'toggle', + ); + + $columns = getTableColumns( 'Monitors' ); + $changes = getFormChanges( $monitor, $_REQUEST['newMonitor'], $types, $columns ); + + if ( count( $changes ) ) { + if ( $mid ) { + + # If we change anything that changes the shared mem size, zma can complain. So let's stop first. + zmaControl( $monitor, 'stop' ); + zmcControl( $monitor, 'stop' ); + dbQuery( 'UPDATE Monitors SET '.implode( ", ", $changes ).' WHERE Id =?', array($mid) ); + if ( isset($changes['Name']) ) { + $saferOldName = basename( $monitor['Name'] ); + $saferNewName = basename( $_REQUEST['newMonitor']['Name'] ); + rename( ZM_DIR_EVENTS."/".$saferOldName, ZM_DIR_EVENTS."/".$saferNewName); + } + 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; + + $zones = dbFetchAll( 'SELECT * FROM Zones WHERE MonitorId=?', NULL, array($mid) ); + 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 ) ) { + dbQuery( "update Zones set ".implode( ", ", $changes )." WHERE MonitorId=? AND Id=?", array( $mid, $zone['Id'] ) ); + } + } + } + } elseif ( ! $user['MonitorIds'] ) { // Can only create new monitors if we are not restricted to specific monitors +# FIXME This is actually a race condition. Should lock the table. + $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']; + 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) ) ); + //$view = 'none'; + mkdir( ZM_DIR_EVENTS.'/'.$mid, 0755 ); + $saferName = basename($_REQUEST['newMonitor']['Name']); + symlink( $mid, ZM_DIR_EVENTS.'/'.$saferName ); + if ( isset($_COOKIE['zmGroup']) ) { + dbQuery( "UPDATE Groups SET MonitorIds = concat(MonitorIds,',".$mid."') WHERE Id=?", array($_COOKIE['zmGroup']) ); + } + } else { + Error("Users with Monitors restrictions cannot create new monitors."); + } + $restart = true; + } + + if ( ZM_OPT_X10 ) { + $x10Changes = getFormChanges( $x10Monitor, $_REQUEST['newX10Monitor'] ); + + if ( count( $x10Changes ) ) { + if ( $x10Monitor && isset($_REQUEST['newX10Monitor']) ) { + dbQuery( "update TriggersX10 set ".implode( ", ", $x10Changes )." where MonitorId=?", array($mid) ); + } elseif ( !$user['MonitorIds'] ) { + if ( !$x10Monitor ) { + dbQuery( "insert into TriggersX10 set MonitorId = ?, ".implode( ", ", $x10Changes ), array( $mid ) ); + } else { + dbQuery( "delete from TriggersX10 where MonitorId = ?", array($mid) ); + } + } + $restart = true; + } + } + + if ( $restart ) { + $new_monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id = ?', NULL, array($mid) ); + //fixDevices(); + //if ( $cookies ) + //session_write_close(); + + zmcControl( $new_monitor, 'start' ); + zmaControl( $new_monitor, 'start' ); + + if ( $monitor['Controllable'] ) { + require_once( 'control_functions.php' ); + sendControlCommand( $mid, 'quit' ); + } + // really should thump zmwatch and maybe zmtrigger too. + //daemonControl( 'restart', 'zmwatch.pl' ); + $refreshParent = true; + } // end if restart + $view = 'none'; } + if ( $action == 'delete' ) { + if ( isset($_REQUEST['markMids']) && !$user['MonitorIds'] ) { + foreach( $_REQUEST['markMids'] as $markMid ) { + if ( canEdit( 'Monitors', $markMid ) ) { + if ( $monitor = dbFetchOne( 'SELECT * FROM Monitors WHERE Id = ?', NULL, array($markMid) ) ) { + if ( daemonCheck() ) { + zmaControl( $monitor, 'stop' ); + zmcControl( $monitor, 'stop' ); + } + + // This is the important stuff + dbQuery( 'DELETE FROM Monitors WHERE Id = ?', array($markMid) ); + dbQuery( 'DELETE FROM Zones WHERE MonitorId = ?', array($markMid) ); + if ( ZM_OPT_X10 ) + dbQuery( 'DELETE FROM TriggersX10 WHERE MonitorId=?', array($markMid) ); + + 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 ) { + // 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) ); + foreach( $markEids as $markEid ) + deleteEvent( $markEid, $markMid ); + + deletePath( ZM_DIR_EVENTS.'/'.basename($monitor['Name']) ); + deletePath( ZM_DIR_EVENTS.'/'.$monitor['Id'] ); // I'm trusting the Id. + } // end if ZM_OPT_FAST_DELETE + } // end if found the monitor in the db + } // end if canedit this monitor + } // end foreach monitor in MarkMid + } // markMids is set and we aren't limited to specific monitors + } // end if action == Delete + } + + // 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']) ) { + dbQuery( "update Devices set Name=?, KeyString=? where Id=?", array($_REQUEST['newDevice']['Name'], $_REQUEST['newDevice']['KeyString'], $_REQUEST['did']) ); + } else { + dbQuery( "insert into Devices set Name=?, KeyString=?", array( $_REQUEST['newDevice']['Name'], $_REQUEST['newDevice']['KeyString'] ) ); + } + $refreshParent = true; + $view = 'none'; + } + } elseif ( $action == 'delete' ) { + if ( isset($_REQUEST['markDids']) ) { + foreach( $_REQUEST['markDids'] as $markDid ) { + dbQuery( "delete from Devices where Id=?", array($markDid) ); + $refreshParent = true; + } + } + } // end if action + } // end if canedit devices + + // Group view actions + 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 + 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; + } + } + } + $refreshParent = true; + } // end if can edit groups + + // System edit actions + if ( canEdit( 'System' ) ) { + if ( isset( $_REQUEST['object'] ) ) { + if ( $_REQUEST['object'] == 'server' ) { + + if ( $action == 'Save' ) { + 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; + } else { + Error( "Unknown action $action in saving Server" ); + } + } else if ( $_REQUEST['object'] == 'storage' ) { + if ( $action == 'Save' ) { + if ( !empty($_REQUEST['id']) ) + $dbStorage = dbFetchOne( 'SELECT * FROM Storage WHERE Id=?', NULL, array($_REQUEST['id']) ); + else + $dbStorage = array(); + + $types = array(); + $changes = getFormChanges( $dbStorage, $_REQUEST['newStorage'], $types ); + + if ( count( $changes ) ) { + if ( !empty($_REQUEST['id']) ) { + dbQuery( "UPDATE Storage SET ".implode( ", ", $changes )." WHERE Id = ?", array($_REQUEST['id']) ); + } else { + dbQuery( "INSERT INTO Storage set ".implode( ", ", $changes ) ); + } + $refreshParent = true; + } + $view = 'none'; + } else if ( $action == 'delete' ) { + if ( !empty($_REQUEST['markIds']) ) { + foreach( $_REQUEST['markIds'] as $Id ) + dbQuery( 'DELETE FROM Storage WHERE Id=?', array($Id) ); + } + $refreshParent = true; + } else { + Error( "Unknown action $action in saving Storage" ); + } + } # end if isset($_REQUEST['object'] ) + + } else if ( $action == 'version' && isset($_REQUEST['option']) ) { + $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; + } + } // end switch option + } + 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']) ) { + dbQuery( 'UPDATE Config SET Value=? WHERE Name=?', array( $newValue, $name ) ); + $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']) ) + $dbUser = dbFetchOne( "SELECT * FROM Users WHERE Id=?", NULL, array($_REQUEST['uid']) ); + else + $dbUser = array(); + + $types = array(); + $changes = getFormChanges( $dbUser, $_REQUEST['newUser'], $types ); + + if ( $_REQUEST['newUser']['Password'] ) + $changes['Password'] = "Password = password(".dbEscape($_REQUEST['newUser']['Password']).")"; + else + unset( $changes['Password'] ); + + if ( count( $changes ) ) { + if ( !empty($_REQUEST['uid']) ) { + dbQuery( "update Users set ".implode( ", ", $changes )." where Id = ?", array($_REQUEST['uid']) ); + # If we are updating the logged in user, then update our session user data. + if ( $user and ( $dbUser['Username'] == $user['Username'] ) ) + userLogin( $dbUser['Username'], $dbUser['Password'] ); + } else { + dbQuery( "insert into Users set ".implode( ", ", $changes ) ); + } + $refreshParent = true; + } + $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']; + dbQuery( "replace into States set Name=?, Definition=?", array( $_REQUEST['runState'],$definition) ); + } + } elseif ( $action == 'delete' ) { + if ( isset($_REQUEST['runState']) ) + dbQuery( "delete from States where Name=?", array($_REQUEST['runState']) ); + + if ( isset($_REQUEST['markUids']) ) { + foreach( $_REQUEST['markUids'] as $markUid ) + dbQuery( "delete from Users where Id = ?", array($markUid) ); + if ( $markUid == $user['Id'] ) + userLogout(); + } + } + } else { + if ( ZM_USER_SELF_EDIT && $action == 'user' ) { + $uid = $user['Id']; + + $dbUser = dbFetchOne( 'SELECT Id, Password, Language FROM Users WHERE Id = ?', NULL, array($uid) ); + + $types = array(); + $changes = getFormChanges( $dbUser, $_REQUEST['newUser'], $types ); + + if ( !empty($_REQUEST['newUser']['Password']) ) + $changes['Password'] = "Password = password(".dbEscape($_REQUEST['newUser']['Password']).")"; + else + unset( $changes['Password'] ); + if ( count( $changes ) ) { + dbQuery( "update Users set ".implode( ", ", $changes )." where Id=?", array($uid) ); + $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(); + } } ?> diff --git a/web/includes/database.php b/web/includes/database.php index 8335357b2..40cd8950b 100644 --- a/web/includes/database.php +++ b/web/includes/database.php @@ -26,351 +26,314 @@ $GLOBALS['dbLogLevel'] = DB_LOG_OFF; $GLOBALS['dbConn'] = false; -function dbConnect() -{ - global $dbConn; +function dbConnect() { + global $dbConn; - if (strpos(ZM_DB_HOST, ':')) { - // Host variable may carry a port or socket. - list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2); - if (ctype_digit($portOrSocket)) { - $socket = ':host='.$host . ';port='.$portOrSocket; - } else { - $socket = ':unix_socket='.$portOrSocket; - } - } else { - $socket = ':host='.ZM_DB_HOST; - } + if (strpos(ZM_DB_HOST, ':')) { + // Host variable may carry a port or socket. + list($host, $portOrSocket) = explode(':', ZM_DB_HOST, 2); + if (ctype_digit($portOrSocket)) { + $socket = ':host='.$host . ';port='.$portOrSocket; + } else { + $socket = ':unix_socket='.$portOrSocket; + } + } else { + $socket = ':host='.ZM_DB_HOST; + } - try { - $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_ERRMODE, PDO::ERRMODE_EXCEPTION); - } catch(PDOException $ex ) { - echo "Unable to connect to ZM db." . $ex->getMessage(); - $dbConn = null; - } + try { + $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_ERRMODE, PDO::ERRMODE_EXCEPTION); + } catch(PDOException $ex ) { + echo "Unable to connect to ZM db." . $ex->getMessage(); + $dbConn = null; + } } dbConnect(); -function dbDisconnect() -{ - global $dbConn; - $dbConn = null; +function dbDisconnect() { + global $dbConn; + $dbConn = null; } -function dbLogOff() -{ - global $dbLogLevel; - $dbLogLevel = DB_LOG_OFF; +function dbLogOff() { + global $dbLogLevel; + $dbLogLevel = DB_LOG_OFF; } -function dbLogOn() -{ - global $dbLogLevel; - $dbLogLevel = DB_LOG_ONLY; +function dbLogOn() { + global $dbLogLevel; + $dbLogLevel = DB_LOG_ONLY; } -function dbLogDebug() -{ - global $dbLogLevel; - $dbLogLevel = DB_LOG_DEBUG; +function dbLogDebug() { + global $dbLogLevel; + $dbLogLevel = DB_LOG_DEBUG; } -function dbDebug() -{ - dbLogDebug(); +function dbDebug() { + dbLogDebug(); } -function dbLog( $sql, $update=false ) -{ - global $dbLogLevel; - $noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG); - if ( $dbLogLevel > DB_LOG_OFF ) - Logger::Debug( "SQL-LOG: $sql".($noExecute?" (not executed)":"") ); - return( $noExecute ); +function dbLog( $sql, $update=false ) { + global $dbLogLevel; + $noExecute = $update && ($dbLogLevel >= DB_LOG_DEBUG); + if ( $dbLogLevel > DB_LOG_OFF ) + Debug( "SQL-LOG: $sql".($noExecute?" (not executed)":"") ); + return( $noExecute ); } -function dbError( $sql ) -{ - Fatal( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" ); +function dbError( $sql ) { + Fatal( "SQL-ERR '".$dbConn->errorInfo()."', statement was '".$sql."'" ); } -function dbEscape( $string ) -{ - global $dbConn; - if ( version_compare( phpversion(), "4.3.0", "<") ) - if ( get_magic_quotes_gpc() ) - return( $dbConn->quote( stripslashes( $string ) ) ); - else - return( $dbConn->quote( $string ) ); +function dbEscape( $string ) { + global $dbConn; + if ( version_compare( phpversion(), "4.3.0", "<") ) + if ( get_magic_quotes_gpc() ) + return( $dbConn->quote( stripslashes( $string ) ) ); else - if ( get_magic_quotes_gpc() ) - return( $dbConn->quote( stripslashes( $string ) ) ); - else - return( $dbConn->quote( $string ) ); + return( $dbConn->quote( $string ) ); + else + if ( get_magic_quotes_gpc() ) + return( $dbConn->quote( stripslashes( $string ) ) ); + else + return( $dbConn->quote( $string ) ); } function dbQuery( $sql, $params=NULL ) { - global $dbConn; - if ( dbLog( $sql, true ) ) - return; - $result = NULL; - try { - if ( isset($params) ) { - $result = $dbConn->prepare( $sql ); - $result->execute( $params ); - } else { - $result = $dbConn->query( $sql ); - } - } catch(PDOException $e) { - Fatal( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."'" ); + global $dbConn; + if ( dbLog( $sql, true ) ) + return; + $result = NULL; + try { + if ( isset($params) ) { + $result = $dbConn->prepare( $sql ); + $result->execute( $params ); + } else { + $result = $dbConn->query( $sql ); } - return( $result ); + } catch(PDOException $e) { + Fatal( "SQL-ERR '".$e->getMessage()."', statement was '".$sql."'" ); + } + return( $result ); } -function dbFetchOne( $sql, $col=false, $params=NULL ) -{ - $result = dbQuery( $sql, $params ); - if ( ! $result ) { - Fatal( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) ); - return false; - } +function dbFetchOne( $sql, $col=false, $params=NULL ) { + $result = dbQuery( $sql, $params ); + if ( ! $result ) { + Fatal( "SQL-ERR dbFetchOne no result, statement was '".$sql."'" . ( $params ? 'params: ' . join(',',$params) : '' ) ); + return false; + } - if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) - return( $col?$dbRow[$col]:$dbRow ); - return( false ); + if ( $result && $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) { + if ( $col ) { + if ( ! isset( $dbRow[$col] ) ) { + Warning( "$col does not exist in the returned row" ); + } + return $dbRow[$col]; + } + return $dbRow; + } + return( false ); } -function dbFetchAll( $sql, $col=false, $params=NULL ) -{ - $result = dbQuery( $sql, $params ); - if ( ! $result ) { - Fatal( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) ); - return false; - } +function dbFetchAll( $sql, $col=false, $params=NULL ) { + $result = dbQuery( $sql, $params ); + if ( ! $result ) { + Fatal( "SQL-ERR dbFetchAll no result, statement was '".$sql."'" . ( $params ? 'params: ' .join(',', $params) : '' ) ); + return false; + } - $dbRows = array(); - while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) - $dbRows[] = $col?$dbRow[$col]:$dbRow; - return( $dbRows ); + $dbRows = array(); + while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) + $dbRows[] = $col?$dbRow[$col]:$dbRow; + return( $dbRows ); } -function dbFetchAssoc( $sql, $indexCol, $dataCol=false ) -{ - $result = dbQuery( $sql ); +function dbFetchAssoc( $sql, $indexCol, $dataCol=false ) { + $result = dbQuery( $sql ); - $dbRows = array(); - while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) - $dbRows[$dbRow[$indexCol]] = $dataCol?$dbRow[$dataCol]:$dbRow; - return( $dbRows ); + $dbRows = array(); + while( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) + $dbRows[$dbRow[$indexCol]] = $dataCol?$dbRow[$dataCol]:$dbRow; + return( $dbRows ); } -function dbFetch( $sql, $col=false ) -{ - return( dbFetchAll( $sql, $col ) ); +function dbFetch( $sql, $col=false ) { + return( dbFetchAll( $sql, $col ) ); } -function dbFetchNext( $result, $col=false ) -{ - if ( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) - return( $col?$dbRow[$col]:$dbRow ); - return( false ); +function dbFetchNext( $result, $col=false ) { + if ( $dbRow = $result->fetch( PDO::FETCH_ASSOC ) ) + return( $col?$dbRow[$col]:$dbRow ); + return( false ); } -function dbNumRows( $sql ) -{ - $result = dbQuery( $sql ); - return( $result->rowCount() ); +function dbNumRows( $sql ) { + $result = dbQuery( $sql ); + return( $result->rowCount() ); } -function dbInsertId() -{ - global $dbConn; - return( $dbConn->lastInsertId() ); +function dbInsertId() { + global $dbConn; + return( $dbConn->lastInsertId() ); } -function getEnumValues( $table, $column ) -{ - $row = dbFetchOne( "describe $table $column" ); - preg_match_all( "/'([^']+)'/", $row['Type'], $matches ); - return( $matches[1] ); +function getEnumValues( $table, $column ) { + $row = dbFetchOne( "describe $table $column" ); + preg_match_all( "/'([^']+)'/", $row['Type'], $matches ); + return( $matches[1] ); } -function getSetValues( $table, $column ) -{ - return( getEnumValues( $table, $column ) ); +function getSetValues( $table, $column ) { + return( getEnumValues( $table, $column ) ); } -function getUniqueValues( $table, $column, $asString=1 ) -{ - $values = array(); - $sql = "select distinct $column from $table where (not isnull($column) and $column != '') order by $column"; - foreach( dbFetchAll( $sql ) as $row ) - { - if ( $asString ) - $values[$row[$column]] = $row[$column]; - else - $values[] = $row[$column]; - } - return( $values ); +function getUniqueValues( $table, $column, $asString=1 ) { + $values = array(); + $sql = "select distinct $column from $table where (not isnull($column) and $column != '') order by $column"; + foreach( dbFetchAll( $sql ) as $row ) { + if ( $asString ) + $values[$row[$column]] = $row[$column]; + else + $values[] = $row[$column]; + } + return( $values ); } -function getTableColumns( $table, $asString=1 ) -{ - $columns = array(); - $sql = "describe $table"; - foreach( dbFetchAll( $sql ) as $row ) - { - if ( $asString ) - $columns[$row['Field']] = $row['Type']; - else - $columns[] = $row['Type']; - } - return( $columns ); +function getTableColumns( $table, $asString=1 ) { + $columns = array(); + $sql = "describe $table"; + foreach( dbFetchAll( $sql ) as $row ) { + if ( $asString ) + $columns[$row['Field']] = $row['Type']; + else + $columns[] = $row['Type']; + } + return( $columns ); } -function getTableAutoInc( $table ) -{ - $row = dbFetchOne( "show table status where Name=?", NULL, array($table) ); - return( $row['Auto_increment'] ); +function getTableAutoInc( $table ) { + $row = dbFetchOne( "show table status where Name=?", NULL, array($table) ); + return( $row['Auto_increment'] ); } -function getTableDescription( $table, $asString=1 ) -{ - $columns = array(); - foreach( dbFetchAll( "describe $table" ) as $row ) - { - $desc = array( - 'name' => $row['Field'], - 'required' => ($row['Null']=='NO')?true:false, - 'default' => $row['Default'], - 'db' => $row, +function getTableDescription( $table, $asString=1 ) { + $columns = array(); + foreach( dbFetchAll( "describe $table" ) as $row ) { + $desc = array( + 'name' => $row['Field'], + 'required' => ($row['Null']=='NO')?true:false, + 'default' => $row['Default'], + 'db' => $row, ); - if ( preg_match( "/^varchar\((\d+)\)$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'text'; - $desc['typeAttrib'] = 'varchar'; - $desc['maxLength'] = $matches[1]; - } - elseif ( preg_match( "/^(\w+)?text$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'text'; - if (!empty($matches[1]) ) - $desc['typeAttrib'] = $matches[1]; - switch ( $matches[1] ) - { - case 'tiny' : - $desc['maxLength'] = 255; - break; - case 'medium' : - $desc['maxLength'] = 32768; - break; - case '' : - case 'big' : - //$desc['minLength'] = -128; - break; - default : - Error( "Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); - break; - } - } - elseif ( preg_match( "/^(enum|set)\((.*)\)$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'text'; - $desc['typeAttrib'] = $matches[1]; - preg_match_all( "/'([^']+)'/", $matches[2], $matches ); - $desc['values'] = $matches[1]; - } - elseif ( preg_match( "/^(\w+)?int\(\d+\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'integer'; - switch ( $matches[1] ) - { - case 'tiny' : - $desc['minValue'] = -128; - $desc['maxValue'] = 127; - break; - case 'small' : - $desc['minValue'] = -32768; - $desc['maxValue'] = 32767; - break; - case 'medium' : - $desc['minValue'] = -8388608; - $desc['maxValue'] = 8388607; - break; - case '' : - $desc['minValue'] = -2147483648; - $desc['maxValue'] = 2147483647; - break; - case 'big' : - //$desc['minValue'] = -128; - //$desc['maxValue'] = 127; - break; - default : - Error( "Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); - break; - } - if ( !empty($matches[1]) ) - $desc['typeAttrib'] = $matches[1]; - if ( $desc['unsigned'] = ( isset($matches[2]) && $matches[2] == 'unsigned' ) ) - { - $desc['maxValue'] += (-$desc['minValue']); - $desc['minValue'] = 0; - } - } - elseif ( preg_match( "/^(?:decimal|numeric)\((\d+)(?:,(\d+))?\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'fixed'; - $desc['range'] = $matches[1]; - if ( isset($matches[2]) ) - $desc['precision'] = $matches[2]; - else - $desc['precision'] = 0; - $desc['unsigned'] = ( isset($matches[3]) && $matches[3] == 'unsigned' ); - } - elseif ( preg_match( "/^(datetime|timestamp|date|time)$/", $row['Type'], $matches ) ) - { - $desc['type'] = 'datetime'; - switch ( $desc['typeAttrib'] = $matches[1] ) - { - case 'datetime' : - case 'timestamp' : - $desc['hasDate'] = true; - $desc['hasTime'] = true; - break; - case 'date' : - $desc['hasDate'] = true; - $desc['hasTime'] = false; - break; - case 'time' : - $desc['hasDate'] = false; - $desc['hasTime'] = true; - break; - } - } - else - { - Error( "Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'" ); - } - - if ( $asString ) - $columns[$row['Field']] = $desc; - else - $columns[] = $desc; + if ( preg_match( "/^varchar\((\d+)\)$/", $row['Type'], $matches ) ) { + $desc['type'] = 'text'; + $desc['typeAttrib'] = 'varchar'; + $desc['maxLength'] = $matches[1]; + } elseif ( preg_match( "/^(\w+)?text$/", $row['Type'], $matches ) ) { + $desc['type'] = 'text'; + if (!empty($matches[1]) ) + $desc['typeAttrib'] = $matches[1]; + switch ( $matches[1] ) { + case 'tiny' : + $desc['maxLength'] = 255; + break; + case 'medium' : + $desc['maxLength'] = 32768; + break; + case '' : + case 'big' : + //$desc['minLength'] = -128; + break; + default : + Error( "Unexpected text qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); + break; + } + } elseif ( preg_match( "/^(enum|set)\((.*)\)$/", $row['Type'], $matches ) ) { + $desc['type'] = 'text'; + $desc['typeAttrib'] = $matches[1]; + preg_match_all( "/'([^']+)'/", $matches[2], $matches ); + $desc['values'] = $matches[1]; + } elseif ( preg_match( "/^(\w+)?int\(\d+\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) { + $desc['type'] = 'integer'; + switch ( $matches[1] ) { + case 'tiny' : + $desc['minValue'] = -128; + $desc['maxValue'] = 127; + break; + case 'small' : + $desc['minValue'] = -32768; + $desc['maxValue'] = 32767; + break; + case 'medium' : + $desc['minValue'] = -8388608; + $desc['maxValue'] = 8388607; + break; + case '' : + $desc['minValue'] = -2147483648; + $desc['maxValue'] = 2147483647; + break; + case 'big' : + //$desc['minValue'] = -128; + //$desc['maxValue'] = 127; + break; + default : + Error( "Unexpected integer qualifier '".$matches[1]."' found for field '".$row['Field']."' in table '".$table."'" ); + break; + } + if ( !empty($matches[1]) ) + $desc['typeAttrib'] = $matches[1]; + if ( $desc['unsigned'] = ( isset($matches[2]) && $matches[2] == 'unsigned' ) ) { + $desc['maxValue'] += (-$desc['minValue']); + $desc['minValue'] = 0; + } + } elseif ( preg_match( "/^(?:decimal|numeric)\((\d+)(?:,(\d+))?\)(?:\s+(unsigned))?$/", $row['Type'], $matches ) ) { + $desc['type'] = 'fixed'; + $desc['range'] = $matches[1]; + if ( isset($matches[2]) ) + $desc['precision'] = $matches[2]; + else + $desc['precision'] = 0; + $desc['unsigned'] = ( isset($matches[3]) && $matches[3] == 'unsigned' ); + } elseif ( preg_match( "/^(datetime|timestamp|date|time)$/", $row['Type'], $matches ) ) { + $desc['type'] = 'datetime'; + switch ( $desc['typeAttrib'] = $matches[1] ) { + case 'datetime' : + case 'timestamp' : + $desc['hasDate'] = true; + $desc['hasTime'] = true; + break; + case 'date' : + $desc['hasDate'] = true; + $desc['hasTime'] = false; + break; + case 'time' : + $desc['hasDate'] = false; + $desc['hasTime'] = true; + break; + } + } else { + Error( "Can't parse database type '".$row['Type']."' found for field '".$row['Field']."' in table '".$table."'" ); } - return( $columns ); + + if ( $asString ) + $columns[$row['Field']] = $desc; + else + $columns[] = $desc; + } + return( $columns ); } -function dbFetchMonitor( $mid ) -{ - return( dbFetchOne( "select * from Monitors where Id = ?", NULL, array($mid) ) ); +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) ) ); +function dbFetchGroup( $gid ) { + return( dbFetchOne( "select * from Groups where Id = ?", NULL, array($gid) ) ); } ?>