Associated Tags Controller Documentation
File: /controllers/associatedtag.php
Purpose: Manages product and document tags for categorization and search functionality
Last Updated: December 20, 2024
Total Functions: 7 actions
Lines of Code: ~104
---
๐ Overview
The Associated Tags Controller is a lightweight tagging system that enables flexible categorization and labeling of products, documents, or other entities. It provides:
- โข Simple tag creation and management
- โข Tag search and autocomplete functionality
- โข Soft delete capability (conditions-based)
- โข AJAX-powered tag suggestions
- โข JSON API endpoints for frontend integration
- โข User-specific tag ownership tracking
Primary Functions
- โ Create new tags with names
- โ Edit existing tag names
- โ Soft delete tags (set conditions = 1)
- โ List all active tags
- โ AJAX autocomplete search API
- โ User ownership tracking
- โ Date stamping for audit trails
Related Controllers
- โข productController.php - Product tagging
- โข sellbillController.php - Document tagging
- โข buyBillController.php - Purchase order tagging
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|---|---|---|
| **associatedtags** | Tag master data | id, tagname, today, conditions, userid |
CREATE TABLE associatedtags (
id INT PRIMARY KEY AUTO_INCREMENT,
tagname VARCHAR(255) NOT NULL,
today DATETIME NOT NULL,
conditions TINYINT DEFAULT 0, -- 0=active, 1=deleted
userid INT NOT NULL
);
---
๐ Key Functions
1. Default Action - Add Tag Form
Location: Lines 18-22
Purpose: Display simple form to create new tags
Process Flow:
1. Load header template
2. Display add form template
3. Load footer template
4. No authentication required (open access)
Template: associatedtagview/add.html
---
2. show - List All Tags
Location: Lines 22-28
Purpose: Display all active tags in tabular format
Process Flow:
1. Authenticate user access
2. Query all tags where conditions = 0
3. Assign tags to template
4. Display with header/footer
SQL Query:
SELECT associatedtags.* FROM `associatedtags` WHERE conditions = 0
Template: associatedtagview/show.html
---
3. edit - Load Tag for Editing
Location: Lines 29-36
Purpose: Load specific tag data for modification
Process Flow:
1. Authenticate user access
2. Get tag ID from GET parameter with filtering
3. Load tag record using RedBean ORM
4. Assign to edit template
5. Display edit form
Security: Uses filter_input(INPUT_GET, 'id') for sanitization
Template: associatedtagview/edit.html
---
4. add - Create New Tag
Location: Lines 37-50
Purpose: Process new tag creation from form submission
Process Flow:
1. Extract tag name from POST with filtering
2. Create new RedBean dispense object
3. Set tag properties (name, date, user, status)
4. Store in database
5. Redirect to success or error page
RedBean Operations:
$associatedtags = R::dispense('associatedtags');
$associatedtags->today = $today;
$associatedtags->conditions = 0;
$associatedtags->userid = $userid;
$associatedtags->tagname = $tagname;
R::store($associatedtags);
---
5. update - Modify Existing Tag
Location: Lines 51-64
Purpose: Update tag name and metadata
Process Flow:
1. Get tag name and ID from POST with filtering
2. Load existing tag record
3. Update properties (name, date, user)
4. Store changes to database
5. Redirect to success or error page
Key Difference: Preserves original conditions value, only updates name and audit fields
---
6. del - Soft Delete Tag
Location: Lines 65-75
Purpose: Deactivate tag without removing historical data
Process Flow:
1. Get tag ID from GET parameter
2. Load tag record
3. Set conditions = 1 (soft delete)
4. Store updated record
5. Redirect to success or error page
Soft Delete Logic:
$associatedtags = R::load('associatedtags', $id);
$associatedtags->conditions = 1;
R::store($associatedtags);
---
7. getTags - AJAX Autocomplete API
Location: Lines 76-89
Purpose: Provide JSON API for tag search and autocomplete
Function Signature:
// GET Parameters:
// term - Search term for tag name
// page_limit - Maximum results to return (integer)
Process Flow:
1. Extract search term and limit from GET
2. Query tags with LIKE matching on name
3. Format results as JSON array with id/text pairs
4. Return JSON response for frontend consumption
SQL Query:
SELECT * FROM associatedtags
WHERE conditions = 0
AND tagname LIKE "%{term}%"
LIMIT {page_limit}
JSON Response Format:
[
{"id": 1, "text": "Electronics"},
{"id": 2, "text": "Clothing"},
{"id": 3, "text": "Books"}
]
---
๐ Workflows
Workflow 1: Tag Creation and Usage
---
Workflow 2: AJAX Tag Search Integration
---
๐ URL Routes & Actions
| URL Parameter | Description | Authentication | Response | |
|---|---|---|---|---|
| `do=` (empty) | Show add tag form | No | HTML form | |
| `do=show` | List all active tags | Yes | HTML table | |
| `do=edit&id=X` | Edit specific tag | Yes | HTML form | |
| `do=add` | Create new tag | No | Redirect | |
| `do=update` | Update existing tag | No | Redirect | |
| `do=del&id=X` | Soft delete tag | No | Redirect | |
| `do=getTags&term=X&page_limit=N` | AJAX search API | No | JSON | |
| `do=sucess` | Success message | No | HTML | |
| `do=error` | Error message | No | HTML |
Create Tag (do=add):
- โข
tagname- Tag name/label
Update Tag (do=update):
- โข
tagname- Updated tag name - โข
id- Tag ID to update
Delete Tag (do=del):
- โข
id- Tag ID to deactivate
Search Tags (do=getTags):
- โข
term- Search string for tag name matching - โข
page_limit- Maximum results (integer)
---
๐ Security & Permissions
Authentication Matrix
Action | Auth Required | User Restrictions
----------------|---------------|------------------
Add Form | No | Open access
Show Tags | Yes | View all tags
Edit Tag | Yes | Edit any tag
Create Tag | No | Auto-assign userid
Update Tag | No | No ownership check
Delete Tag | No | Delete any tag
AJAX Search | No | Public API
Input Sanitization
- โข GET Parameters: Uses
filter_input()for ID and search terms - โข POST Parameters: Uses
filter_input(INPUT_POST)for tag names - โข SQL Injection: Protected by RedBean ORM parameterized queries
Business Rules
1. Tag Names: No length limits enforced in code
2. Soft Delete: Uses conditions flag instead of physical deletion
3. User Ownership: Records creating user but no access restrictions
4. Public API: AJAX search endpoint has no authentication
---
๐งฎ Integration Points
Frontend Integration
// Example autocomplete integration
$.ajax({
url: 'associatedtag.php?do=getTags',
data: {
term: searchTerm,
page_limit: 10
},
success: function(data) {
// data is array of {id, text} objects
populateDropdown(JSON.parse(data));
}
});
Product Tagging Integration
// Example usage in product forms
$tagIds = $_POST['tagids']; // Array of selected tag IDs
$tagString = is_array($tagIds) ? implode(',', $tagIds) : '';
$product->tags = $tagString; // Store as comma-separated IDs
---
๐ Performance Considerations
Database Optimization
1. Indexes Needed:
- associatedtags(conditions) - For active tag filtering
- associatedtags(tagname) - For search performance
- associatedtags(userid) - For user-specific queries
2. Query Optimization:
- LIKE queries can be slow on large datasets
- Consider full-text indexing for better search
- Limit results with reasonable page_limit values
Caching Opportunities
- โข Frequently used tags could be cached
- โข AJAX search results suitable for browser caching
- โข Tag dropdown lists can be cached per user session
---
๐ Common Issues & Troubleshooting
1. AJAX Search Not Working
Issue: Autocomplete returns no results
Cause: Search term contains special characters or query limit too low
Debug:
-- Test search query manually
SELECT * FROM associatedtags
WHERE conditions = 0
AND tagname LIKE '%searchterm%'
LIMIT 10;
2. Tags Disappear from Lists
Issue: Tags not showing in dropdown
Cause: Tags soft-deleted (conditions = 1)
Fix:
-- Check tag status
SELECT id, tagname, conditions FROM associatedtags WHERE id = ?;
-- Reactivate if needed
UPDATE associatedtags SET conditions = 0 WHERE id = ?;
3. Duplicate Tags Created
Issue: Multiple tags with same name
Cause: No uniqueness constraint in database
Prevention:
-- Add unique constraint
ALTER TABLE associatedtags
ADD CONSTRAINT uk_tagname_active
UNIQUE KEY (tagname, conditions);
---
๐งช Testing Scenarios
Test Case 1: Basic Tag Management
1. Access tag add form (no auth required)
2. Create tag with descriptive name
3. Verify tag appears in listing (requires auth)
4. Edit tag name
5. Verify changes saved
6. Soft delete tag
7. Confirm tag no longer appears in active lists
Test Case 2: AJAX Search API
1. Create several test tags with related names
2. Test search with partial matches
3. Verify JSON response format
4. Test with special characters in search
5. Test pagination with page_limit parameter
6. Verify only active tags returned
Test Case 3: Integration Testing
1. Create tags via management interface
2. Test tag selection in product forms
3. Verify tag associations save correctly
4. Test tag search in product filters
5. Confirm tag deletion doesn't break references
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข productController.php - Product tagging integration
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur