Files
assetmgt/api/v2/post/marketing_upload.php
“VeLiTi” 7aebb762d3 Refactor API endpoints and update invoice generation
- Updated API calls in equipment.php, equipment_manage.php, and equipments_mass_update.php to use v2 endpoints.
- Changed payload decoding from decode_payload to json_decode for consistency.
- Enhanced invoice generation in factuur.php and webhook files to use a new email template and PDF structure.
- Added new email and PDF templates for invoices to improve formatting and readability.
- Improved marketing folder handling in marketing.php with better payload management.
- Updated CSS for marketing to enhance UI interactions.
- Added JavaScript checks for browser compatibility in softwaretool.php.
- Adjusted user permissions in settingsprofiles.php to reflect new features.
2026-01-14 13:31:22 +01:00

336 lines
11 KiB
PHP

<?php
defined($security_key) or exit;
//------------------------------------------
// Marketing Upload
//------------------------------------------
//Connect to DB
$pdo = dbConnect($dbname);
//SoldTo is empty
if (empty($partner->soldto) || $partner->soldto == ''){$soldto_search = '%';} else {$soldto_search = '-%';}
//default whereclause
list($whereclause,$condition) = getWhereclauselvl2("",$permission,$partner,'');
//BUILD UP PARTNERHIERARCHY FROM USER
$partner_hierarchy = $condition;
//QUERY AND VERIFY ALLOWED
if (isAllowed('marketing',$profile,$permission,'C') === 1){
if (!isset($_FILES['file'])) {
echo json_encode(['success' => false, 'error' => 'No file uploaded']);
exit;
}
$file = $_FILES['file'];
$folder_id = $_POST['folder_id'] ?? '';
$tags = isset($_POST['tags']) ? json_decode($_POST['tags'], true) : [];
$title = $_POST['title'] ?? pathinfo($file['name'], PATHINFO_FILENAME);
// Validate file type
$allowedTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'mp4', 'mov', 'avi'];
$filename = $file['name'];
$ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!in_array($ext, $allowedTypes)) {
echo json_encode(['success' => false, 'error' => 'Invalid file type. Allowed: ' . implode(', ', $allowedTypes)]);
exit;
}
$imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'webp'];
$isImage = in_array($ext, $imageTypes);
// For images over 10MB, automatically compress
if ($isImage && $file['size'] > 10000000) {
$compressed = compressImage($file['tmp_name'], $ext, 10000000);
if ($compressed === false) {
echo json_encode(['success' => false, 'error' => 'Failed to compress large image. Please reduce file size manually.']);
exit;
}
// Update file size after compression
$file['size'] = filesize($file['tmp_name']);
}
// Non-images must be under 10MB
if (!$isImage && $file['size'] > 25000000) {
echo json_encode(['success' => false, 'error' => 'File too large. Maximum size is 25MB.']);
exit;
}
// Create unique filename
$unique_filename = uniqid() . '_' . time() . '.' . $ext;
$target_dir = dirname(__FILE__, 4) . "/marketing/uploads/";
$target_file = $target_dir . $unique_filename;
$logical_path = "marketing/uploads/" . $unique_filename;
// Ensure upload directory exists
if (!file_exists($target_dir)) {
mkdir($target_dir, 0755, true);
}
if (move_uploaded_file($file['tmp_name'], $target_file)) {
// Generate thumbnail
$thumbnail_path = null;
$thumb_dir = $target_dir . "thumbs/";
if (!file_exists($thumb_dir)) {
mkdir($thumb_dir, 0755, true);
}
// Generate thumbnail for images
if (in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
$thumbnail_file = $thumb_dir . $unique_filename;
if (generateThumbnail($target_file, $thumbnail_file, 200, 200)) {
$thumbnail_path = "marketing/uploads/thumbs/" . $unique_filename;
}
}
// Generate thumbnail for videos
elseif (in_array($ext, ['mp4', 'mov', 'avi'])) {
$thumbnail_filename = pathinfo($unique_filename, PATHINFO_FILENAME) . '.jpg';
$thumbnail_file = $thumb_dir . $thumbnail_filename;
if (generateVideoThumbnail($target_file, $thumbnail_file)) {
$thumbnail_path = "marketing/uploads/thumbs/" . $thumbnail_filename;
}
}
// Insert into database
$insert_sql = 'INSERT INTO `marketing_files` (`title`, `original_filename`, `file_path`, `thumbnail_path`, `file_type`, `file_size`, `folder_id`, `tags`, `createdby`, `accounthierarchy`) VALUES (?,?,?,?,?,?,?,?,?,?)';
$stmt = $pdo->prepare($insert_sql);
$stmt->execute([
$title,
$filename,
$logical_path,
$thumbnail_path,
$ext,
$file['size'],
$folder_id,
json_encode($tags),
$username,
$partner_hierarchy
]);
$file_id = $pdo->lastInsertId();
// Insert tags into separate table
if (!empty($tags)) {
$tag_sql = 'INSERT IGNORE INTO `marketing_tags` (`tag_name`) VALUES (?)';
$tag_stmt = $pdo->prepare($tag_sql);
$file_tag_sql = 'INSERT INTO `marketing_file_tags` (`file_id`, `tag_id`) SELECT ?, id FROM marketing_tags WHERE tag_name = ?';
$file_tag_stmt = $pdo->prepare($file_tag_sql);
foreach ($tags as $tag) {
$tag_stmt->execute([trim($tag)]);
$file_tag_stmt->execute([$file_id, trim($tag)]);
}
}
echo json_encode([
'success' => true,
'file_id' => $file_id,
'path' => $logical_path,
'thumbnail' => $thumbnail_path,
'message' => 'File uploaded successfully'
]);
} else {
echo json_encode(['success' => false, 'error' => 'Failed to move uploaded file']);
}
} else {
echo json_encode(['success' => false, 'error' => 'Insufficient permissions']);
}
// Function to compress large images
function compressImage($source, $ext, $maxSize) {
$info = @getimagesize($source);
if ($info === false) return false;
$mime = $info['mime'];
// Load image
switch ($mime) {
case 'image/jpeg':
$image = @imagecreatefromjpeg($source);
break;
case 'image/png':
$image = @imagecreatefrompng($source);
break;
case 'image/gif':
$image = @imagecreatefromgif($source);
break;
case 'image/webp':
$image = @imagecreatefromwebp($source);
break;
default:
return false;
}
if ($image === false) return false;
$width = imagesx($image);
$height = imagesy($image);
// Start with 90% quality and reduce dimensions if needed
$quality = 90;
$scale = 1.0;
$tempFile = $source . '.tmp';
// Try progressive compression
while (true) {
// Calculate new dimensions
$newWidth = (int)($width * $scale);
$newHeight = (int)($height * $scale);
// Create resized image
$resized = imagecreatetruecolor($newWidth, $newHeight);
// Preserve transparency for PNG/GIF
if ($mime === 'image/png' || $mime === 'image/gif') {
imagealphablending($resized, false);
imagesavealpha($resized, true);
$transparent = imagecolorallocatealpha($resized, 255, 255, 255, 127);
imagefilledrectangle($resized, 0, 0, $newWidth, $newHeight, $transparent);
}
imagecopyresampled($resized, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
// Save with current quality
if ($ext === 'jpg' || $ext === 'jpeg') {
imagejpeg($resized, $tempFile, $quality);
} elseif ($ext === 'png') {
// PNG compression level (0-9, where 9 is best compression)
$pngQuality = (int)((100 - $quality) / 11);
imagepng($resized, $tempFile, $pngQuality);
} elseif ($ext === 'webp') {
imagewebp($resized, $tempFile, $quality);
} else {
imagegif($resized, $tempFile);
}
imagedestroy($resized);
$fileSize = filesize($tempFile);
// If file is small enough, use it
if ($fileSize <= $maxSize) {
imagedestroy($image);
rename($tempFile, $source);
return true;
}
// If we've reduced too much, give up
if ($quality < 50 && $scale < 0.5) {
imagedestroy($image);
@unlink($tempFile);
return false;
}
// Reduce quality or scale
if ($quality > 50) {
$quality -= 10;
} else {
$scale -= 0.1;
}
}
}
// Function to generate thumbnail
function generateThumbnail($source, $destination, $width, $height) {
$info = getimagesize($source);
if ($info === false) return false;
$mime = $info['mime'];
switch ($mime) {
case 'image/jpeg':
$image = imagecreatefromjpeg($source);
break;
case 'image/png':
$image = imagecreatefrompng($source);
break;
case 'image/gif':
$image = imagecreatefromgif($source);
break;
case 'image/webp':
$image = imagecreatefromwebp($source);
break;
default:
return false;
}
if ($image === false) return false;
$original_width = imagesx($image);
$original_height = imagesy($image);
// Calculate aspect ratio
$aspect_ratio = $original_width / $original_height;
if ($width / $height > $aspect_ratio) {
$new_width = $height * $aspect_ratio;
$new_height = $height;
} else {
$new_height = $width / $aspect_ratio;
$new_width = $width;
}
$thumbnail = imagecreatetruecolor($new_width, $new_height);
// Preserve transparency
imagealphablending($thumbnail, false);
imagesavealpha($thumbnail, true);
$transparent = imagecolorallocatealpha($thumbnail, 255, 255, 255, 127);
imagefilledrectangle($thumbnail, 0, 0, $new_width, $new_height, $transparent);
imagecopyresampled($thumbnail, $image, 0, 0, 0, 0, $new_width, $new_height, $original_width, $original_height);
// Save thumbnail
switch ($mime) {
case 'image/jpeg':
$result = imagejpeg($thumbnail, $destination, 85);
break;
case 'image/png':
$result = imagepng($thumbnail, $destination, 8);
break;
case 'image/gif':
$result = imagegif($thumbnail, $destination);
break;
case 'image/webp':
$result = imagewebp($thumbnail, $destination, 85);
break;
default:
$result = false;
}
imagedestroy($image);
imagedestroy($thumbnail);
return $result;
}
// Function to generate video thumbnail
function generateVideoThumbnail($source, $destination) {
// Check if ffmpeg is available
$ffmpeg = trim(shell_exec('which ffmpeg 2>/dev/null'));
if (empty($ffmpeg)) {
return false;
}
// Generate thumbnail from video at 1 second mark
// -i: input file
// -ss: seek to 1 second
// -vframes 1: extract one frame
// -vf: scale to 200x200 maintaining aspect ratio
$command = sprintf(
'%s -i %s -ss 00:00:01 -vframes 1 -vf "scale=200:200:force_original_aspect_ratio=decrease" %s 2>&1',
escapeshellarg($ffmpeg),
escapeshellarg($source),
escapeshellarg($destination)
);
exec($command, $output, $return_code);
return $return_code === 0 && file_exists($destination);
}
?>