File Uploads
FILE MANAGEMENT
Contents
1. Image Uploads — DGZ_Uploader
1.1 Overview and Architecture
1.2 Choosing the Right Class
1.3 The $modify Parameter — the Key to Everything
1.4 DGZ_Upload — Base Class Reference
1.5 DGZ_Uploader — Child Class Reference
1.6 DGZ_Thumbnail — Thumbnail Engine Reference
1.7 Scenarios and Code Examples
A. Simple image upload (no thumbnail)
B. Image upload with automatic thumbnail
C. Upload with thumbnail in a separate folder
D. Upload images into a per-record sub-folder
E. Uploading a document (PDF)
F. Uploading a video or audio file
G. Multiple file upload
H. Controlling thumbnail dimensions and quality
I. Generating a thumbnail from an already-uploaded file
J. Displaying uploaded images in a view
1.8 Supported File Types
1.9 Config Integration (configs/app.php)
1.10 Error Handling and Messages
1.11 Backwards Compatibility Notes
PDF Generation — moved to its own page (see "PDF Generation" in the sidebar)
1. Image Uploads — DGZ_Uploader
1.1 Overview and Architecture
⚙️ Server requirement — the GD extension. Thumbnail generation uses PHP's GD library (
imagecreatefrompng(),imagecreatefromjpeg(),imagecreatefromwebp(), etc.). The server's PHP must have GD enabled, with support for the formats you upload (PNG, JPEG, GIF, WebP). If GD is missing you'll get a fatalCall to undefined function ...imagecreatefrompng()at upload time. On shared / cPanel hosting, enable it under Select PHP Version → Extensions →gd. (Declared asext-gdin Dorguzen'scomposer.json.)
Dorguzen ships a three-class file upload system in core/DGZ_Uploader/:
┌─────────────────────────────────────────────────────────────────────────┐
│ core/DGZ_Uploader/ │
│ │
│ DGZ_Upload ← base class │
│ Validation, move_uploaded_file(), conflict-safe renaming. │
│ Works for images, documents, videos — any file type. │
│ Does NOT generate thumbnails. │
│ │
│ DGZ_Uploader ← child class (extends DGZ_Upload) │
│ Everything DGZ_Upload does, PLUS optional thumbnail generation. │
│ This is the class you use for image uploads in web features. │
│ │
│ DGZ_Thumbnail ← thumbnail engine (used by DGZ_Uploader) │
│ PHP GD-based proportional resize, quality control, WebP support. │
│ Can also be used standalone on already-uploaded files. │
└─────────────────────────────────────────────────────────────────────────┘
The flow when you call move('resize') on a DGZ_Uploader instance:
HTTP upload ($_FILES)
│
▼
DGZ_Uploader::move('resize')
│
├── validates MIME type
├── validates file size
├── move_uploaded_file() → saves original (e.g. photo.jpg)
│
└── DGZ_Thumbnail::create()
├── reads image dimensions with getimagesize()
├── calculates proportional thumbnail size (max 200px longest side)
├── imagecopyresampled() ← high-quality bilinear resampling
└── saves thumbnail (e.g. photo_thb.jpg, quality 82)
1.2 Choosing the Right Class
Scenario Use
────────────────────────────────────────── ─────────────────────────────
Upload an image, no thumbnail needed DGZ_Upload with 'original'
Upload an image + generate a thumbnail DGZ_Uploader with 'resize'
Upload an admin image, skip all checks DGZ_Uploader with 'original-allow'
Upload a PDF or text document DGZ_Upload + addPermittedTypes()
Upload a video or audio file DGZ_Upload with 'original-allow'
Re-thumbnail an already-uploaded image DGZ_Thumbnail standalone
1.3 The $modify Parameter — the Key to Everything
Both classes have a single move() method. The $modify string argument controls
what happens. Think of it as the upload mode:
move('original')
Validates MIME type and file size. Saves the file as-is. No thumbnail.
This is the default and the safe choice for image uploads.
move('original-allow')
Bypasses ALL validation — no type check, no size check. The file is
saved unconditionally. Use this for admin-only upload forms where you
trust the user, or for file types outside the built-in whitelist
(videos, audio, ZIP files, etc.).
⚠ Never expose this mode to unauthenticated users.
move('resize')
Validates MIME type and file size, saves the original, then
automatically generates a _thb thumbnail. Only meaningful on
DGZ_Uploader (calling it on DGZ_Upload just does a plain upload).
The second argument, $overwrite (bool, default false), controls what happens
when a file with the same name already exists at the destination:
false (default) — keeps both files; the new one is renamed (photo_1.jpg,
photo_2.jpg, etc.)
true — overwrites the existing file silently
1.4 DGZ_Upload — Base Class Reference
File: core/DGZ_Uploader/DGZ_Upload.php
Constructor:
new DGZ_Upload(string $destinationPath)
$destinationPath — absolute filesystem path to the upload directory.
Must already exist and be writable.
Public methods:
move(string $modify = 'original', bool $overwrite = false) : void
Triggers the upload pipeline. Reads from $_FILES automatically.
See §1.3 for the $modify values.
getMessages() : array
Returns an array of human-readable outcome strings, one per file:
"photo.jpg uploaded successfully"
"photo.jpg exceeds maximum size: 50.0kB"
"video.mp4 is not a permitted type of file."
Always check this after move() to give feedback to the user.
extension(string $filename) : string [static]
Returns the file extension of a filename without the dot.
DGZ_Upload::extension('sunset.jpg') // 'jpg'
$uploader->extension($filenames[0]) // instance call also works
thumbName(string $filename, string $suffix = '_thb') : string [static]
Derives the thumbnail filename from an original filename.
Use this anywhere you need to display the thumbnail — in views,
services, or API responses — without repeating the pathinfo() logic.
DGZ_Upload::thumbName('sunset.jpg') // 'sunset_thb.jpg'
DGZ_Upload::thumbName('hero.PNG', '_sm') // 'hero_sm.PNG'
$uploader->thumbName($filenames[0]) // instance call also works
The $suffix must match whatever was passed to DGZ_Thumbnail::setSuffix().
When using the default suffix (_thb), the second argument can be omitted.
getFilenames() : array
Returns the final saved filename(s) after any conflict renaming.
Store this in your database — it is the name that was actually written
to disk, which may differ from what the user uploaded.
By design, getFilenames() returns ONLY the original file names, never
the thumbnail names. This is intentional: thumbnail names do not need
to be stored because they are always mechanically derivable from the
original. Strip the extension, append _thb, put the extension back —
that is always the thumbnail name. Since the thumbnail is generated from
the original in the same operation, conflict renaming applies to both at
once: if the original is saved as sunset_1.jpg (because sunset.jpg was
already taken), the thumbnail will be sunset_1_thb.jpg. They are always
in sync, so there is nothing extra to store or look up.
The one exception: if you explicitly call DGZ_Thumbnail::setSuffix() to
use a suffix other than _thb, make sure you use that same suffix
consistently wherever you derive the thumbnail name in your views.
Since _thb is the default and there is rarely a reason to change it,
in practice this is never an issue.
setMaxSize(int|string $size) : void
Overrides the default 50 KB file size limit.
Accepts a human-readable string (recommended) or a raw integer in bytes.
The string is case-insensitive and the space between number and unit is
optional. Decimal values are supported.
$uploader->setMaxSize('2MB'); // 2 megabytes
$uploader->setMaxSize('500KB'); // 500 kilobytes
$uploader->setMaxSize('1.5 MB'); // 1.5 megabytes
$uploader->setMaxSize('1GB'); // 1 gigabyte (large video, admin only)
$uploader->setMaxSize(5242880); // raw bytes — still works (5 MB)
$uploader->setMaxSize(5 * 1024 * 1024); // expression — still works
Supported units: B, KB, MB, GB (case-insensitive).
If no unit is given the value is treated as bytes.
getMaxSize() : string
Returns the current limit formatted for display: e.g. "50.0kB".
addPermittedTypes(array $mimes) : void
Appends extra MIME types to the whitelist. Only types from the
$alsoValid list inside isValidMime() are accepted:
'image/tiff', 'image/webp', 'application/pdf',
'text/plain', 'text/rtf'
Example: $uploader->addPermittedTypes(['application/pdf'])
Default permitted image types:
image/gif, image/jpeg, image/pjpeg, image/png, image/webp
1.5 DGZ_Uploader — Child Class Reference
File: core/DGZ_Uploader/DGZ_Uploader.php
Inherits everything from DGZ_Upload and adds thumbnail support.
Constructor:
new DGZ_Uploader(string $path, string $uniqueSubFolder = '')
$path — EITHER a key from your configs/app.php array that maps to an
absolute directory path, OR an absolute path directly. If the key is found
in config, that value is used as the destination. Otherwise, $path itself
is used as an absolute path.
$uniqueSubFolder — optional sub-directory under $path. Useful when each
record (portfolio item, news article, product) has its own image folder.
Example: passing '42/' gives destination '/absolute/path/portfolioImages/42/'
The constructor ensures a trailing slash.
The constructor also reads maxFileUploadSize from configs/app.php and
applies it automatically. You do not need to call setMaxSize() manually
unless you want a different limit than the global config.
Additional methods (beyond DGZ_Upload):
setThumbMaxSize(int $pixels) : self
Sets the maximum pixel dimension for the generated thumbnail.
Default: 200. The thumbnail is scaled proportionally so neither
width nor height exceeds this value. The original file is always
saved at its full uploaded size — only the thumbnail is capped.
Call before move('resize').
$uploader = new DGZ_Uploader('galleryImagesPath');
$uploader->setThumbMaxSize(150);
$uploader->move('resize');
Returns $this so calls can be chained.
setThumbDestination(string $path) : void
Redirects thumbnail output to a different folder from the original.
Must be called before move(). If not called, thumbnails land in the
same directory as the original.
1.6 DGZ_Thumbnail — Thumbnail Engine Reference
File: core/DGZ_Uploader/DGZ_Thumbnail.php
Used internally by DGZ_Uploader. Also usable standalone when you need to re-thumbnail a file that was already uploaded, or batch-process existing images.
Constructor:
new DGZ_Thumbnail(string $absoluteImagePath)
Reads the image from disk. If unreadable or not a supported format,
errors are added to getMessages() and create() will do nothing safely.
Default settings:
$_maxSize = 500 DGZ_Thumbnail's own internal default, longest side in pixels.
NOTE: when DGZ_Uploader calls this class via move('resize'),
it overrides this to 200px automatically. The 500px default
only applies when you use DGZ_Thumbnail standalone (e.g.
batch re-thumbnailing). A 1200×800 image becomes 500×333.
To change the default when used via DGZ_Uploader, call
$uploader->setThumbMaxSize() before move('resize') instead
of setMaxSize() on DGZ_Thumbnail directly.
$_suffix = '_thb' appended to base filename before the extension:
hero.jpg → hero_thb.jpg
$_quality = 82 JPEG and WebP output quality (1–100).
82 is the web industry standard: excellent visual quality
at roughly 60% the file size of quality 100.
PNG always uses compression level 6 (level 0 =
uncompressed; level 9 = maximum compression).
Public methods:
setDestination(string $path) : void
Sets the output directory for the thumbnail. Called automatically by
DGZ_Uploader. Must be called before create() when using standalone.
setMaxSize(int $pixels) : void
Change the thumbnail size cap. Default 500. Example: setMaxSize(300)
caps the longest dimension at 300px.
setSuffix(string $suffix) : void
Change the thumbnail suffix. Leading underscore is added automatically
if missing. setSuffix('thumb') produces _thumb. setSuffix('_sm') stays _sm.
setSuffix('') removes the suffix entirely (thumbnail saves with same
base name as original — careful, may overwrite!).
setQuality(int $quality) : void
Sets JPEG and WebP output quality. Accepts 1–100.
Recommendations:
90 near-lossless, larger files — use for print-quality originals
82 default — excellent for web display
75 good quality, noticeably smaller — use for heavily-trafficked pages
60 visible compression artefacts — use only for thumbnails of thumbnails
create() : void
Runs the resize pipeline: calculateSize → getName → createThumbnail.
Safe to call even if the image was unreadable — it will just add a
message and do nothing.
getMessages() : array
Returns outcome strings: "hero_thb.jpg created successfully." or
"Couldn't create a thumbnail for hero.jpg"
Supported input → output formats:
JPEG (.jpg/.jpeg) → JPEG
PNG (.png) → PNG (alpha transparency preserved)
GIF (.gif) → GIF
WebP (.webp) → WebP (alpha transparency preserved)
Images smaller than $_maxSize on both sides are saved at their original
dimensions — they are never upscaled, only downscaled.
1.7 Scenarios and Code Examples
A. Simple image upload (no thumbnail)
Upload a user's avatar or a news article hero image when a thumbnail is not needed. Uses DGZ_Upload directly.
use Dorguzen\Core\DGZ_Uploader\DGZ_Upload;
// HTML form: <input type="file" name="news_image">
$destination = '/Applications/MAMP/htdocs/myapp/assets/images/news/';
$uploader = new DGZ_Upload($destination);
$uploader->move('original'); // validate + upload, no thumbnail
$messages = $uploader->getMessages();
$filenames = $uploader->getFilenames();
if (!empty($filenames)) {
$savedAs = $filenames[0]; // e.g. 'hero.jpg' or 'hero_1.jpg' if renamed
// save $savedAs to your database row
} else {
// upload failed — show $messages to the user
}
B. Image upload with automatic thumbnail (the recommended pattern)
This is the pattern to use for news articles, portfolio items, newsletters, blog posts, gallery images — anywhere you show a grid of thumbnails and open the full-size image on click.
move('resize') uploads the original AND generates the _thb thumbnail in one
call. You only ever store the original filename in the database; the thumbnail
name is always reconstructable from it.
use Dorguzen\Core\DGZ_Uploader\DGZ_Uploader;
// 'portfolioImagesPath' is a key in configs/app.php pointing to the
// absolute upload folder. See §1.9 for how to set this up.
$uploader = new DGZ_Uploader('portfolioImagesPath');
$uploader->move('resize');
$messages = $uploader->getMessages();
$filenames = $uploader->getFilenames();
if (!empty($filenames)) {
$original = $filenames[0]; // 'sunset.jpg' — save this in the DB
// thumbnail saved automatically as 'sunset_thb.jpg' in the same folder
}
// --- In your view, deriving the thumbnail name ---
// Never store the thumbnail name in the DB. Use the built-in helper:
$thumb = DGZ_Upload::thumbName($original); // 'sunset_thb.jpg'
C. Upload with thumbnail in a separate folder
Useful when you want full-resolution originals in one place and web-displayable thumbnails in another (e.g. originals in /full/, thumbs in /thumbs/ for CDN delivery).
$uploader = new DGZ_Uploader('portfolioImagesPath');
$uploader->setThumbDestination(
'/Applications/MAMP/htdocs/myapp/assets/images/portfolio/thumbs/'
);
$uploader->move('resize');
$filenames = $uploader->getFilenames();
// Original: /assets/images/portfolio/sunset.jpg
// Thumbnail: /assets/images/portfolio/thumbs/sunset_thb.jpg
D. Upload images into a per-record sub-folder
For features like a portfolio or product catalogue where each item has its own directory. Pass the record's ID (or slug) as the second constructor arg. The folder must already exist and be writable — create it when you create the DB record.
// After INSERT, get the new record ID:
$itemId = $this->portfolioModel->getLastInsertId();
// Create the sub-folder (only if it doesn't exist yet):
$basePath = '/Applications/MAMP/htdocs/myapp/assets/images/portfolio/';
$subDir = $basePath . $itemId . '/';
if (!is_dir($subDir)) {
mkdir($subDir, 0755, true);
}
// Upload into that sub-folder:
$uploader = new DGZ_Uploader('portfolioImagesPath', $itemId . '/');
$uploader->move('resize');
// Files land at: /assets/images/portfolio/42/hero.jpg
// /assets/images/portfolio/42/hero_thb.jpg
E. Uploading a document (PDF or plain text)
DGZ_Upload's default whitelist only allows images. To accept PDFs, you must
add the MIME type with addPermittedTypes(). You also need to raise the max
size since the default 50 KB limit is too small for most documents.
use Dorguzen\Core\DGZ_Uploader\DGZ_Upload;
$uploader = new DGZ_Upload('/Applications/MAMP/htdocs/myapp/storage/docs/');
$uploader->addPermittedTypes(['application/pdf']);
$uploader->setMaxSize('10MB');
$uploader->move('original');
$messages = $uploader->getMessages();
$filenames = $uploader->getFilenames();
Note: PHP's own upload size limits (upload_max_filesize and post_max_size in
php.ini) also apply and must be raised server-side for large files. The
setMaxSize() call here adds an application-level guard on top of that.
F. Uploading a video or audio file
Videos and audio files have MIME types not in the DGZ whitelist at all
(video/mp4, audio/mpeg, etc.). The cleanest approach is 'original-allow'
mode, which bypasses all type and size checks. Reserve this for admin forms.
use Dorguzen\Core\DGZ_Uploader\DGZ_Upload;
// Admin-only: upload a video with no type or size restriction.
// 'original-allow' bypasses setMaxSize() too, so no need to set it here.
$uploader = new DGZ_Upload('/Applications/MAMP/htdocs/myapp/storage/videos/');
$uploader->move('original-allow');
$messages = $uploader->getMessages();
$filenames = $uploader->getFilenames();
⚠ Important: PHP still enforces upload_max_filesize and post_max_size from
php.ini regardless of $modify. For large video files, raise these in your
php.ini or .htaccess:
upload_max_filesize = 512M
post_max_size = 512M
max_execution_time = 300
Alternative: for public-facing video upload with type checking, use
addPermittedTypes() and setMaxSize() — but do NOT use isValidMime() for
video MIME types as they are not in its allowed list. You would need to
extend the class and override isValidMime() for that use case.
G. Multiple file upload
The class handles multi-file inputs automatically. Your HTML form just needs the multiple attribute and array notation in the name:
<input type="file" name="gallery_images[]" multiple>
The PHP side is identical to a single upload:
$uploader = new DGZ_Uploader('galleryImagesPath');
$uploader->move('resize');
$filenames = $uploader->getFilenames();
// $filenames = ['photo1.jpg', 'photo2.jpg', 'photo3_thb.jpg' ... ]
// Wait — getFilenames() returns only the originals, not thumbnails.
// Thumbnails are generated silently alongside each original.
foreach ($filenames as $name) {
// save each $name to the database
}
// Messages are collected for each file individually:
foreach ($uploader->getMessages() as $msg) {
echo $msg . "\n";
// "photo1.jpg uploaded successfully"
// "photo2.jpg uploaded successfully and renamed photo2_1.jpg"
// "huge.jpg exceeds maximum size: 50.0kB"
}
H. Controlling thumbnail dimensions and quality
DGZ_Uploader creates thumbnails with default settings (200px max side, quality 82). The original file is always saved at full uploaded size.
To override the thumbnail max size, call setThumbMaxSize() before move():
$uploader = new DGZ_Uploader('galleryImagesPath');
$uploader->setThumbMaxSize(300); // cap thumbnail at 300px longest side
$uploader->move('resize');
$filenames = $uploader->getFilenames();
// original: photo.jpg (full size) | thumbnail: photo_thb.jpg (≤300px)
To also override quality, use DGZ_Thumbnail standalone after the upload:
Step 1 — upload the original only (no thumbnail yet):
$uploader = new DGZ_Uploader('galleryImagesPath');
$uploader->move('original');
$filenames = $uploader->getFilenames();
Step 2 — generate a custom thumbnail with full control:
use Dorguzen\Core\DGZ_Uploader\DGZ_Thumbnail;
$destDir = '/Applications/MAMP/htdocs/myapp/assets/images/gallery/';
$original = $destDir . $filenames[0];
$thumb = new DGZ_Thumbnail($original);
$thumb->setDestination($destDir);
$thumb->setMaxSize(300); // cap at 300px longest side
$thumb->setQuality(75); // slightly more compression (default is 82)
$thumb->create();
foreach ($thumb->getMessages() as $msg) {
echo $msg; // "photo_thb.jpg created successfully."
}
Quality guide:
90 — near-lossless, ~40% larger than default; good for high-quality prints
82 — default, excellent web quality
75 — still good, noticeably smaller files; good for high-traffic pages
60 — visible artefacts; only for tiny thumbnails where size is critical
I. Generating a thumbnail from an already-uploaded file
If you have images on disk that were uploaded without thumbnails (e.g. before DGZ_Uploader was adopted), you can batch-generate thumbnails using DGZ_Thumbnail standalone.
use Dorguzen\Core\DGZ_Uploader\DGZ_Thumbnail;
$sourceDir = '/Applications/MAMP/htdocs/myapp/assets/images/portfolio/';
$thumbDir = $sourceDir . 'thumbs/'; // must already exist
foreach (glob($sourceDir . '*.{jpg,jpeg,png,gif,webp}', GLOB_BRACE) as $file) {
// skip files that are already thumbnails
if (strpos(basename($file), '_thb.') !== false) continue;
$thumb = new DGZ_Thumbnail($file);
$thumb->setDestination($thumbDir);
$thumb->create();
foreach ($thumb->getMessages() as $msg) {
echo $msg . "\n";
}
}
Run this as a one-off CLI script or a controller action behind an admin route.
J. Displaying uploaded images in a view
Store only the original filename in your database column. In your view, build
the file path using getFileRootPath() from Config, and derive the thumbnail
name from the original filename.
In your service/controller, pass the image filename to the view:
$item = $this->portfolioModel->getItem($id);
// $item['portfolio_image'] = 'sunset.jpg'
In your view:
<?php
use Dorguzen\Core\DGZ_Uploader\DGZ_Upload;
$imgPath = $this->controller->config->getFileRootPath() . 'assets/images/portfolio/';
$original = $item['portfolio_image']; // 'sunset.jpg'
$thumbnail = DGZ_Upload::thumbName($original); // 'sunset_thb.jpg'
?>
<!-- Thumbnail in grid (fast load): -->
<img src="<?= $imgPath . $thumbnail ?>" alt="Portfolio item">
<!-- Link to full-size on click: -->
<a href="<?= $imgPath . $original ?>">
<img src="<?= $imgPath . $thumbnail ?>" alt="Portfolio item">
</a>
1.8 Supported File Types
For image upload and thumbnail generation:
Format MIME type Upload Thumbnail Notes
────── ─────────────── ─────── ────────── ──────────────────────────────
JPEG image/jpeg ✓ ✓ Most common for photos
JPEG image/pjpeg ✓ ✓ Progressive JPEG (IE legacy)
PNG image/png ✓ ✓ Alpha transparency preserved
GIF image/gif ✓ ✓ Animation is not preserved
WebP image/webp ✓ ✓ 25-35% smaller than JPEG
For other file types (via addPermittedTypes or 'original-allow'):
Format MIME type Upload Thumbnail Notes
────── ───────────────────── ─────── ────────── ──────────────────────
PDF application/pdf ✓ ✗ Via addPermittedTypes()
TXT text/plain ✓ ✗ Via addPermittedTypes()
RTF text/rtf ✓ ✗ Via addPermittedTypes()
TIFF image/tiff ✓ ✗ Via addPermittedTypes()
Video video/* (any) ✓ ✗ Use 'original-allow' mode
Audio audio/* (any) ✓ ✗ Use 'original-allow' mode
1.9 Config Integration (configs/app.php)
DGZ_Uploader's constructor looks up path keys in your configs/app.php array.
Define your upload destinations there rather than hardcoding absolute paths:
// configs/app.php
return [
// ... other config ...
'newsImagesPath' => '/Applications/MAMP/htdocs/myapp/assets/images/news/',
'portfolioImagesPath' => '/Applications/MAMP/htdocs/myapp/assets/images/portfolio/',
'galleryImagesPath' => '/Applications/MAMP/htdocs/myapp/assets/images/gallery/',
'newsletterImagesPath' => '/Applications/MAMP/htdocs/myapp/assets/images/newsletters/',
'maxFileUploadSize' => '2MB',
];
Then in your controller or service:
$uploader = new DGZ_Uploader('newsImagesPath'); // looks up config key
$uploader->move('resize');
maxFileUploadSize is automatically applied by DGZ_Uploader's constructor —
you do not need to call setMaxSize() separately.
Remember: in production the absolute path changes. Set the correct absolute
paths per environment in their respective configs/app.php or use APP_ENV
branching inside configs/app.php to resolve the right path.
1.10 Error Handling and Messages
Always check getMessages() after move(). A successful upload produces a
message like "photo.jpg uploaded successfully". A failed upload produces an
error message — but the method does NOT throw an exception, so you must check:
$uploader->move('resize');
$filenames = $uploader->getFilenames();
$messages = $uploader->getMessages();
if (empty($filenames)) {
// Nothing was saved — show messages as user-facing errors
$errors = $messages;
} else {
$savedAs = $filenames[0];
// Check messages anyway — some may be warnings (e.g. renamed)
}
Common messages:
"photo.jpg uploaded successfully"
"photo.jpg uploaded successfully and renamed photo_1.jpg"
"photo.jpg exceeds maximum size: 50.0kB"
"video.mp4 is not a permitted type of file."
"No file selected."
"Error uploading photo.jpg. Please try again." ← partial upload
"System error uploading photo.jpg. Contact webmaster."
"photo_thb.jpg created successfully."
"Couldn't create a thumbnail for photo.jpg"
1.11 Backwards Compatibility Notes
The following improvements were made to the class system. All changes are backwards compatible — no public method signatures were altered.
Behaviour changes in DGZ_Thumbnail:
-
Thumbnails now correctly receive the
_thbsuffix. Previously the$_suffixproperty was defined ('_thb') but was never actually applied increateThumbnail()— a bug meaning thumbnails were saved with the SAME name as the original, silently overwriting it. This is now fixed: hero.jpg generates hero_thb.jpg. If you have thumbnails on disk from before this fix, they will have been saved without the suffix (same name as original). New thumbnails will use the suffix. Keep this in mind when displaying older uploaded images. -
JPEG output quality changed from 100 to 82. Quality 100 is lossless JPEG — the largest possible file size with no visible benefit over 82. Quality 82 is the web industry standard.
-
PNG compression changed from 0 to 6. Level 0 means uncompressed — PNG files at full size. Level 6 is the standard web default: good compression ratio, fast decode.
-
WebP is now a supported upload and thumbnail format (was silently rejected before). Alpha transparency is preserved for WebP and PNG.
-
setQuality()method added to DGZ_Thumbnail for per-use quality control. -
Default thumbnail dimension changed from 500px to 200px (DGZ_Uploader). DGZ_Uploader now passes 200px to DGZ_Thumbnail automatically when calling
move('resize'). Previously the thumbnail inherited DGZ_Thumbnail's own default of 500px, meaning a 500×400 source image produced an identically- sized thumbnail. Thumbnails are now always a fraction of the main image. DGZ_Thumbnail's own internal default (500px) is unchanged — this only affects thumbnails generated throughDGZ_Uploader::move('resize'). To override: call$uploader->setThumbMaxSize(n)beforemove('resize'). New method added:DGZ_Uploader::setThumbMaxSize(int $pixels): self
PDF generation has its own page — see PDF Generation.