$value) { if ($value != $item[$key]) $changes[$key] = $value; } } return $field_errors; } /* * Parser/formater values helpers */ function format_size($size, $digit=False) { if (!$digit && $digit!==0) $digit=2; if ($size>=1099511627776) return number_format($size/1099511627776,$digit)."To"; elseif ($size>=1073741824) return number_format($size/1073741824,$digit)."Go"; else if ($size>=1048576) return number_format($size/1048576,$digit)."Mo"; else if ($size>=1024) return number_format($size/1024,$digit)."Ko"; else return $size."o"; } function can_modify($item) { return can_do( $item, array('pending') ); } function can_archive($item) { return can_do( $item, array('refused', 'validated') ); } function can_delete($item) { return can_do( $item, array('archived') ); } function can_do($item, $status=array()) { return in_array($item['status'], $status); } /* * Generic Data/value helpers */ function vardump($data) { ob_start(); var_dump($data); $data = ob_get_contents(); ob_end_clean(); return $data; } /** * Format a callable object for logging * @param string|array $callable The callable object * @return string The callable object string representation */ function format_callable($callable) { if (is_string($callable)) return $callable."()"; if (is_array($callable)) if (is_string($callable[0])) return $callable[0]."::".$callable[1]."()"; elseif (is_object($callable[0])) return get_class($callable[0])."->".$callable[1]."()"; else return "Unkown->".$callable[1]."()"; // @phpstan-ignore-next-line return vardump($callable); } /* * Generic file/directory helpers */ function dump_file($file_path, $max_age=3600) { if (is_file($file_path)) { header('Content-Type: '.mime_content_type($file_path)); $last_modified_time = filemtime($file_path); $etag = md5_file($file_path); header("Cache-Control: max-age=$max_age, must-revalidate"); header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); header("Etag: $etag"); if ( ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time ) || ( isset($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag ) ) { header("HTTP/1.1 304 Not Modified"); exit(); } header('Pragma: public'); header('Content-Length: ' . filesize($file_path)); readfile($file_path); exit(); } header("HTTP/1.1 404 Not found"); exit(); } function delete_directory($dir, $recursive=true) { $files = array_diff(scandir($dir), array('.','..')); if ($recursive) { foreach ($files as $file) { if (is_dir("$dir/$file")) { if (!delete_directory("$dir/$file", true)) { Log :: error("delete_directory($dir) : Fail to delete sub-directory '$dir/$file'."); return false; } } else if (!unlink("$dir/$file")) { Log :: error("delete_directory($dir) : Fail to delete '$dir/$file'."); return false; } } } else if (!empty($files)) { Log :: error("delete_directory($dir) : Directory is not empty."); return false; } return rmdir($dir); } /* * Run external command helper */ /** * Run external command * * @param $command string|array The command. It's could be an array of the command with its * arguments. * @param $data_stdin string|null The command arguments (optional, default: null) * @param $escape_command_args boolean If true, the command will be escaped * (optional, default: true) * * @return false|array An array of return code, stdout and stderr result or False in case of fatal * error **/ function run_external_command($command, $data_stdin=null, $escape_command_args=true) { if (is_array($command)) $command = implode(' ', $command); if ($escape_command_args) $command = escapeshellcmd($command); Log :: debug("Run external command: '$command'"); $descriptorspec = array( 0 => array("pipe", "r"), // stdin 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w"), // stderr ); $process = proc_open($command, $descriptorspec, $pipes); if (!is_resource($process)) { Log :: error("Fail to run external command: '$command'"); return false; } if (!is_null($data_stdin)) { fwrite($pipes[0], $data_stdin); } fclose($pipes[0]); $stdout = stream_get_contents($pipes[1]); fclose($pipes[1]); $stderr = stream_get_contents($pipes[2]); fclose($pipes[2]); $return_value = proc_close($process); $error = (!empty($stderr) || $return_value != 0); Log :: log( ($error?'ERROR':'DEBUG'), "External command ".($error?"error":"result").":\n". "\tCommand : $command\n". "\tReturn code: $return_value\n". "\tOutput:\n". "\t\t- Stdout :\n$stdout\n\n". "\t\t- Stderr :\n$stderr" ); return array($return_value, $stdout, $stderr); } /** * Check an AJAX request and trigger a fatal error on fail * * Check if session key is present and valid and set AJAX * mode. * * @param string|null $session_key string The current session key (optional) * * @return void **/ function check_ajax_request($session_key=null) { global $ajax, $debug_ajax; Url :: api_mode(true); if (Session :: check_key($session_key)) Tpl :: fatal_error('Invalid request'); if (Tpl :: debug_ajax()) Log :: debug("Ajax Request : ".vardump($_REQUEST)); } # vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab