Skip to content

Instantly share code, notes, and snippets.

@md-riaz
Created March 3, 2025 06:01
Show Gist options
  • Save md-riaz/90b076c4baba5b461fc72c605d7962a3 to your computer and use it in GitHub Desktop.
Save md-riaz/90b076c4baba5b461fc72c605d7962a3 to your computer and use it in GitHub Desktop.
<?php
class Attachment
{
private $allowedTypes = [];
private $allowedSize; // Size in MB
private $uploadPath;
private $fileName;
private $files;
private $errors = [];
/**
* Set allowed MIME types for attachments.
*
* @param array $types
*/
public function setAllowedTypes(array $types)
{
$this->allowedTypes = $types;
}
/**
* Set allowed file size in MB.
*
* @param float|int $size
*/
public function setAllowedSize($size)
{
$this->allowedSize = $size * 1024 * 1024; // Convert MB to bytes
}
/**
* Set the upload directory path.
*
* @param string $path
*/
public function setUploadPath($path)
{
$this->uploadPath = rtrim($path, '/') . '/';
}
/**
* Set the upload file name pattern.
*
* @param string $name
*/
public function setFileName($name)
{
$this->fileName = $name;
}
/**
* Set the files array.
*
* @param array $files
*/
public function setFiles(array $files)
{
$this->files = $files;
}
/**
* Get any upload errors encountered during the process.
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* Upload files to the specified directory.
*
* @return bool
*/
public function upload()
{
// Check if files are set
if (!$this->files || !isset($this->files['name'])) {
$this->errors[] = 'No files to upload.';
return false;
}
// Ensure the upload path exists
if (!is_dir($this->uploadPath) && !mkdir($this->uploadPath, 0755, true)) {
$this->errors[] = 'Failed to create upload directory.';
return false;
}
// Process each file
foreach ($this->files['name'] as $key => $fileName) {
$fileTmp = $this->files['tmp_name'][$key];
$fileType = $this->files['type'][$key];
$fileSize = $this->files['size'][$key];
$error = $this->files['error'][$key];
if ($error !== UPLOAD_ERR_OK) {
$this->errors[] = "Error uploading file $fileName: " . $this->getFileUploadError($error);
continue;
}
// Validate file type
if (!in_array($fileType, $this->allowedTypes)) {
$this->errors[] = "File type not allowed for $fileName.";
continue;
}
// Validate file size
if ($fileSize > $this->allowedSize) {
$this->errors[] = "File $fileName exceeds the maximum allowed size of " . $this->allowedSize / (1024 * 1024) . " MB.";
continue;
}
// Generate a target file name
$targetFileName = $this->getUniqueFileName($fileName);
$targetFilePath = $this->uploadPath . $targetFileName;
// Move the file to the upload directory
if (!move_uploaded_file($fileTmp, $targetFilePath)) {
$this->errors[] = "Failed to move uploaded file $fileName.";
continue;
}
}
return empty($this->errors);
}
/**
* Generate a unique file name.
*
* @param string $originalName
* @return string
*/
private function getUniqueFileName($originalName)
{
$extension = pathinfo($originalName, PATHINFO_EXTENSION);
return $this->fileName . '_' . uniqid() . '.' . $extension;
}
/**
* Translate file upload errors to human-readable messages.
*
* @param int $errorCode
* @return string
*/
private function getFileUploadError($errorCode)
{
$errors = [
UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive specified in the HTML form.',
UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.',
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.',
UPLOAD_ERR_EXTENSION => 'A PHP extension stopped the file upload.',
];
return $errors[$errorCode] ?? 'Unknown upload error.';
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment