The Pramnos Framework includes a comprehensive media management system that handles file uploads, image processing, thumbnail generation, and media organization. The system provides automatic resizing, cropping, rotation, and supports various media types including images, documents, and PDFs.
- Overview
- Basic Usage
- Media Types
- File Upload
- Image Processing
- Thumbnails
- Media Organization
- Advanced Features
- Database Schema
- API Reference
The Media system consists of several key components:
- MediaObject (
\Pramnos\Media\MediaObject) - Main media management class - ResizeTools (
\Pramnos\Media\ResizeTools) - Image resizing and processing - Thumbnail (
\Pramnos\Media\Thumbnail) - Thumbnail representation - File Management - Organized storage with automatic directory creation
- Multi-format Support: Images (JPG, PNG, GIF, BMP, ICO), PDFs, Office documents
- Automatic Processing: Thumbnail generation, image resizing, orientation fixing
- Organized Storage: Hierarchical directory structure by date and module
- Usage Tracking: Track media usage across different modules
- Deduplication: Automatic detection and linking of duplicate files
- Image Manipulation: Rotate, crop, resize with quality preservation
- Responsive Images: Multiple thumbnail sizes for different use cases
use Pramnos\Media\MediaObject;
// Create new media object
$media = new MediaObject();
// Set basic properties
$media->mediatype = 1; // 1 = image
$media->name = 'Sample Image';
$media->description = 'A sample image for demonstration';
$media->module = 'gallery';// Upload from $_FILES
$media = new MediaObject();
$result = $media->uploadFile($_FILES['file'], 'gallery');
if ($media->error === false) {
echo "File uploaded successfully! Media ID: " . $media->mediaid;
} else {
echo "Upload failed: " . $media->error;
}// Add an existing image file
$media = new MediaObject();
$media->addImage('/path/to/existing/image.jpg', 'gallery', true); // true = delete original
// Add remote image
$media = new MediaObject();
$media->addRemoteImage('https://example.com/image.jpg', 'gallery');The system supports different media types with specific handling:
// Media type constants
$media->mediatype = 0; // Generic file
$media->mediatype = 1; // Image
$media->mediatype = 2; // Emoticon/small image
$media->mediatype = 3; // PDF document
$media->mediatype = 4; // Flash media (deprecated)
$media->mediatype = 5; // Video// Images get automatic thumbnails and resizing
$imageMedia = new MediaObject();
$imageMedia->mediatype = 1;
$imageMedia->max = 1024; // Max width/height
$imageMedia->medium = 600; // Medium size
$imageMedia->thumb = 120; // Thumbnail size
// PDFs get placeholder thumbnails
$pdfMedia = new MediaObject();
$pdfMedia->mediatype = 3;// Handle form upload
if (isset($_FILES['upload'])) {
$media = new MediaObject();
// Set upload constraints
$media->max = 2048; // Max size: 2048px
$media->medium = 800; // Medium size: 800px
$media->thumb = 150; // Thumbnail: 150px
$media->deleteOriginal = false; // Keep original
$media->uploadFile($_FILES['upload'], 'user_uploads');
if ($media->error === false) {
$media->save();
echo "Upload successful: " . $media->url;
}
}// Fix multiple file upload array structure
\Pramnos\General\Helpers::fixFilesArray($_FILES);
foreach ($_FILES['uploads'] as $file) {
$media = new MediaObject();
$media->uploadFile($file, 'gallery');
if ($media->error === false) {
$media->save();
}
}$media = new MediaObject();
// Set allowed file types
$media->mediatype = 1; // Images only
// Upload will automatically validate:
// - File type (by extension and MIME type)
// - File size (by server limits)
// - Image dimensions
// - Security (filename sanitization)
$result = $media->uploadFile($_FILES['file'], 'gallery');$media = new MediaObject();
// Set processing options
$media->max = 1920; // Maximum dimension
$media->maxHeight = 1080; // Maximum height
$media->medium = 800; // Medium size
$media->mediumHeight = 600; // Medium height
$media->thumb = 200; // Thumbnail size
$media->thumbHeight = 150; // Thumbnail height
$media->fixOrientation = true; // Fix EXIF orientation
$media->uploadFile($_FILES['image'], 'gallery');// Load existing media
$media = new MediaObject();
$media->load(123);
// Process image with new settings
$media->processImage($media->filename, dirname($media->filename));
$media->save();$media = new MediaObject();
$media->load(123);
// Rotate image
$media->rotateLeft(); // 90 degrees left
$media->rotateRight(); // 90 degrees right
$media->rotate(45); // Custom angle// Thumbnails are created automatically during upload
$media = new MediaObject();
$media->uploadFile($_FILES['image'], 'gallery');
// Access thumbnails
foreach ($media->thumbnails as $thumbnail) {
echo "Size: " . $thumbnail->x . "x" . $thumbnail->y . "\n";
echo "URL: " . $thumbnail->url . "\n";
echo "Reason: " . $thumbnail->reason . "\n"; // 'original', 'medium', 'thumb'
}$media = new MediaObject();
$media->load(123);
// Get predefined sizes
$thumb = $media->getThumb(); // Standard thumbnail
$medium = $media->getMedium(); // Medium size
$original = $media->getOriginal(); // Original size
// Get custom size (creates if doesn't exist)
$custom = $media->get(300, 200, true); // 300x200, cropped$media = new MediaObject();
$media->load(123);
// Create custom size thumbnail
$thumbnail = $media->get(
400, // Width
300, // Height
true, // Crop to exact size
false, // Don't force recreation
false, // No debug
true // Use resampling for quality
);
echo "Custom thumbnail URL: " . $thumbnail->url;// Files are organized by module
$media = new MediaObject();
$media->uploadFile($_FILES['file'], 'gallery'); // Goes to /uploads/gallery/
$media->uploadFile($_FILES['file'], 'products'); // Goes to /uploads/products/
$media->uploadFile($_FILES['file'], 'blog'); // Goes to /uploads/blog/The system automatically creates a hierarchical directory structure:
www/uploads/
├── gallery/
│ ├── 2024/
│ │ ├── 01/
│ │ │ ├── 15/
│ │ │ │ ├── image1.jpg
│ │ │ │ └── thumb_image1.jpg
│ │ │ └── 16/
│ │ └── 02/
│ └── 2023/
└── products/
└── 2024/
// Track where media is used
$media = new MediaObject();
$media->load(123);
// Add usage
$media->addUsage(
'blog', // Module
'post-456', // Specific item ID
'Featured Image', // Title
'Main blog post image', // Description
'featured,blog', // Tags
1 // Order
);
// Get all usages
$usages = $media->getUsages('blog');
foreach ($usages as $usage) {
echo "Used in: " . $usage->usageModule . " - " . $usage->usageSpecific;
}// The system automatically detects duplicates by MD5 hash
$media = new MediaObject();
$media->uploadFile($_FILES['file'], 'gallery');
// If file already exists, $media->medialink will point to original
if ($media->medialink > 0) {
echo "This file already exists as Media ID: " . $media->medialink;
}// Get all media linked to the same original
$media = new MediaObject();
$media->load(123);
$linkedMedia = $media->getLinkedMedia();
foreach ($linkedMedia as $linked) {
echo "Linked media ID: " . $linked->mediaid;
}// Update multiple media usages
MediaObject::multipleUsageUpdate(
[123, 456, 789], // Media IDs
'gallery', // Module
'album-1' // Specific ID
);
// Clear all usages for a module
$media = new MediaObject();
$media->clearUsage('old_module', 'item-123');// Get media by type
$media = new MediaObject();
$imageList = $media->getList(1, 'gallery'); // Type 1 (images) from gallery module
// Get media by user
$userMedia = $media->getList(0, '', 123); // All types, any module, user ID 123CREATE TABLE media (
mediaid INT AUTO_INCREMENT PRIMARY KEY,
mediatype INT DEFAULT 0,
userid INT DEFAULT 0,
module VARCHAR(100),
order_field INT DEFAULT 0,
name VARCHAR(255),
filename TEXT,
url TEXT,
shortcut VARCHAR(50),
tags TEXT,
date INT,
views INT DEFAULT 0,
thumbnails TEXT,
filesize INT DEFAULT 0,
description TEXT,
x INT DEFAULT 0,
y INT DEFAULT 0,
usages INT DEFAULT 0,
md5 VARCHAR(32),
medialink INT DEFAULT 0,
otherusers TINYINT DEFAULT 0,
othermodules TINYINT DEFAULT 0
);CREATE TABLE mediause (
usageid INT AUTO_INCREMENT PRIMARY KEY,
mediaid INT,
module VARCHAR(100),
specific VARCHAR(255),
date INT,
title VARCHAR(255),
description TEXT,
tags TEXT,
order_field INT DEFAULT 0,
FOREIGN KEY (mediaid) REFERENCES media(mediaid)
);uploadFile($file, $module, $type)- Upload file from $_FILESuploadImage($file, $module)- Upload image fileaddImage($filepath, $module, $deleteOriginal)- Add existing imageaddRemoteImage($url, $module)- Download and add remote image
processImage($file, $path)- Process uploaded imagerotate($degrees)- Rotate image by degreesrotateLeft()- Rotate 90 degrees leftrotateRight()- Rotate 90 degrees right
get($width, $height, $crop, $force, $debug, $resample)- Get/create thumbnailgetThumb()- Get standard thumbnailgetMedium()- Get medium size imagegetOriginal()- Get original size image
load($mediaid)- Load media by IDsave($force)- Save media to databasedelete()- Delete media and files
addUsage($module, $specific, $title, $description, $tags, $order)- Add usagegetUsages($module, $specific, $removeDuplicates)- Get usage listclearUsage($module, $specific, $safe)- Remove usagesremoveUsage($usageid, $safe)- Remove specific usage
createMd5()- Generate MD5 hash of filegetList($type, $module, $userid)- Get media list
resize($src, $width, $height)- Resize image to dimensionsdisplay($src, $width, $height)- Output resized image directly
$maxsize- Maximum allowed dimension (default: 1024)$defaultwidth- Default width when not specified (default: 120)$crop- Allow cropping when both dimensions set (default: true)$resample- Use resampling for quality (default: true)$fillcolor- Background fill color for resampling (default: "FFFFFF")$debug- Enable debug output (default: false)
$filename- Full file path$url- Web-accessible URL$x- Width in pixels$y- Height in pixels$filesize- File size in bytes$views- View counter$reason- Creation reason ('original', 'medium', 'thumb', 'custom')
// Always validate uploads
$media = new MediaObject();
$media->mediatype = 1; // Restrict to images only
// Set reasonable size limits
$media->max = 2048;
$media->medium = 800;
// Check for errors after upload
if ($media->uploadFile($_FILES['file'], 'gallery') && $media->error === false) {
$media->save();
}// Use appropriate thumbnail sizes
$media = new MediaObject();
$media->thumb = 150; // For listing pages
$media->medium = 600; // For detail views
$media->max = 1920; // For full-size display
// Lazy load thumbnails
$thumbnail = $media->get(200, 200, false, false); // Don't force recreation// Regular cleanup of unused media
$media = new MediaObject();
$unusedMedia = $media->getList(0, '', ''); // Get all media
foreach ($unusedMedia as $item) {
if ($item->usages == 0) {
// Consider for deletion after grace period
if ($item->date < (time() - (30 * 24 * 3600))) { // 30 days old
$item->delete();
}
}
}try {
$media = new MediaObject();
$media->uploadFile($_FILES['file'], 'gallery');
if ($media->error !== false) {
throw new Exception("Upload failed: " . $media->error);
}
$media->save();
} catch (Exception $e) {
\Pramnos\Logs\Logger::log("Media upload error: " . $e->getMessage());
// Handle error appropriately
}- Framework Guide - Core framework concepts
- Database Guide - Database operations
- Theme Guide - Media display in themes
- Framework Guide - Application structure
- Logging Guide - Error logging and debugging
-
Upload Failures
- Check file permissions on upload directory
- Verify PHP upload limits (upload_max_filesize, post_max_size)
- Ensure sufficient disk space
-
Thumbnail Generation Issues
- Verify GD extension is installed
- Check memory limits for large images
- Ensure write permissions on thumbnail directories
-
File Not Found Errors
- Verify file paths are correct
- Check that files weren't manually deleted
- Use the path fixing functionality for migrated sites
-
Performance Issues
- Optimize image sizes before upload
- Use appropriate thumbnail sizes
- Consider CDN for large media libraries
For additional debugging, enable debug mode on ResizeTools and check the application logs for detailed error information.