I’m experiencing an issue with a Docker container running on a server. I have a PHP script that creates a CSV file (e.g., test_visit_events_unfinished.csv) when a user first visits the website. This file logs data related to an experiment on the site. Once the user completes the experiment, a JavaScript function sends a POST request to my PHP script in application/x-www-form-urlencoded format. At this point, the PHP script should rename the file to test_visit_events_finished.csv.
What I want:
Once a new CSV file is created, it is named in the format test_visit_events_unfinished.csv
. If the action finish
is triggered, the file should be renamed to test_visit_events_finished.csv
without modifying its contents.
What I tried:
I’ve tried multiple times to check if the file exists before renaming it, but no errors are thrown, and instead, a new file is created. I’ve verified the directory’s write permissions, and I suspect that the issue might be due to the user lacking permissions on this specific file. How can I dynamically assign the necessary permissions to the file?
Code
my php logic, the path to the file is correct. So the append and innit actions do work:
// Check if 'action' key exists in POST data
if (isset($_POST['action']) && $_POST['action'] === "init") {
// Get name of log file, and ensure it's named with _unfinished by default
$fid = $_POST['task'] ?? 'default_task'; // Default task if 'task' is missing
$unfinishedFileName = $fid . "_unfinished" . LOGEXT; // Append _unfinished to the filename
// Save data for the first time
$header = "cursor,timestamp,xpos,ypos,event,xpath,attrs,extras" . PHP_EOL;
file_put_contents(LOGDIR . "/" . $unfinishedFileName, $header . $info_data);
// Notify recording script
echo round(microtime(true) * 1000);
} else if (isset($_POST['action']) && $_POST['action'] === "append") {
// Get the log file name, use _unfinished if not specified
$fid = $_POST['task'] ?? 'default_task'; // Default task if 'task' is missing
$unfinishedFileName = $fid . "_unfinished" . LOGEXT; // Append _unfinished to the filename
// Don't write blank lines
if (trim($info_data)) {
file_put_contents(LOGDIR . "/" . $unfinishedFileName, $info_data, FILE_APPEND);
}
} else if (isset($_POST['action']) && $_POST['action'] === "finish") {
// Get the log file name without the suffix
$fid = $_POST['taskname'] ?? 'default_task'; // Default task if 'taskname' is missing
$unfinishedFileName = $fid . "_unfinished" . LOGEXT; // File with _unfinished suffix
$finishedFileName = $fid . "_finished" . LOGEXT; // File with _finished suffix
$originalFilePath = LOGDIR . "/" . $unfinishedFileName;
$finishedFilePath = LOGDIR . "/" . $finishedFileName;
if (file_exists($originalFilePath)) {
// Check if the _finished file already exists to avoid overwriting
if (!file_exists($finishedFilePath)) {
// Rename the file to mark it as finished
if (!rename($originalFilePath, $finishedFilePath)) {
exit('Failed to mark file as finished');
}
echo 'File marked as finished';
} else {
exit('A file with _finished already exists');
}
} else {
exit('Original _unfinished file not found');
}
}
here is my docker logic for giving the rights to write in the directory with contains the file:
RUN usermod -u 1000 www-data &&
groupmod -g 1000 www-data &&
chown -R www-data:www-data /var/www/html &&
chmod -R 755 /var/www/html/logs
here is the javascript functions which should send the filename for changing the name:
async function finishExperiment(eventFile) {
console.log("Now savint to: ", eventFile);
// Send a request to the server to mark the log file as "finished"
try {
const response = await fetch("static/php/writeEvents.php", {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded" // Set content type to 'x-www-form-urlencoded'
},
body: new URLSearchParams({
action: "finish", // The action type to perform
taskname: eventFile // The filename to mark as finished
})
});
// Handle the response
const data = await response.text(); // Assuming the server sends a plain text message
} catch (error) {
console.error("Error finishing the experiment:", error);
}