Check Redundant Names Controller Documentation
File: /controllers/checkRedundantNames.php
Purpose: Data quality validation system for checking name uniqueness across all system entities
Last Updated: December 20, 2024
Total Functions: 2
Lines of Code: ~602
---
๐ Overview
The Check Redundant Names Controller is a comprehensive data quality validation system that ensures name uniqueness across all system entities. It handles:
- โข Real-time name validation during data entry
- โข Cross-entity name conflict detection
- โข Category-specific validation rules
- โข AJAX-based validation responses
- โข Multi-entity validation support
- โข Edit-mode validation (exclude current record)
- โข Comprehensive entity coverage
- โข Performance-optimized validation queries
Primary Functions
- โ Real-time name uniqueness validation
- โ Multi-entity validation support (40+ entity types)
- โ Category-specific validation for products
- โ Edit-mode validation (exclude current record)
- โ AJAX-based validation responses
- โ Performance-optimized queries
- โ Comprehensive entity coverage
- โ Data quality enforcement
Related Controllers
- โข productController.php - Product management
- โข clientController.php - Customer management
- โข supplierController.php - Supplier management
- โข All entity management controllers
---
๐๏ธ Database Tables
Entity Validation Coverage (40+ Tables)
| Entity Type | Table Name | Validation Field | Special Rules | |
|---|---|---|---|---|
| **Product Categories** | productcat | productCatName | Hierarchy-aware | |
| **Products** | product | productName | Category-specific | |
| **Assets** | assets | assetsName | Standard validation | |
| **Asset Categories** | assetscat | cattitel | Standard validation | |
| **Banks** | bank | bankname | Standard validation | |
| **Bank Accounts** | bankaccount | accountname | Standard validation | |
| **Clients** | client | clientname | Standard validation | |
| **Client Codes** | client | clientcode | Code validation | |
| **Cost Centers** | costcenter | name | Standard validation | |
| **Expense Types** | expensestype | expensestypename | Standard validation |
The system validates names across these entities:
- โข Financial: banks, bankaccounts, saves, expenses, policies
- โข Inventory: products, productcats, units, stores, suppliers
- โข Personnel: users, usergroups, employees, workshops
- โข Operations: branches, shippercompanies, billnames, billproperties
- โข Customer Management: clients, clientareas, typeclients
- โข Restaurant: restauranthalls, restauranttables, restaurantplaystations
- โข System: playStationCards, employeegroups, employeesubgroups
- โข Assets: assets, assetcategories, spareParts
---
๐ Key Functions
1. Default Action (empty $do) - Real-Time Validation
Location: Line 343
Purpose: Perform real-time name validation during data entry
Parameters:
$name = $_GET['name']; // Name to validate
$tablename = $_GET['tablename']; // Entity type
$catid = $_GET['catid']; // Category ID (for products)
Process Flow:
1. Extract validation parameters from GET request
2. Handle category ID for product-specific validation
3. Call checkName() function with parameters
4. Return validation result (0=unique, 1=duplicate)
Category Handling:
if (!isset($catid) && $catid == '-1') {
$catid = 0;
}
checkName($name, $tablename, $catid);
---
2. Edit Mode Validation (do=checkNameWithId) - Exclude Current Record
Location: Line 353
Purpose: Validate name uniqueness while excluding the current record being edited
Parameters:
$name = $_GET['name']; // New name to validate
$id = $_GET['id']; // Current record ID to exclude
$tablename = $_GET['tablename']; // Entity type
Process Flow:
1. Load Current Record: Get existing name for the record being edited
2. Name Comparison: Check if name actually changed
3. Conditional Validation: Only validate if name changed
4. Category Extraction: For products, extract category from existing data
Entity-Specific Loading:
switch ($tablename) {
case "productcat":
$data = $productCatDAO->load($id);
$oldName = $data->productCatName;
break;
case "client":
$data = $myClientRecord->load($id);
$oldName = $data->clientname;
break;
case "product":
$data = $productExt->loadEX($id);
$oldName = $data->productName;
$catid = $data->productCatId; // Extract category
break;
// ... 40+ other cases
}
Change Detection Logic:
if ($name != $oldName) {
if ($tablename == "product") {
if (isset($catid) && $catid != 0) {
checkName($name, $tablename, $catid);
}
} else {
checkName($name, $tablename, 0);
}
} else {
echo $flag; // No change, return success
}
---
3. checkName() - Core Validation Logic
Location: Line 537
Purpose: Execute the actual name validation with comprehensive entity support
Function Signature:
function checkName($name, $tablename, $catid)
Validation Process:
1. Parameter Validation: Ensure name and table are provided
2. Entity-Specific Queries: Execute appropriate DAO query for each entity
3. Special Product Logic: Handle category-specific product validation
4. Result Determination: Return 0 (unique) or 1 (duplicate)
Comprehensive Validation Chain:
if (($tablename == "productcat" && (count($productCatDAO->queryByProductCatName($name)) > 0)) ||
($tablename == "assets" && (count($myAssetsRecord->queryByAssetsName($name)) > 0)) ||
($tablename == "bank" && (count($myBankRecord->queryByBankname($name)) > 0)) ||
// ... 40+ other entity checks
) {
$flag = '1'; // Duplicate found
} elseif ($tablename == "product") {
// Special product category validation
if (isset($catid) && $catid != 0) {
if (count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0) {
$flag = '1';
} else {
$flag = '0';
}
}
} else {
$flag = '0'; // Unique name
}
Product Category Validation:
// Products can have same name in different categories
if ($tablename == "product") {
$catid = $_GET['catid'];
if (isset($catid) && $catid != 0) {
if (count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0) {
$flag = '1'; // Duplicate in same category
} else {
$flag = '0'; // Unique within category
}
}
}
---
๐ Workflows
Workflow 1: Real-Time Name Validation
---
Workflow 2: Edit Mode Validation
---
๐งฎ Calculation Methods
Validation Logic Algorithm
function checkName($name, $tablename, $catid) {
$flag = '0'; // Default: unique
if (isset($name) && $name != "" && isset($tablename) && $tablename != "") {
// Build comprehensive validation chain
$isDuplicate = false;
// Check each entity type
switch ($tablename) {
case 'productcat':
$isDuplicate = count($productCatDAO->queryByProductCatName($name)) > 0;
break;
case 'client':
$isDuplicate = count($myClientRecord->queryByClientname($name)) > 0;
break;
case 'product':
// Special category-specific logic
if (isset($catid) && $catid != 0) {
$isDuplicate = count($productExt->checkForProductNameInOneCategory2($name, $catid)) > 0;
}
break;
// ... handle all 40+ entity types
}
$flag = $isDuplicate ? '1' : '0';
}
echo $flag;
}
Performance Optimization
// Optimized query pattern for large datasets
function optimizedNameCheck($name, $tablename) {
// Use indexed queries with LIMIT 1 for existence checks
$query = "SELECT 1 FROM {$tablename} WHERE name_field = ? LIMIT 1";
$result = executeQuery($query, [$name]);
return count($result) > 0 ? 1 : 0;
}
---
๐ Security & Permissions
Input Validation
// Secure parameter handling
$name = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
$tablename = filter_input(INPUT_GET, 'tablename', FILTER_SANITIZE_STRING);
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
// Validate table name against whitelist
$allowedTables = [
'productcat', 'client', 'supplier', 'product',
'bank', 'store', 'unit', 'usergroup',
// ... all valid entity types
];
if (!in_array($tablename, $allowedTables)) {
die('Invalid table name');
}
SQL Injection Prevention
// DAO-based queries prevent SQL injection
// Example secure query:
$results = $productCatDAO->queryByProductCatName($name);
// This uses parameterized queries internally
Access Control Recommendations
// Add user permission checks
function validateAccess($tablename) {
$userPermissions = $_SESSION['user_permissions'];
switch ($tablename) {
case 'client':
return $userPermissions['manage_clients'] ?? false;
case 'product':
return $userPermissions['manage_products'] ?? false;
// ... other permission checks
}
return false;
}
---
๐ Performance Considerations
Database Optimization
1. Required Indexes:
-- Create indexes on name fields for all validated entities
CREATE INDEX idx_productcat_name ON productcat(productCatName);
CREATE INDEX idx_client_name ON client(clientname);
CREATE INDEX idx_product_name_category ON product(productName, productCatId);
CREATE INDEX idx_supplier_name ON supplier(suppliername);
```
2. **Query Optimization**:
- Use LIMIT 1 for existence checks
- Index all name fields used in validation
- Optimize category-specific product queries
3. **Caching Strategy**:
```php
// Cache validation results for session duration
if (!isset($_SESSION['name_cache'])) {
$_SESSION['name_cache'] = [];
}
$cacheKey = md5($name . $tablename . $catid);
if (isset($_SESSION['name_cache'][$cacheKey])) {
echo $_SESSION['name_cache'][$cacheKey];
return;
}
$result = checkName($name, $tablename, $catid);
$_SESSION['name_cache'][$cacheKey] = $result;
```
### Memory Management
php
// Efficient processing for batch validations
function batchValidateNames($validationList) {
$results = [];
foreach ($validationList as $validation) {
$result = checkName($validation['name'], $validation['table'], $validation['catid']);
$results[] = $result;
// Clear any large objects
unset($validation);
}
return $results;
}
---
## ๐ Common Issues & Troubleshooting
### 1. **False Positive Duplicates**
**Issue**: Validation shows duplicate when name should be allowed
**Cause**: Category-specific logic not applied correctly
**Debug**:
php
// Add debugging to checkName function
echo "Checking: name=$name, table=$tablename, catid=$catid
";
if ($tablename == "product") {
$duplicates = $productExt->checkForProductNameInOneCategory2($name, $catid);
echo "Found " . count($duplicates) . " duplicates in category $catid
";
}
### 2. **Edit Mode Not Working**
**Issue**: Edit validation fails when name unchanged
**Cause**: Record loading or name comparison errors
**Debug**:
php
// Debug edit mode validation
echo "Record ID: $id
";
echo "Old name: '$oldName'
";
echo "New name: '$name'
";
echo "Names equal: " . ($name == $oldName ? 'YES' : 'NO') . "
";
### 3. **Performance Issues**
**Issue**: Slow validation responses
**Cause**: Missing indexes or inefficient queries
**Solution**:
php
// Profile validation queries
$start = microtime(true);
$result = checkName($name, $tablename, $catid);
$duration = microtime(true) - $start;
if ($duration > 0.1) { // Log slow queries
error_log("Slow validation: {$duration}s for $tablename:$name");
}
---
## ๐งช Testing Scenarios
### Test Case 1: Basic Name Validation
1. Enter new unique name
2. Verify returns 0 (valid)
3. Enter existing name
4. Verify returns 1 (invalid)
5. Test with special characters
6. Verify proper handling
### Test Case 2: Category-Specific Product Validation
1. Create product in category A
2. Try same name in category A (should fail)
3. Try same name in category B (should succeed)
4. Verify category isolation works
### Test Case 3: Edit Mode Validation
1. Edit existing record without changing name
2. Verify validation passes
3. Change to existing name
4. Verify validation fails
5. Change to new unique name
6. Verify validation passes
### JavaScript Integration Test
javascript
// Example client-side validation
function validateEntityName(name, tablename, catid, callback) {
$.ajax({
url: 'checkRedundantNames.php',
data: {
name: name,
tablename: tablename,
catid: catid || 0
},
success: function(response) {
callback(response == '0'); // true if unique
}
});
}
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข Data Quality Management Guide - Complete data validation procedures
- โข Entity Management Documentation - All entity controllers
- โข Database Schema Documentation - Table relationships and constraints
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When new entities are added to the system