2020-04-18 00:51:33 +02:00
|
|
|
<?php
|
|
|
|
|
2023-01-29 17:36:21 +01:00
|
|
|
use EesyPHP\Check;
|
|
|
|
use EesyPHP\Log;
|
2023-01-29 22:34:43 +01:00
|
|
|
use EesyPHP\Session;
|
2023-01-31 00:30:04 +01:00
|
|
|
use EesyPHP\Tpl;
|
|
|
|
use EesyPHP\Url;
|
2023-01-29 17:36:21 +01:00
|
|
|
|
2020-04-18 00:51:33 +02:00
|
|
|
/*
|
|
|
|
* Check values helpers
|
|
|
|
*/
|
|
|
|
function check_status($status) {
|
|
|
|
global $status_list;
|
|
|
|
return array_key_exists($status, $status_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Handling item POST data
|
|
|
|
*/
|
2022-04-24 17:43:44 +02:00
|
|
|
function handle_item_post_data(&$info, $enabled_fields=null, $required_fields=null, &$item=null,
|
|
|
|
&$changes=null) {
|
2020-04-18 00:51:33 +02:00
|
|
|
$field_errors=array();
|
|
|
|
if (isset($_POST['submit'])) {
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: debug('POST data : '.vardump($_POST));
|
2020-04-18 00:51:33 +02:00
|
|
|
// Name
|
|
|
|
if (!$enabled_fields || in_array('name', $enabled_fields)) {
|
|
|
|
if (isset($_POST['name'])) {
|
2023-01-29 17:36:21 +01:00
|
|
|
if (Check :: name($_POST['name'])) {
|
2020-04-18 00:51:33 +02:00
|
|
|
$info['name'] = $_POST['name'];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$field_errors['name'] = "Ce nom est invalide.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$field_errors['name'] = "Cette information est obligatoire.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// status
|
|
|
|
if (!$enabled_fields || in_array('status', $enabled_fields)) {
|
|
|
|
if (isset($_POST['status']) && check_status($_POST['status'])) {
|
|
|
|
$info['status'] = $_POST['status'];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$field_errors['status'] = "Cette information est obligatoire.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// description
|
2022-04-24 17:43:44 +02:00
|
|
|
if (
|
|
|
|
isset($_POST['description']) &&
|
|
|
|
(!$enabled_fields || in_array('description', $enabled_fields))
|
|
|
|
) {
|
2023-01-29 17:36:21 +01:00
|
|
|
if (Check :: is_empty(trim($_POST['description']))) {
|
2020-04-18 00:51:33 +02:00
|
|
|
$info['description'] = null;
|
|
|
|
}
|
2023-01-29 17:36:21 +01:00
|
|
|
else if (Check :: description($_POST['description'])) {
|
2020-04-18 00:51:33 +02:00
|
|
|
$info['description'] = $_POST['description'];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$field_errors['description'] = "Cette description est invalide.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check custom required fields
|
|
|
|
if (is_array($required_fields)) {
|
|
|
|
foreach ($required_fields as $field) {
|
|
|
|
if (array_key_exists($field, $field_errors))
|
|
|
|
continue;
|
2023-01-29 17:36:21 +01:00
|
|
|
if (array_key_exists($field, $info) && !is_null($info[$field]) && !Check :: is_empty($info))
|
2020-04-18 00:51:33 +02:00
|
|
|
continue;
|
|
|
|
$field_errors[$field] = "Cette information est obligatoire.";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (empty($field_errors) && is_array($item) && !is_null($changes)) {
|
|
|
|
$changes = array();
|
|
|
|
foreach ($info as $key => $value) {
|
|
|
|
if ($value != $item[$key])
|
|
|
|
$changes[$key] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $field_errors;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parser/formater values helpers
|
|
|
|
*/
|
|
|
|
$_date_format = "%d/%m/%Y";
|
|
|
|
$_date_time_format = "%d/%m/%Y %H:%M:%S";
|
|
|
|
function format_time($time, $with_time=true) {
|
|
|
|
global $_date_format, $_date_time_format;
|
|
|
|
if ($with_time)
|
|
|
|
return strftime($_date_time_format, $time);
|
|
|
|
return strftime($_date_format, $time);
|
|
|
|
}
|
|
|
|
|
|
|
|
function parse_date($date, $with_time=true) {
|
|
|
|
global $_date_format, $_date_time_format;
|
|
|
|
if ($with_time)
|
|
|
|
$ptime = strptime($date, $_date_time_format);
|
|
|
|
else
|
|
|
|
$ptime = strptime($date, $_date_format);
|
|
|
|
if(is_array($ptime)) {
|
|
|
|
return mktime(
|
|
|
|
$ptime['tm_hour'],
|
|
|
|
$ptime['tm_min'],
|
|
|
|
$ptime['tm_sec'],
|
|
|
|
$ptime['tm_mon']+1,
|
|
|
|
$ptime['tm_mday'],
|
|
|
|
$ptime['tm_year']+1900
|
|
|
|
);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
2022-04-24 17:43:44 +02:00
|
|
|
ob_start();
|
|
|
|
var_dump($data);
|
|
|
|
$data = ob_get_contents();
|
|
|
|
ob_end_clean();
|
|
|
|
return $data;
|
2020-04-18 00:51:33 +02:00
|
|
|
}
|
|
|
|
|
2023-01-29 11:51:41 +01:00
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
}
|
|
|
|
|
2020-04-18 00:51:33 +02:00
|
|
|
/*
|
|
|
|
* Generic file/directory helpers
|
|
|
|
*/
|
|
|
|
function dump_file($file_path, $max_age=3600) {
|
2022-04-24 17:43:44 +02:00
|
|
|
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();
|
2020-04-18 00:51:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function delete_directory($dir, $recursive=true) {
|
2022-04-24 17:43:44 +02:00
|
|
|
$files = array_diff(scandir($dir), array('.','..'));
|
|
|
|
if ($recursive) {
|
2020-04-18 00:51:33 +02:00
|
|
|
foreach ($files as $file) {
|
|
|
|
if (is_dir("$dir/$file")) {
|
2022-04-24 17:43:44 +02:00
|
|
|
if (!delete_directory("$dir/$file", true)) {
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: error("delete_directory($dir) : Fail to delete sub-directory '$dir/$file'.");
|
2022-04-24 17:43:44 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (!unlink("$dir/$file")) {
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: error("delete_directory($dir) : Fail to delete '$dir/$file'.");
|
2022-04-24 17:43:44 +02:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-18 00:51:33 +02:00
|
|
|
}
|
2022-04-24 17:43:44 +02:00
|
|
|
}
|
|
|
|
else if (!empty($files)) {
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: error("delete_directory($dir) : Directory is not empty.");
|
2022-04-24 17:43:44 +02:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-18 00:51:33 +02:00
|
|
|
return rmdir($dir);
|
|
|
|
}
|
2021-07-28 17:13:10 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Run external command helper
|
|
|
|
*/
|
2022-04-24 17:43:44 +02:00
|
|
|
/**
|
|
|
|
* 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) {
|
2023-01-29 11:51:41 +01:00
|
|
|
if (is_array($command))
|
2022-04-24 17:43:44 +02:00
|
|
|
$command = implode(' ', $command);
|
|
|
|
if ($escape_command_args)
|
|
|
|
$command = escapeshellcmd($command);
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: debug("Run external command: '$command'");
|
2022-04-24 17:43:44 +02:00
|
|
|
$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)) {
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: error("Fail to run external command: '$command'");
|
2022-04-24 17:43:44 +02:00
|
|
|
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);
|
2023-01-29 17:36:21 +01:00
|
|
|
Log :: log(
|
2022-04-24 17:43:44 +02:00
|
|
|
($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);
|
|
|
|
}
|
2023-01-29 11:51:41 +01:00
|
|
|
|
2023-01-29 19:18:10 +01:00
|
|
|
/**
|
|
|
|
* 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;
|
2023-01-31 00:30:04 +01:00
|
|
|
Url :: api_mode(true);
|
2023-01-29 19:18:10 +01:00
|
|
|
|
2023-01-29 22:34:43 +01:00
|
|
|
if (Session :: check_key($session_key))
|
2023-01-31 00:30:04 +01:00
|
|
|
Tpl :: fatal_error('Invalid request');
|
2023-01-29 19:18:10 +01:00
|
|
|
|
2023-01-31 00:30:04 +01:00
|
|
|
if (Tpl :: debug_ajax())
|
2023-01-29 19:18:10 +01:00
|
|
|
Log :: debug("Ajax Request : ".vardump($_REQUEST));
|
|
|
|
}
|
|
|
|
|
2023-01-29 11:51:41 +01:00
|
|
|
# vim: tabstop=2 shiftwidth=2 softtabstop=2 expandtab
|