dolibarr.filearchive/ajax/addfile.php
data cbf04e6cc9 FileArchiv: Tile/Gallery view with toggle buttons
- Added formObjectOptions hook for document pages
- CSS/JS injected via DOMContentLoaded for proper timing
- Toggle between list and tile view (localStorage persisted)
- Lightbox for image gallery with keyboard navigation
- Fixed hook contexts (productdocuments, invoicedocuments, etc.)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-19 16:59:19 +01:00

160 lines
5.2 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* Add file to email attachment session
*/
if (!defined('NOTOKENRENEWAL')) {
define('NOTOKENRENEWAL', '1');
}
if (!defined('NOREQUIREMENU')) {
define('NOREQUIREMENU', '1');
}
if (!defined('NOREQUIREAJAX')) {
define('NOREQUIREAJAX', '1');
}
// Load Dolibarr environment
$res = 0;
// Path from /custom/filearchiv/ajax/ to main.inc.php
if (!$res && file_exists("../../../main.inc.php")) {
$res = @include "../../../main.inc.php";
}
// Fallback for different directory structures
if (!$res && file_exists("../../../../main.inc.php")) {
$res = @include "../../../../main.inc.php";
}
if (!$res && file_exists("../../main.inc.php")) {
$res = @include "../../main.inc.php";
}
if (!$res) {
die("Include of main fails");
}
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
header('Content-Type: application/json; charset=UTF-8');
// Debug logging
$debugFile = '/tmp/filearchiv_addfile_debug.log';
@file_put_contents($debugFile, date('Y-m-d H:i:s') . " === addfile.php called ===\n", FILE_APPEND);
@file_put_contents($debugFile, "Session ID: " . session_id() . "\n", FILE_APPEND);
@file_put_contents($debugFile, "User ID: " . (isset($user) ? $user->id : 'not set') . "\n", FILE_APPEND);
@file_put_contents($debugFile, "POST: " . print_r($_POST, true) . "\n", FILE_APPEND);
// Security check
if (!isModEnabled('filearchiv')) {
http_response_code(403);
echo json_encode(array('success' => false, 'error' => 'Module not enabled'));
exit;
}
$filepath = GETPOST('filepath', 'alphanohtml');
$filename = GETPOST('filename', 'alphanohtml');
$trackid = GETPOST('trackid', 'aZ09');
if (empty($filepath) || empty($filename)) {
echo json_encode(array('success' => false, 'error' => 'Missing parameters'));
exit;
}
// Security: Check that file exists and is readable
if (!file_exists($filepath) || !is_readable($filepath)) {
echo json_encode(array('success' => false, 'error' => 'File not found or not readable'));
exit;
}
// Security: Check that file is within allowed directories
$allowed = false;
$allowedPaths = array(
$conf->societe->multidir_output[$conf->entity],
$conf->propal->multidir_output[$conf->entity],
$conf->commande->multidir_output[$conf->entity],
$conf->facture->multidir_output[$conf->entity],
$conf->expedition->dir_output,
$conf->product->multidir_output[$conf->entity],
);
if (!empty($conf->fournisseur->commande->multidir_output[$conf->entity])) {
$allowedPaths[] = $conf->fournisseur->commande->multidir_output[$conf->entity];
}
if (!empty($conf->fournisseur->facture->multidir_output[$conf->entity])) {
$allowedPaths[] = $conf->fournisseur->facture->multidir_output[$conf->entity];
}
foreach ($allowedPaths as $path) {
if (!empty($path) && strpos(realpath($filepath), realpath($path)) === 0) {
$allowed = true;
break;
}
}
if (!$allowed) {
echo json_encode(array('success' => false, 'error' => 'Access denied to file path'));
exit;
}
// Get temporary directory for attachments
$upload_dir = $conf->user->dir_temp . '/' . $user->id . '/email_attachments';
if (!empty($trackid)) {
$upload_dir .= '/' . $trackid;
}
if (!is_dir($upload_dir)) {
dol_mkdir($upload_dir);
}
// Copy file to temp directory
$destfile = $upload_dir . '/' . $filename;
// Make filename unique if already exists
$counter = 1;
$pathinfo = pathinfo($filename);
$basename = $pathinfo['filename'];
$ext = isset($pathinfo['extension']) ? '.' . $pathinfo['extension'] : '';
while (file_exists($destfile)) {
$destfile = $upload_dir . '/' . $basename . '_' . $counter . $ext;
$counter++;
}
$result = dol_copy($filepath, $destfile);
if ($result < 0) {
echo json_encode(array('success' => false, 'error' => 'Failed to copy file'));
exit;
}
// Add to session for FormMail
// FormMail uses trackid as suffix: listofpaths-TRACKID
$keytoavoidconflict = empty($trackid) ? '' : '-'.$trackid;
$listofpaths = isset($_SESSION["listofpaths".$keytoavoidconflict]) ? $_SESSION["listofpaths".$keytoavoidconflict] : '';
$listofnames = isset($_SESSION["listofnames".$keytoavoidconflict]) ? $_SESSION["listofnames".$keytoavoidconflict] : '';
$listofmimes = isset($_SESSION["listofmimes".$keytoavoidconflict]) ? $_SESSION["listofmimes".$keytoavoidconflict] : '';
// Get mime type
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$mime = dol_mimetype($destfile);
// Append to session
$listofpaths = $listofpaths . ($listofpaths ? ';' : '') . $destfile;
$listofnames = $listofnames . ($listofnames ? ';' : '') . basename($destfile);
$listofmimes = $listofmimes . ($listofmimes ? ';' : '') . $mime;
$_SESSION["listofpaths".$keytoavoidconflict] = $listofpaths;
$_SESSION["listofnames".$keytoavoidconflict] = $listofnames;
$_SESSION["listofmimes".$keytoavoidconflict] = $listofmimes;
// Debug logging
@file_put_contents($debugFile, "Key: listofpaths$keytoavoidconflict\n", FILE_APPEND);
@file_put_contents($debugFile, "Set listofpaths: $listofpaths\n", FILE_APPEND);
@file_put_contents($debugFile, "Set listofnames: $listofnames\n", FILE_APPEND);
@file_put_contents($debugFile, "Destfile: $destfile\n", FILE_APPEND);
@file_put_contents($debugFile, "File copied: " . (file_exists($destfile) ? "YES" : "NO") . "\n", FILE_APPEND);
echo json_encode(array(
'success' => true,
'message' => 'File added successfully',
'filename' => basename($destfile)
));