Fixcats Documentation

Fix Categories Controller Documentation

File: /controllers/fixcats.php

Purpose: Batch category consolidation and product migration utility

Last Updated: December 20, 2024

Total Functions: 1 main script

Lines of Code: ~54

---

โš ๏ธ CRITICAL WARNING

This is a DATA MIGRATION UTILITY

USE WITH EXTREME CAUTION - CAN CAUSE IRREVERSIBLE DATA CHANGES

---

๐Ÿ“‹ Overview

The Fix Categories Controller is a utility script for consolidating product categories by migrating products from multiple categories into a single target category. It:

โšก Critical Use Cases

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Modifications)

Table NamePurposeKey Columns**MODIFICATION TYPE**
**product**Product master dataproductId, productCatId**UPDATES** - Category assignments changed
### Reference Tables (Read-Only)

Table NamePurposeKey ColumnsAccess Type
**productcat**Category hierarchyproductCatId, productCatName, productCatParentRead-only
### System Dependencies

---

๐Ÿ”ง Core Functionality

Main Execution Flow

Location: Lines 27-53

Purpose: Iteratively consolidate orphaned product categories

$newCatId = 1408;  // TARGET CATEGORY - HARDCODED!

1. Category Analysis Query

SELECT GROUP_CONCAT(distinct currentCat.productCatId SEPARATOR ', ')
FROM productcat as currentCat
left join productcat as child on (child.productCatParent = currentCat.productCatId and child.productCatId is Null)
join product on product.productCatId = currentCat.productCatId
where currentCat.productCatId != $newCatId
GROUP BY 'all'

Query Logic:

2. Data Safety Mechanism

$cats = substr($cats, 0, strripos($cats, ","));

3. Iterative Migration Process

do {
    // Generate UPDATE SQL
    $txt = "update product set productCatId = $newCatId where productCatId in ($cats)";
    
    // Execute update
    R::exec($txt);
    
    // Log to file
    fwrite($myfile, $txt . ";\r\n");
    
    // Re-query for remaining categories
    $cats = R::getCell($sql);
    $cats = substr($cats, 0, strripos($cats, ","));
    
} while (!empty($cats))

---

๐Ÿ”„ Workflow

Complete Migration Process

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Category Consolidation
HARDCODED TARGET: Category 1408
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Identify Orphaned Categories
- Find categories with products
- Exclude categories with child categories
- Exclude target category (1408)
- Generate comma-separated ID list
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Safety Processing
- Remove incomplete trailing results
- Ensure clean category ID list
- Prevent partial updates
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Execute Migration
- Update all products in identified categories
- Set productCatId = 1408 for all
- Log SQL statement to file
- Execute via RedBean ORM
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Check for More Categories
- Re-run identification query
- Check if more orphaned categories exist
- Continue if categories found
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
COMPLETE: All orphaned products migrated to 1408
SQL log saved to sql.txt
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐Ÿ“ File Operations

SQL Log Generation

File: sql.txt (created/appended in same directory)

Purpose: Track all SQL statements executed

Log Format:

update product set productCatId = 1408 where productCatId in (101,102,103,104);
update product set productCatId = 1408 where productCatId in (105,106);

Log Features:

---

โš ๏ธ Safety Considerations

Data Safety Issues

1. HARDCODED TARGET: Category ID 1408 is fixed in code

2. NO ROLLBACK: No undo mechanism provided

3. NO VALIDATION: No checks if target category exists

4. BATCH UPDATES: Large number of products changed at once

5. NO BACKUP: Script doesn't create backups

Recommended Safety Measures

BEFORE EXECUTION:

-- 1. BACKUP AFFECTED TABLES
CREATE TABLE product_backup_YYYYMMDD AS SELECT * FROM product;

-- 2. VERIFY TARGET CATEGORY EXISTS
SELECT * FROM productcat WHERE productCatId = 1408;

-- 3. CHECK CURRENT DISTRIBUTION
SELECT productCatId, COUNT(*) as product_count 
FROM product 
WHERE productCatId != 1408 
GROUP BY productCatId;

-- 4. IDENTIFY AFFECTED PRODUCTS
SELECT COUNT(*) as affected_products
FROM productcat as currentCat
left join productcat as child on (child.productCatParent = currentCat.productCatId and child.productCatId is Null)
join product on product.productCatId = currentCat.productCatId
where currentCat.productCatId != 1408;

AFTER EXECUTION VERIFICATION:

-- Verify migration results
SELECT productCatId, COUNT(*) as product_count 
FROM product 
GROUP BY productCatId 
ORDER BY product_count DESC;

---

๐Ÿ”’ Security & Permissions

File System Access

Database Access

Session Requirements

---

๐Ÿ› Potential Issues & Risks

1. Target Category Doesn't Exist

Issue: Category 1408 might not exist in database

Result: Database constraint errors

Prevention:

INSERT INTO productcat (productCatId, productCatName, productCatParent) 
VALUES (1408, 'Consolidated Category', 0) 
ON DUPLICATE KEY UPDATE productCatName = productCatName;

2. Foreign Key Constraints

Issue: Other tables might reference product categories

Result: Migration could fail or leave inconsistent data

Check Dependencies:

-- Find tables referencing product categories
SELECT TABLE_NAME, COLUMN_NAME 
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
WHERE REFERENCED_TABLE_NAME = 'productcat';

3. Infinite Loop Risk

Issue: Query might not eventually empty

Result: Script runs indefinitely

Debug: Add iteration counter and break after reasonable limit

4. Large Dataset Performance

Issue: Updating thousands of products at once

Result: Database locks or timeouts

Solution: Add batch size limits

---

๐Ÿงช Testing Strategy

Pre-Production Testing

-- 1. Create test environment
CREATE DATABASE test_erp19;
-- ... import production data

-- 2. Test with small dataset
UPDATE product SET productCatId = 999 WHERE productId IN (1,2,3);

-- 3. Run script and verify
-- 4. Check sql.txt log
-- 5. Verify data integrity

Production Considerations

1. Schedule during low usage

2. Monitor database performance

3. Have rollback plan ready

4. Test on copy of production data first

---

๐Ÿ“š Related Documentation

---

๐Ÿšจ USAGE WARNING

THIS SCRIPT WILL:

THIS SCRIPT WILL NOT:

ONLY RUN IF:

---

Documented By: AI Assistant

Review Status: โœ… Complete - WITH WARNINGS

Next Review: Before ANY execution