SugarCRM 7.9卸载包时无法删除自定义字段的技术问询
Let's break down why your post-uninstall script isn't working when using ModuleLoader, and how to fix it.
First: Check Your Manifest's Post-Uninstall Configuration
The most likely issue is an incorrect format in your manifest.php for the post_uninstall hook. Sugar expects each script entry to use the from key, not a numeric index.
Wrong:
'post_uninstall' => [ [ 0 => '<basepath>/post_uninstall.php' ] ]
Correct:
'post_uninstall' => [ [ 'from' => '<basepath>/post_uninstall.php' ] ]
If the format is wrong, ModuleLoader won't execute your script at all—explaining why manual runs work but uninstall gets stuck.
Second: Improve Your Post-Uninstall Script
Even with the right manifest, your script might be missing critical context or cleanup steps. Here's a revised version that handles edge cases and ensures proper cache clearing:
<?php // Block direct access to the script if (!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); $fieldsByModule = [ 'Users' => [ 'field1_c', 'field2_c', 'field3_c', 'field4_c', 'field5_c', 'field6_c' ], ]; foreach ($fieldsByModule as $moduleName => $fields) { // Get a valid DynamicField instance for the module $dynField = new DynamicField(); $dynField->bean = BeanFactory::getBean($moduleName); $dynField->module = $moduleName; foreach ($fields as $field) { // Only attempt deletion if the field exists to avoid errors $existingField = $dynField->getField($field); if ($existingField) { // Delete the field from the database and metadata $dynField->deleteField($field); // Clear module-specific cache immediately SugarCache::instance()->clearCache($moduleName); } } } // Clear global metadata cache to ensure changes take effect MetadataManager::getManager()->clearCache();
Key Improvements:
- Added a valid entry point check to comply with Sugar's security rules.
- Checks if the field exists before deleting, preventing fatal errors that could halt the uninstall process.
- Clears module and global metadata cache to avoid conflicts with the "Rebuilding Platforms" step.
Alternative: Let Sugar Handle Field Deletion Automatically
If you properly define your custom fields in the manifest.php custom_fields array, Sugar's ModuleLoader will automatically install and uninstall these fields for you—no need for a post-uninstall script.
Example of a complete custom field definition in manifest.php:
$installdefs = [ 'id' => 'user_custom_fields_package', 'name' => 'User Custom Fields', 'description' => 'Adds custom fields to the Users module', 'version' => '1.0', 'author' => 'Your Name', 'custom_fields' => [ [ 'name' => 'field1_c', 'label' => 'Field 1', 'module' => 'Users', 'type' => 'varchar', 'len' => 255, 'required' => false, 'audited' => false, 'massupdate' => false, 'duplicate_merge' => 'disabled', ], // Repeat for field2_c to field6_c ], // Other install definitions... ];
This is the recommended approach because it leverages Sugar's native module management system, reducing the chance of conflicts or missed cleanup steps.
Why Your Original Script Caused a Hang
When the uninstall process reaches "Rebuilding Platforms", it's regenerating module metadata. If your script was either not executing (due to manifest format) or leaving stale cache data, this step could stall while trying to reconcile inconsistent metadata. Fixing the manifest and adding cache clearing resolves this conflict.
内容的提问来源于stack exchange,提问作者maciey_b

