Hostname();}, $Servers)); switch ($view) { case 'login': { if (defined('ZM_OPT_USE_GOOG_RECAPTCHA') && defined('ZM_OPT_GOOG_RECAPTCHA_SITEKEY') && defined('ZM_OPT_GOOG_RECAPTCHA_SECRETKEY') && ZM_OPT_USE_GOOG_RECAPTCHA && ZM_OPT_GOOG_RECAPTCHA_SITEKEY && ZM_OPT_GOOG_RECAPTCHA_SECRETKEY) { $additionalScriptSrc .= ' https://www.google.com'; } // fall through } case 'bandwidth': case 'blank': case 'console': case 'controlcap': case 'cycle': case 'donate': case 'download': case 'error': case 'events': case 'export': case 'frame': case 'function': case 'log': case 'logout': case 'optionhelp': case 'options': case 'plugin': case 'postlogin': case 'privacy': case 'server': case 'state': case 'status': case 'storage': case 'version': { // Enforce script-src on pages where inline scripts and event handlers have been fixed. header("Content-Security-Policy: script-src 'self' 'nonce-$nonce' $additionalScriptSrc"); break; } default: { // Use Report-Only mode on all other pages. header("Content-Security-Policy-Report-Only: script-src 'self' 'nonce-$nonce' $additionalScriptSrc;". (ZM_CSP_REPORT_URI ? ' report-uri '.ZM_CSP_REPORT_URI : '' ) ); break; } } } function CORSHeaders() { if ( isset($_SERVER['HTTP_ORIGIN']) ) { # The following is left for future reference/use. $valid = false; global $Servers; if ( ! $Servers ) $Servers = ZM\Server::find(); if ( sizeof($Servers) < 1 ) { # Only need CORSHeaders in the event that there are multiple servers in use. # ICON: Might not be true. multi-port? if ( ZM_MIN_STREAMING_PORT ) { ZM\Debug('Setting default Access-Control-Allow-Origin from ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); } return; } foreach ( $Servers as $Server ) { if ( preg_match('/^(https?:\/\/)?'.preg_quote($Server->Hostname(),'/').'/i', $_SERVER['HTTP_ORIGIN']) or preg_match('/^(https?:\/\/)?'.preg_quote($Server->Name(),'/').'/i', $_SERVER['HTTP_ORIGIN']) ) { $valid = true; ZM\Debug('Setting Access-Control-Allow-Origin from '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); break; } } if ( !$valid ) { ZM\Warning($_SERVER['HTTP_ORIGIN'] . ' is not found in servers list.'); } } } function getMimeType( $file ) { if ( function_exists('mime_content_type') ) { return mime_content_type($file); } elseif ( function_exists('finfo_file') ) { $finfo = finfo_open(FILEINFO_MIME); $mimeType = finfo_file($finfo, $file); finfo_close($finfo); return $mimeType; } return trim(exec('file -bi '.escapeshellarg($file).' 2>/dev/null')); } function outputVideoStream($id, $src, $width, $height, $format, $title='') { echo getVideoStreamHTML($id, $src, $width, $height, $format, $title); } function getVideoStreamHTML($id, $src, $width, $height, $format, $title='') { $html = ''; $width = validInt($width); $height = validInt($height); $title = validHtmlStr($title); if ( file_exists($src) ) { $mimeType = getMimeType($src); } else { switch( $format ) { case 'asf' : $mimeType = 'video/x-ms-asf'; break; case 'avi' : case 'wmv' : $mimeType = 'video/x-msvideo'; break; case 'mov' : $mimeType = 'video/quicktime'; break; case 'mpg' : case 'mpeg' : $mimeType = 'video/mpeg'; break; case 'swf' : $mimeType = 'application/x-shockwave-flash'; break; case '3gp' : $mimeType = 'video/3gpp'; break; default : $mimeType = 'video/'.$format; break; } } if ( !$mimeType || ($mimeType == 'application/octet-stream') ) $mimeType = 'video/'.$format; if ( ZM_WEB_USE_OBJECT_TAGS ) { switch( $mimeType ) { case 'video/x-ms-asf' : case 'video/x-msvideo' : case 'video/mp4' : if ( isWindows() ) { return ''; } case 'video/quicktime' : return ''; case 'application/x-shockwave-flash' : return ''; } # end switch } # end if use object tags return ''; } function outputImageStream( $id, $src, $width, $height, $title='' ) { echo getImageStreamHTML( $id, $src, $width, $height, $title ); } // width and height MUST be valid and include the px function getImageStreamHTML( $id, $src, $width, $height, $title='' ) { if ( canStreamIframe() ) { return ''; } else { return ''; } } function outputControlStream($src, $width, $height, $monitor, $scale, $target) { ?>
'; } function outputImageStill($id, $src, $width, $height, $title='') { echo getImageStill($id, $src, $width, $height, $title=''); } function getImageStill($id, $src, $width, $height, $title='') { return ''; } function getWebSiteUrl($id, $src, $width, $height, $title='') { # Prevent unsightly warnings when php cannot verify the ssl certificate stream_context_set_default( [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, ], ]); # The End User can turn off the following warning under Options -> Web if ( ZM_WEB_XFRAME_WARN ) { $header = get_headers($src, 1); # If the target website has set X-Frame-Options, check it for "sameorigin" and warn the end user if ( array_key_exists('X-Frame-Options', $header) ) { $header = $header['X-Frame-Options']; if ( stripos($header, 'sameorigin') === 0 ) ZM\Warning('Web site '.$src.' has X-Frame-Options set to sameorigin. An X-Frame-Options browser plugin is required to display this site.'); } } return ''; } function outputControlStill($src, $width, $height, $monitor, $scale, $target) { ?> getStreamSrc(array('mode'=>'mpeg', 'format'=>'h264')); } function deletePath( $path ) { ZM\Debug('Deleting '.$path); if ( is_dir($path) ) { system(escapeshellcmd('rm -rf '.$path)); } else if ( file_exists($path) ) { unlink($path); } } function deleteEvent($event) { if ( empty($event) ) { ZM\Error('Empty event passed to deleteEvent.'); return; } if ( gettype($event) != 'array' ) { # $event could be an eid, so turn it into an event hash $event = new ZM\Event($event); } if ( $event->Archived() ) { ZM\Info('Cannot delete Archived event.'); return; } # end if Archived global $user; if ( $user['Events'] == 'Edit' ) { $event->delete(); } # CAN EDIT } /** * $label must be already escaped. It can't be done here since it sometimes contains HTML tags. */ function makeLink($url, $label, $condition=1, $options='') { $string = ''; if ( $condition ) { $string .= ''; } $string .= $label; if ( $condition ) { $string .= ''; } return $string; } //Make it slightly easier to create a link to help text modal function makeHelpLink($ohndx) { $string = ' (?)'; return $string; } function makeButton($url, $buttonValue, $condition=1, $options='') { $string = ''.translate($buttonValue).''.PHP_EOL; return $string; } function htmlSelect($name, $contents, $values, $behaviours=false) { $behaviourText = ''; if ( !empty($behaviours) ) { if ( is_array($behaviours) ) { foreach ( $behaviours as $event=>$action ) { $behaviourText .= ' '.$event.'="'.$action.'"'; } } else { $behaviourText = ' onchange="'.$behaviours.'"'; } } return ''; } function htmlOptions($options, $values) { $options_html = ''; $has_selected = false; foreach ( $options as $value=>$option ) { $disabled = 0; $text = ''; if ( is_array($option) ) { if ( isset($option['Name']) ) $text = $option['Name']; else if ( isset($option['text']) ) $text = $option['text']; if ( isset($option['disabled']) ) { $disabled = $option['disabled']; } } else if ( is_object($option) ) { $text = $option->Name(); } else { $text = $option; } $selected = is_array($values) ? in_array($value, $values) : (!strcmp($value, $values)); if ( !$has_selected ) $has_selected = $selected; $options_html .= ''.PHP_EOL; } # end foreach options if ( $values and ((!is_array($values)) or count($values) ) and ! $has_selected ) { ZM\Warning('Specified value '.print_r($values, true).' not in contents: '.print_r($options, true)); } return $options_html; } # end function htmlOptions function truncText($text, $length, $deslash=1) { return preg_replace('/^(.{'.$length.',}?)\b.*$/', '\\1…', ($deslash?stripslashes($text):$text)); } function buildSelect($name, $contents, $behaviours=false) { $value = ''; if ( preg_match('/^\s*(\w+)\s*(\[.*\])?\s*$/', $name, $matches) && (count($matches) > 2) ) { $arr = $matches[1]; if ( isset($GLOBALS[$arr]) ) $value = $GLOBALS[$arr]; elseif ( isset($_REQUEST[$arr]) ) $value = $_REQUEST[$arr]; if ( !preg_match_all('/\[\s*[\'"]?(\w+)["\']?\s*\]/', $matches[2], $matches) ) { ZM\Fatal("Can't parse selector '$name'"); } for ( $i = 0; $i < count($matches[1]); $i++ ) { $idx = $matches[1][$i]; $value = isset($value[$idx])?$value[$idx]:false; } } else { if ( isset($GLOBALS[$name]) ) $value = $GLOBALS[$name]; elseif ( isset($_REQUEST[$name]) ) $value = $_REQUEST[$name]; } ob_start(); $behaviourText = ''; if ( !empty($behaviours) ) { if ( is_array($behaviours) ) { foreach ( $behaviours as $event=>$action ) { $behaviourText .= ' '.$event.'="'.$action.'"'; } } else { $behaviourText = ' data-on-change-this="'.$behaviours.'"'; } } ?> $value ) { if ( $columns && !isset($columns[$key]) ) continue; if ( !isset($types[$key]) ) $types[$key] = false; switch ( $types[$key] ) { case 'set' : if ( is_array($newValues[$key]) ) { if ( (!isset($values[$key])) or ( join(',',$newValues[$key]) != $values[$key] ) ) { $changes[$key] = "`$key` = ".dbEscape(join(',',$newValues[$key])); } } else if ( (!isset($values[$key])) or $values[$key] ) { $changes[$key] = "`$key` = ''"; } break; case 'image' : if ( is_array( $newValues[$key] ) ) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); $changes[$key.'Width'] = $key.'Width = '.$imageData[0]; $changes[$key.'Height'] = $key.'Height = '.$imageData[1]; $changes[$key.'Type'] = $key.'Type = \''.$newValues[$key]['type'].'\''; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key." = ".dbEscape( ob_get_contents() ); ob_end_clean(); } else { $changes[$key] = "$key = ".dbEscape($value); } break; case 'document' : if ( is_array( $newValues[$key] ) ) { $imageData = getimagesize( $newValues[$key]['tmp_name'] ); $changes[$key.'Type'] = $key.'Type = \''.$newValues[$key]['type'].'\''; $changes[$key.'Size'] = $key.'Size = '.$newValues[$key]['size']; ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key.' = '.dbEscape( ob_get_contents() ); ob_end_clean(); } else { $changes[$key] = $key . ' = '.dbEscape($value); } break; case 'file' : $changes[$key.'Type'] = $key.'Type = '.dbEscape($newValues[$key]['type']); $changes[$key.'Size'] = $key.'Size = '.dbEscape($newValues[$key]['size']); ob_start(); readfile( $newValues[$key]['tmp_name'] ); $changes[$key] = $key.' = \''.dbEscape( ob_get_contents() ).'\''; ob_end_clean(); break; case 'raw' : if ( (!isset($values[$key])) or ($values[$key] != $value) ) { $changes[$key] = $key . ' = '.dbEscape($value); } break; case 'toggle' : if ( (!isset($values[$key])) or $values[$key] != $value ) { if ( empty($value) ) { $changes[$key] = $key.' = 0'; } else { $changes[$key] = $key.' = 1'; //$changes[$key] = $key . ' = '.dbEscape(trim($value)); } } break; case 'integer' : if ( (!isset($values[$key])) or $values[$key] != $value ) { $changes[$key] = $key . ' = '.intval($value); } break; default : if ( !isset($values[$key]) || ($values[$key] != $value) ) { if ( ! isset($value) || $value == '' ) { $changes[$key] = "`$key` = NULL"; } else { $changes[$key] = "`$key` = ".dbEscape(trim($value)); } } break; } // end switch } // end foreach newvalues foreach ( $values as $key=>$value ) { if ( !empty($columns[$key]) ) { if ( !empty($types[$key]) ) { if ( $types[$key] == 'toggle' ) { if ( !isset($newValues[$key]) && !empty($value) ) { $changes[$key] = "`$key` = 0"; } } else if ( $types[$key] == 'set' ) { $changes[$key] = "`$key` = ''"; } } } } return $changes; } function getBrowser(&$browser, &$version) { if ( isset($_SESSION['browser']) ) { $browser = $_SESSION['browser']; $version = $_SESSION['version']; } else { if ( ( preg_match('/MSIE (.*?);/', $_SERVER['HTTP_USER_AGENT'], $logVersion)) || ( preg_match('/.*Trident.*rv:(.*?)(;|\))/', $_SERVER['HTTP_USER_AGENT'], $logVersion)) ) { $version = $logVersion[1]; $browser = 'ie'; } else if ( preg_match('/Chrome\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; // Check for old version of Chrome with bug 5876 if ( $version < 7 ) { $browser = 'oldchrome'; } else { $browser = 'chrome'; } } else if ( preg_match('/Safari\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'safari'; } else if ( preg_match('/Opera[ \/]([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'opera'; } else if ( preg_match('/Konqueror\/([0-9.]+)/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'konqueror'; } else if ( preg_match('/Mozilla\/([0-9].[0-9]{1,2})/', $_SERVER['HTTP_USER_AGENT'], $logVersion) ) { $version = $logVersion[1]; $browser = 'mozilla'; } else { $version = 0; $browser = 'unknown'; } $_SESSION['browser'] = $browser; $_SESSION['version'] = $version; } } function isMozilla() { getBrowser($browser, $version); return $browser == 'mozilla'; } function isKonqueror() { getBrowser($browser, $version); return $browser == 'konqueror'; } function isInternetExplorer() { getBrowser($browser, $version); return $browser == 'ie'; } function isOldChrome() { getBrowser($browser, $version); return $browser == 'oldchrome'; } function isChrome() { getBrowser($browser, $version); return $browser == 'chrome'; } function isOpera() { getBrowser($browser, $version); return $browser == 'opera'; } function isSafari() { getBrowser($browser, $version); return $browser == 'safari'; } function isWindows() { return preg_match('/Win/', $_SERVER['HTTP_USER_AGENT']); } function canStreamIframe() { return isKonqueror(); } function canStreamNative() { // Old versions of Chrome can display the stream, but then it blocks everything else (Chrome bug 5876) return ( ZM_WEB_CAN_STREAM == 'yes' || ( ZM_WEB_CAN_STREAM == 'auto' && (!isInternetExplorer() && !isOldChrome()) ) ); } function canStreamApplet() { if ( (ZM_OPT_CAMBOZOLA && !file_exists( ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA )) ) { ZM\Warning('ZM_OPT_CAMBOZOLA is enabled, but the system cannot find '.ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA); } return (ZM_OPT_CAMBOZOLA && file_exists(ZM_PATH_WEB.'/'.ZM_PATH_CAMBOZOLA)); } function canStream() { return canStreamNative() | canStreamApplet(); } function packageControl($command) { $string = ZM_PATH_BIN.'/zmpkg.pl '.escapeshellarg($command); $string .= ' 2>/dev/null >&- <&- >/dev/null'; exec($string); } function daemonControl($command, $daemon=false, $args=false) { $string = escapeshellcmd(ZM_PATH_BIN).'/zmdc.pl '.$command; if ( $daemon ) { $string .= ' ' . $daemon; if ( $args ) { $string .= ' ' . $args; } } $string = escapeshellcmd($string); #$string .= ' 2>/dev/null >&- <&- >/dev/null'; ZM\Debug('daemonControl '.$string); exec($string); } function zmcControl($monitor, $mode=false) { $Monitor = new ZM\Monitor($monitor); return $Monitor->zmcControl($mode); } function zmaControl($monitor, $mode=false) { $Monitor = new ZM\Monitor($monitor); return $Monitor->zmaControl($mode); } function initDaemonStatus() { global $daemon_status; if ( !isset($daemon_status) ) { if ( daemonCheck() ) { $string = ZM_PATH_BIN.'/zmdc.pl status'; $daemon_status = shell_exec($string); } else { $daemon_status = ''; } } } function daemonStatus($daemon, $args=false) { global $daemon_status; initDaemonStatus(); $string = $daemon; if ( $args ) { if ( is_array($args) ) { $string .= join(' ', $args); } else { $string .= ' ' . $args; } } return ( strpos($daemon_status, "'$string' running") !== false ); } function zmcStatus($monitor) { if ( $monitor['Type'] == 'Local' ) { $zmcArgs = '-d '.$monitor['Device']; } else { $zmcArgs = '-m '.$monitor['Id']; } return daemonStatus('zmc', $zmcArgs); } function zmaStatus($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } return daemonStatus('zma', '-m '.$monitor); } function daemonCheck($daemon=false, $args=false) { $string = ZM_PATH_BIN.'/zmdc.pl check'; if ( $daemon ) { $string .= ' ' . $daemon; if ( $args ) $string .= ' '. $args; } $string = escapeshellcmd($string); $result = exec($string); return preg_match('/running/', $result); } function zmcCheck($monitor) { if ( $monitor['Type'] == 'Local' ) { $zmcArgs = '-d '.$monitor['Device']; } else { $zmcArgs = '-m '.$monitor['Id']; } return daemonCheck('zmc', $zmcArgs); } function zmaCheck($monitor) { if ( is_array($monitor) ) { $monitor = $monitor['Id']; } return daemonCheck('zma', '-m '.$monitor); } function getImageSrc($event, $frame, $scale=SCALE_BASE, $captureOnly=false, $overwrite=false) { $Event = new ZM\Event($event); return $Event->getImageSrc($frame, $scale, $captureOnly, $overwrite); } function viewImagePath($path, $querySep='&') { return '?view=image'.$querySep.'path='.$path; } function createListThumbnail($event, $overwrite=false) { # Load the frame with the highest score to use as a thumbnail if ( !($frame = dbFetchOne('SELECT * FROM Frames WHERE EventId=? AND Score=? ORDER BY FrameId LIMIT 1', NULL, array($event['Id'], $event['MaxScore']) )) ) return false; $frameId = $frame['FrameId']; if ( ZM_WEB_LIST_THUMB_WIDTH ) { $thumbWidth = ZM_WEB_LIST_THUMB_WIDTH; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_WIDTH)/$event['Width']; $thumbHeight = reScale($event['Height'], $scale); } elseif ( ZM_WEB_LIST_THUMB_HEIGHT ) { $thumbHeight = ZM_WEB_LIST_THUMB_HEIGHT; $scale = (SCALE_BASE*ZM_WEB_LIST_THUMB_HEIGHT)/$event['Height']; $thumbWidth = reScale($event['Width'], $scale); } else { ZM\Fatal('No thumbnail width or height specified, please check in Options->Web'); } $imageData = getImageSrc($event, $frame, $scale, false, $overwrite); if ( !$imageData ) { return false; } $thumbData = $frame; $thumbData['Path'] = $imageData['thumbPath']; $thumbData['Width'] = (int)$thumbWidth; $thumbData['Height'] = (int)$thumbHeight; return $thumbData; } function createVideo($event, $format, $rate, $scale, $overwrite=false) { $command = ZM_PATH_BIN.'/zmvideo.pl -e '.$event['Id'].' -f '.$format.' -r '.sprintf('%.2F', ($rate/RATE_BASE)); if ( preg_match('/\d+x\d+/', $scale) ) $command .= ' -S '.$scale; else if ( version_compare(phpversion(), '4.3.10', '>=') ) $command .= ' -s '.sprintf('%.2F', ($scale/SCALE_BASE)); else $command .= ' -s '.sprintf('%.2f', ($scale/SCALE_BASE)); if ( $overwrite ) $command .= ' -o'; $command = escapeshellcmd($command); $result = exec($command, $output, $status); ZM\Debug("generating Video $command: result($result outptu:(".implode("\n", $output )." status($status"); return $status ? '' : rtrim($result); } # This takes more than one scale amount, so it runs through each and alters dimension. # I can't imagine why you would want to do that. function reScale($dimension, $dummy) { $new_dimension = $dimension; for ( $i = 1; $i < func_num_args(); $i++ ) { $scale = func_get_arg($i); if ( !empty($scale) && ($scale != '0') && ($scale != 'auto') && ($scale != SCALE_BASE) ) $new_dimension = (int)(($new_dimension*$scale)/SCALE_BASE); } return $new_dimension; } function deScale($dimension, $dummy) { $new_dimension = $dimension; for ( $i = 1; $i < func_num_args(); $i++ ) { $scale = func_get_arg($i); if ( !empty($scale) && $scale != SCALE_BASE ) $new_dimension = (int)(($new_dimension*SCALE_BASE)/$scale); } return $new_dimension; } function monitorLimitSql() { global $user; if ( !empty($user['MonitorIds']) ) $midSql = ' AND MonitorId IN ('.join(',', preg_split('/["\'\s]*,["\'\s]*/', $user['MonitorIds'])).')'; else $midSql = ''; return $midSql; } function parseSort($saveToSession=false, $querySep='&') { global $sortQuery, $sortColumn, $sortOrder, $limitQuery; // Outputs if ( isset($_REQUEST['filter']['Query']['sort_field']) ) { //Handle both new and legacy filter passing $_REQUEST['sort_field'] = $_REQUEST['filter']['Query']['sort_field']; } if ( isset($_REQUEST['filter']['Query']['sort_asc']) ) { $_REQUEST['sort_asc'] = $_REQUEST['filter']['Query']['sort_asc']; } if ( isset($_REQUEST['filter']['Query']['limit']) ) { $_REQUEST['limit'] = $_REQUEST['filter']['Query']['limit']; } if ( empty($_REQUEST['sort_field']) ) { $_REQUEST['sort_field'] = ZM_WEB_EVENT_SORT_FIELD; $_REQUEST['sort_asc'] = (ZM_WEB_EVENT_SORT_ORDER == 'asc'); } switch( $_REQUEST['sort_field'] ) { case 'Id' : $sortColumn = 'E.Id'; break; case 'MonitorName' : $sortColumn = 'M.Name'; break; case 'Name' : $sortColumn = 'E.Name'; break; case 'Cause' : $sortColumn = 'E.Cause'; break; case 'DateTime' : $sortColumn = 'E.StartDateTime'; $_REQUEST['sort_field'] = 'StartDateTime'; break; case 'DiskSpace' : $sortColumn = 'E.DiskSpace'; break; case 'StartTime' : # legacy $_REQUEST['sort_field'] = 'StartDateTime'; $sortColumn = 'E.StartDateTime'; break; case 'StartDateTime' : $sortColumn = 'E.StartDateTime'; break; case 'EndTime' : #legacy $_REQUEST['sort_field'] = 'EndDateTime'; $sortColumn = 'E.EndDateTime'; break; case 'EndDateTime' : $sortColumn = 'E.EndDateTime'; break; case 'Length' : $sortColumn = 'E.Length'; break; case 'Frames' : $sortColumn = 'E.Frames'; break; case 'AlarmFrames' : $sortColumn = 'E.AlarmFrames'; break; case 'TotScore' : $sortColumn = 'E.TotScore'; break; case 'AvgScore' : $sortColumn = 'E.AvgScore'; break; case 'MaxScore' : $sortColumn = 'E.MaxScore'; break; case 'FramesFrameId' : $sortColumn = 'F.FrameId'; break; case 'FramesType' : $sortColumn = 'F.Type'; break; case 'FramesTimeStamp' : $sortColumn = 'F.TimeStamp'; break; case 'FramesDelta' : $sortColumn = 'F.Delta'; break; case 'FramesScore' : $sortColumn = 'F.Score'; break; default: $sortColumn = 'E.StartDateTime'; break; } if ( !isset($_REQUEST['sort_asc']) ) $_REQUEST['sort_asc'] = 0; $sortOrder = $_REQUEST['sort_asc'] ? 'asc' : 'desc'; $sortQuery = $querySep.'sort_field='.validHtmlStr($_REQUEST['sort_field']).$querySep.'sort_asc='.validHtmlStr($_REQUEST['sort_asc']); if ( !isset($_REQUEST['limit']) ) $_REQUEST['limit'] = ''; if ( $saveToSession ) { $_SESSION['sort_field'] = validHtmlStr($_REQUEST['sort_field']); $_SESSION['sort_asc'] = validHtmlStr($_REQUEST['sort_asc']); } if ($_REQUEST['limit'] != '') { $limitQuery = '&limit='.validInt($_REQUEST['limit']); } } # Historically this function has just modified the passed in filter array. # This would normally be $_REQUEST['filter']; We don't like modifying # request parameters. For now we will keep this behaviour, but note that we # now return the resulting array and other code should by modified to use that. # # Please note that I will be removing the savetosession code as well. function parseFilter(&$filter, $saveToSession=false, $querySep='&') { $Filter = ZM\Filter::parse($filter, $querySep); $filter['sql'] = $Filter->sql(); $filter['querystring'] = $Filter->querystring('filter', $querySep); $filter['hidden_fields'] = $Filter->hidden_fields(); $filter['pre_sql_conditions'] = $Filter->pre_sql_conditions(); $filter['post_sql_conditions'] = $Filter->post_sql_conditions(); if ( $filter['sql'] ) $filter['sql'] = ' AND ( '.$filter['sql'].' )'; #if ( 0 ) { #// ICON I feel like these should be here, but not yet #if ( isset($filter['Query']['sort_field']) ) { #$filter['sql'] .= ' ORDER BY ' . $filter['Query']['sort_field'] . ( #( $filter['Query']['sort_asc'] ? ' ASC' : ' DESC' ) ); #} #} return $filter; } // end function parseFilter(&$filter, $saveToSession=false, $querySep='&') // Please note that the filter is passed in by copy, so you need to use the return value from this function. // function addFilterTerm($filter, $position, $term=false) { if ( $position < 0 ) $position = 0; if ( !isset($filter['Query']['terms']) ) $filter['Query']['terms'] = array(); else if ( $position > count($filter['Query']['terms']) ) $position = count($filter['Query']['terms']); if ( $term && $position == 0 ) unset($term['cnj']); array_splice($filter['Query']['terms'], $position, 0, array($term ? $term : array())); return $filter; } function delFilterTerm($filter, $position) { if ( $position < 0 ) $position = 0; else if ( $position >= count($filter['Query']['terms']) ) $position = count($filter['Query']['terms']); array_splice($filter['Query']['terms'], $position, 1); return $filter; } function getPagination($pages, $page, $maxShortcuts, $query, $querySep='&') { global $view; $pageText = ''; if ( $pages > 1 ) { if ( $page ) { if ( $page < 0 ) $page = 1; if ( $page > $pages ) $page = $pages; if ( $page > 1 ) { if ( false && $page > 2 ) { $pageText .= '<<'; } $pageText .= '<'; $newPages = array(); $pagesUsed = array(); $lo_exp = max(2,log($page-1)/log($maxShortcuts)); for ( $i = 0; $i < $maxShortcuts; $i++ ) { $newPage = round($page-pow($lo_exp,$i)); if ( isset($pagesUsed[$newPage]) ) continue; if ( $newPage <= 1 ) break; $pagesUsed[$newPage] = true; array_unshift($newPages, $newPage); } if ( !isset($pagesUsed[1]) ) array_unshift( $newPages, 1 ); foreach ( $newPages as $newPage ) { $pageText .= ''.$newPage.' '; } } # end if page > 1 $pageText .= '- '.$page.' -'; if ( $page < $pages ) { $newPages = array(); $pagesUsed = array(); $hi_exp = max(2,log($pages-$page)/log($maxShortcuts)); for ( $i = 0; $i < $maxShortcuts; $i++ ) { $newPage = round($page+pow($hi_exp,$i)); if ( isset($pagesUsed[$newPage]) ) continue; if ( $newPage > $pages ) break; $pagesUsed[$newPage] = true; array_push($newPages, $newPage); } if ( !isset($pagesUsed[$pages]) ) array_push($newPages, $pages); foreach ( $newPages as $newPage ) { $pageText .= ' '.$newPage.''; } $pageText .= '>'; if ( false && $page < ($pages-1) ) { $pageText .= '>>'; } } # end if $page < $pages } } return $pageText; } function sortHeader($field, $querySep='&') { global $view; return implode($querySep, array( '?view='.$view, 'page=1'.(isset($_REQUEST['filter'])?$_REQUEST['filter']['query']:''), 'sort_field='.$field, 'sort_asc='.($_REQUEST['sort_field'] == $field ? !$_REQUEST['sort_asc'] : 0), 'limit='.validInt($_REQUEST['limit']), (isset($_REQUEST['eid']) ? 'eid='.$_REQUEST['eid'] : '' ), )); } function sortTag($field) { if ( isset($_REQUEST['sort_field']) ) { if ( $_REQUEST['sort_field'] == $field ) if ( $_REQUEST['sort_asc'] ) return '(^)'; else return '(v)'; } return false; } function getLoad() { $load = sys_getloadavg(); return $load[0]; } function getDiskPercent($path = ZM_DIR_EVENTS) { $total = disk_total_space($path); if ( $total === false ) { ZM\Error('disk_total_space returned false. Verify the web account user has access to ' . $path); return 0; } elseif ( $total == 0 ) { ZM\Error('disk_total_space indicates the following path has a filesystem size of zero bytes ' . $path); return 100; } $free = disk_free_space($path); if ( $free === false ) { ZM\Error('disk_free_space returned false. Verify the web account user has access to ' . $path); } $space = round((($total - $free) / $total) * 100); return $space; } function getDiskBlocks($path = ZM_DIR_EVENTS) { $df = shell_exec('df '.escapeshellarg($path)); $space = -1; if ( preg_match('/\s(\d+)\s+\d+\s+\d+%/ms', $df, $matches) ) $space = $matches[1]; return $space; } function systemStats() { $load = getLoad(); $diskPercent = getDiskPercent(); $pathMapPercent = getDiskPercent(ZM_PATH_MAP); $cpus = getcpus(); $normalized_load = $load / $cpus; # Colorize the system load stat if ( $normalized_load <= 0.75 ) { $htmlLoad = $load; } else if ( $normalized_load <= 0.9 ) { $htmlLoad = ''.$load.''; } else if ( $normalized_load <= 1.1 ) { $htmlLoad = ''.$load.''; } else { $htmlLoad = ''.$load.''; } # Colorize the disk space stat if ( $diskPercent < 98 ) { $htmlDiskPercent = $diskPercent.'%'; } else if ( $diskPercent <= 99 ) { $htmlDiskPercent = ''.$diskPercent.'%'; } else { $htmlDiskPercent = ''.$diskPercent.'%'; } # Colorize the PATH_MAP (usually /dev/shm) stat if ( $pathMapPercent < 90 ) { if ( disk_free_space(ZM_PATH_MAP) > 209715200 ) { # have to always have at least 200MiB free $htmlPathMapPercent = $pathMapPercent.'%'; } else { $htmlPathMapPercent = ''.$pathMapPercent.'%'; } } else if ( $pathMapPercent < 100 ) { $htmlPathMapPercent = ''.$pathMapPercent.'%'; } else { $htmlPathMapPercent = ''.$pathMapPercent.'%'; } $htmlString = translate('Load').': '.$htmlLoad.' - '.translate('Disk').': '.$htmlDiskPercent.' - '.ZM_PATH_MAP.': '.$htmlPathMapPercent; return $htmlString; } function getcpus() { if ( is_readable('/proc/cpuinfo') ) { # Works on Linux preg_match_all('/^processor/m', file_get_contents('/proc/cpuinfo'), $matches); $num_cpus = count($matches[0]); } else { # Works on BSD $matches = explode(':', shell_exec('sysctl hw.ncpu')); $num_cpus = trim($matches[1]); } return $num_cpus; } // Function to fix a problem whereby the built in PHP session handling // features want to put the sid as a hidden field after the form or // fieldset tag, neither of which will work with strict XHTML Basic. function sidField() { if ( SID ) { list($sessname, $sessid) = explode('=', SID); ?> '; return false; } $dx1 = $line1[1]['x'] - $line1[0]['x']; $dy1 = $line1[1]['y'] - $line1[0]['y']; $dx2 = $line2[1]['x'] - $line2[0]['x']; $dy2 = $line2[1]['y'] - $line2[0]['y']; if ( $dx1 ) { $m1 = $dy1/$dx1; $b1 = $line1[0]['y'] - ($m1 * $line1[0]['x']); } else { $b1 = $line1[0]['y']; } if ( $dx2 ) { $m2 = $dy2/$dx2; $b2 = $line2[0]['y'] - ($m2 * $line2[0]['x']); } else { $b2 = $line2[0]['y']; } if ( $dx1 && $dx2 ) { // Both not vertical if ( $m1 != $m2 ) { // Not parallel or colinear $x = ( $b2 - $b1 ) / ( $m1 - $m2 ); if ( $x >= $min_x1 && $x <= $max_x1 && $x >= $min_x2 && $x <= $max_x2 ) { if ( $debug ) echo "Intersecting, at x $x