# Trongate-v2---Simple-Uploader **Repository Path**: wfdaj/Trongate-v2---Simple-Uploader ## Basic Information - **Project Name**: Trongate-v2---Simple-Uploader - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-12-17 - **Last Updated**: 2026-10-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Simple Uploader - Trongate v2 Teaching Module A minimal file upload example demonstrating core Trongate v2 patterns using text-based files. **For educational purposes only** - not intended for production use. ## Module Purpose **Goal:** Teach fundamental file upload patterns in Trongate v2 using the simplest possible implementation. **File types:** TXT, MD, CSV, LOG (text-based files) **Key concept:** Upload a file → Store it → Display success. Nothing more. **Note:** For production file uploads with database storage and management features, use the `file_uploader` module. For image uploads with resizing/thumbnails, use the `image` module. ## Architecture: The Three-Method Pattern This module demonstrates Trongate's recommended pattern for handling POST requests: ```php index() // Display form submit_upload() // Process upload + redirect success() // Display result ``` **Benefit:** Each method has a single, clear responsibility. No mixed concerns. No code duplication. ## Installation ```bash # Create module directory mkdir -p modules/simple_uploader # Create uploads subdirectory mkdir -p modules/simple_uploader/uploads chmod 755 modules/simple_uploader/uploads # Place files # - Simple_uploader.php → modules/simple_uploader/ # - upload_form.php → modules/simple_uploader/views/ # - upload_success.php → modules/simple_uploader/views/ ``` Access at: `yoursite.com/simple_uploader` ## Code Walkthrough ### Controller: `Simple_uploader.php` **Method 1: `index()` - Display Form** ```php function index() { $data['view_module'] = 'simple_uploader'; $data['view_file'] = 'upload_form'; $this->view('upload_form', $data); } ``` *Responsibility:* Render the upload interface. Nothing else. **Method 2: `submit_upload()` - Process Upload** ```php function submit_upload() { // 1. Validate FIRST $this->validation->set_rules( 'userfile', 'File', 'required|allowed_types[txt,md,csv,log]|max_size[500]' ); $result = $this->validation->run(); // 2. If valid: upload and redirect if ($result === true) { $config['destination'] = 'uploads'; $config['upload_to_module'] = true; $config['make_rand_name'] = false; $file_info = $this->file->upload($config); // Redirect with filename (already URL-safe from sanitize_filename) set_flashdata('File uploaded successfully!'); redirect('simple_uploader/success/' . $file_info['file_name']); } else { // 3. If invalid: show form with errors $this->index(); } } ``` *Responsibility:* - Validate the file (required, type, size) - Upload only if validation passes - Redirect to prevent duplicate submissions **Why redirect?** Prevents the "Confirm Form Resubmission" warning on refresh. **Method 3: `success()` - Display Result** ```php function success() { // Filename from URL segment (no decoding needed - sanitize_filename makes it safe) $filename = segment(3); $data['filename'] = $filename; $data['view_module'] = 'simple_uploader'; $data['view_file'] = 'upload_success'; $this->view('upload_success', $data); } ``` *Responsibility:* Retrieve filename from URL and display success page. **No `urlencode()` or `urldecode()` needed** because `sanitize_filename()` creates URL-safe filenames automatically. ## Validation Rules Explained ```php 'required|allowed_types[txt,md,csv,log]|max_size[500]' ``` | Rule | Purpose | |-------------------|----------------------------------------------| | `required` | File must be selected | | `allowed_types` | Only .txt, .md, .csv, .log extensions allowed| | `max_size` | Maximum file size: 500 KB | **Validation happens BEFORE upload** - catching errors early without wasting server resources. ## Configuration Options ```php $config['destination'] = 'uploads'; $config['upload_to_module'] = true; $config['make_rand_name'] = false; ``` | Option | Effect | |-----------------------|------------------------------------------------------------------------| | `destination` | Target directory within module | | `upload_to_module` | Store relative to module path (`modules/simple_uploader/uploads/`) | | `make_rand_name` | `false` = keep original filename (URL-safe via sanitize_filename) | ## Key Architectural Concepts ### 1. The File Module is a Utility The `File` module is **not a controller** - it's a standalone utility class: ```php class File { // Note: does NOT extend Trongate public function __construct() { block_url_invocation('file'); // Cannot access via URL } } ``` You use it via `$this->file` from within controllers. This is a **security feature**, not a bug. ### 2. No Manual Session Manipulation Needed While `set_flashdata()` uses sessions for messages, you **never manually store/retrieve the filename in sessions**. The filename travels via URL segment, making it: - Bookmarkable - Easier to debug - Cleaner than hidden session data ### 3. URL-Safe Filenames Automatically The `File` module uses `sanitize_filename()` which: - Removes/replaces special characters - Prevents null byte attacks - Transliterates international characters - Creates URL-safe names **Result:** No need for `urlencode()`/`urldecode()` in your controller. ## Common Mistakes (And How to Avoid Them) ### Mistake 1: Rendering View Directly in submit_upload() ❌ **Wrong:** ```php function submit_upload() { if ($result === true) { $this->view('upload_success', $data); // Don't! } } ``` ✅ **Right:** (As shown in actual code) ```php function submit_upload() { if ($result === true) { redirect('simple_uploader/success/' . $filename); } } ``` **Why:** Prevents duplicate uploads on page refresh. ### Mistake 2: Full Path Destinations ❌ **Wrong:** ```php $config['destination'] = '/var/www/html/uploads'; ``` ✅ **Right:** (As shown in actual code) ```php $config['destination'] = 'uploads'; $config['upload_to_module'] = true; ``` **Why:** Module-relative paths are portable and cleaner. ### Mistake 3: Skipping Validation ❌ **Wrong:** ```php // Upload then validate (too late!) $file_info = $this->file->upload($config); $this->validation->set_rules(...); ``` ✅ **Right:** (As shown in actual code) ```php // Validate then upload $this->validation->set_rules(...); if ($this->validation->run() === true) { $file_info = $this->file->upload($config); } ``` **Why:** Catch errors before wasting server resources. ## Extending This Module Once you understand this simple example, try these enhancements: ### 1. Change File Types ```php 'required|allowed_types[pdf,doc,docx]|max_size[2000]' ``` ### 2. Enable Random Names ```php $config['make_rand_name'] = true; // Prevents filename collisions ``` ### 3. Add Database Storage ```php $data = [ 'file_name' => $file_info['file_name'], 'file_size' => $file_info['file_size'], 'uploaded_at' => time() ]; $this->model->insert($data, 'uploaded_files'); ``` ## Learning Path ### Stage 1: Understand This Module - Run it and upload a few text files - Study the three methods and their separation - Trace the flow: form → processing → success ### Stage 2: Modify It - Change allowed file types - Try `make_rand_name = true` - Add a file listing page ### Stage 3: Advanced Features - Study the `file_uploader` module (production-ready) - Add user authentication - Add delete functionality ## Frequently Asked Questions ### Q: Why can't I access /file/upload directly? **A:** The File module is a utility library, not a controller. It's designed for internal use only: ```php $this->file->upload($config); // ✅ Correct your-site.com/file/upload // ❌ Blocked by design ``` This prevents malicious access to file operations. ### Q: Why not use this in production? **A:** This module intentionally omits: - User authentication - Admin templates - Database storage - File management (edit/delete) - Pagination - Advanced security For production, use the `file_uploader` module. ### Q: Why use URL segment instead of session for filename? **A:** - **Cleaner:** No manual session handling - **Debuggable:** URL shows exactly what file was uploaded - **Bookmarkable:** Success page can be revisited - **Framework-aligned:** Follows Trongate's stateless patterns ### Q: What if I need multiple file uploads? **A:** This example handles one file. For multiple files, you'd need to: - Loop through `$_FILES` array - Modify validation rules - Handle each file individually See the `file_uploader` module for a production example. ### Q: Why text files instead of images? **A:** Text files are simpler for teaching: - No dimension validation needed - Clear separation from the `image` module - Common in real applications (logs, CSVs, configs) - Fewer concepts to learn at once ## Summary: What This Module Teaches ✅ **Three-method controller pattern** ✅ **Validation before processing** ✅ **POST-Redirect-GET pattern** ✅ **Using utility modules (`$this->file`)** ✅ **URL-safe filename handling** ✅ **Flash messages for user feedback** ✅ **Clean separation of concerns** ## Next Steps 1. **Master this module** - Understand every line 2. **Study `file_uploader`** - See production implementation 3. **Study `image` module** - Learn image-specific features 4. **Build your own** - Apply patterns to custom modules **Ready to upload files the Trongate way!**