Modified AtoM Core Files¶
This document describes the files that differ from a pure AtoM 2.10 installation when using the AHG Framework.
Summary¶
| File | Type | Purpose |
|---|---|---|
config/ProjectConfiguration.class.php |
Replaced | Database-driven plugin loading |
plugins/sfPluginAdminPlugin/.../themesAction.class.php |
Patched | Theme visibility fix |
plugins/qbAclPlugin/lib/QubitAcl.class.php |
Patched | Role 99 duplicate fix |
/etc/nginx/sites-available/atom |
Modified | Framework compatibility |
1. ProjectConfiguration.class.php¶
Location: {ATOM_ROOT}/config/ProjectConfiguration.class.php
Type: Replaced entirely (from template)
Template: atom-framework/config/ProjectConfiguration.class.php.template
What Changed¶
The install script replaces AtoM's default ProjectConfiguration.class.php with a custom version that includes:
- Framework Bootstrap Loading - Initializes Laravel Query Builder
- Database-Driven Plugin Loading -
loadPluginsFromDatabase()function
Key Addition: loadPluginsFromDatabase()¶
/**
* Load plugins from atom_plugin table instead of setting_i18n
*/
protected function loadPluginsFromDatabase(array $corePlugins = []): array
{
$plugins = $corePlugins;
try {
$pdo = new PDO(
'mysql:host=' . sfConfig::get('app_database_host', 'localhost') .
';dbname=' . sfConfig::get('app_database_name'),
sfConfig::get('app_database_user'),
sfConfig::get('app_database_password')
);
$stmt = $pdo->query('SELECT name FROM atom_plugin WHERE is_enabled = 1 ORDER BY load_order');
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
if (!in_array($row['name'], $plugins)) {
$plugins[] = $row['name'];
}
}
} catch (PDOException $e) {
// Fallback to core plugins only
}
return $plugins;
}
Why This Change¶
- Before: AtoM loads plugins from
setting_i18ntable (id=1), a serialized PHP array - After: Plugins loaded from
atom_plugintable with proper fields (is_enabled, load_order, is_locked) - Benefit: Enables CLI management, plugin auditing, and prevents accidental disabling of critical plugins
Legacy Compatibility¶
The setting_i18n table (id=1) is still maintained for:
- The sfPluginAdminPlugin UI (Admin → Plugins)
- Backwards compatibility with AtoM core code
When a plugin is enabled via CLI, both tables are updated.
2. themesAction.class.php¶
Location: {ATOM_ROOT}/plugins/sfPluginAdminPlugin/modules/sfPluginAdminPlugin/actions/themesAction.class.php
Type: Patched (specific lines modified)
What Changed¶
Removed the loop that filters out enabled plugins from the theme list.
Original Code (lines 43-46)¶
Patched Code¶
// Removed: themes should remain visible even when enabled
// foreach (sfPluginAdminPluginConfiguration::$pluginNames as $name) {
// unset($pluginPaths[$name]);
// }
Why This Change¶
Problem: AtoM's default behavior removes enabled plugins from the themes list. When ahgThemeB5Plugin is enabled, it disappears from Admin → Themes, making it impossible to switch or view theme settings.
Root Cause: Symlinks from plugins/ to atom-ahg-plugins/ resolve to their real path, which doesn't match sf_plugins_dir, causing theme detection to fail for enabled plugins.
Solution: Don't filter out enabled plugins - themes should always be visible in the list.
Additional Fixes in This File¶
-
Unserialize Fallback (line ~80):
-
Try/Catch around Plugin Instantiation - Prevents fatal errors if a plugin class fails to load
3. QubitAcl.class.php¶
Location: {ATOM_ROOT}/plugins/qbAclPlugin/lib/QubitAcl.class.php
Type: Patched (specific method modified)
What Changed¶
Added in_array checks in buildUserRoleList() method to prevent duplicate role registration.
Original Code¶
protected function buildUserRoleList($user)
{
// Don't add user twice
if (in_array($user->getUserID(), $this->_roles)) {
return $this;
}
$parents = [];
if ($user->isAuthenticated()) {
// Add authenticated group
$this->acl->addRole(QubitAclGroup::getById(QubitAclGroup::AUTHENTICATED_ID));
$this->_roles[] = QubitAclGroup::AUTHENTICATED_ID;
// Add groups (if user belongs to any)
if (0 < count($aclUserGroups = $user->user->getAclUserGroups())) {
foreach ($aclUserGroups as $aclUserGroup) {
$aclGroup = $aclUserGroup->group;
$this->acl->addRole($aclGroup, $aclGroup->parent);
$this->_roles[] = $aclGroup->id;
$parents[] = $aclGroup->id;
}
}
// ...
}
}
Patched Code¶
protected function buildUserRoleList($user)
{
// Don't add user twice
if (in_array($user->getUserID(), $this->_roles)) {
return $this;
}
$parents = [];
if ($user->isAuthenticated()) {
// Add authenticated group (check first to avoid duplicate)
if (!in_array(QubitAclGroup::AUTHENTICATED_ID, $this->_roles)) {
$this->acl->addRole(QubitAclGroup::getById(QubitAclGroup::AUTHENTICATED_ID));
$this->_roles[] = QubitAclGroup::AUTHENTICATED_ID;
}
// Add groups (if user belongs to any)
if (0 < count($aclUserGroups = $user->user->getAclUserGroups())) {
foreach ($aclUserGroups as $aclUserGroup) {
$aclGroup = $aclUserGroup->group;
if (!in_array($aclGroup->id, $this->_roles)) {
$this->acl->addRole($aclGroup, $aclGroup->parent);
$this->_roles[] = $aclGroup->id;
}
$parents[] = $aclGroup->id;
}
}
// ...
}
}
Why This Change¶
Problem: When a user is in acl_user_group with group_id = 99 (Authenticated), the code:
1. First adds role 99 (AUTHENTICATED_ID) for all authenticated users
2. Then loops through user's groups and tries to add 99 again
3. Zend ACL throws: Role id '99' already exists in the registry
Error Message:
500 | Internal Server Error | Zend_Acl_Role_Registry_Exception
Role id '99' already exists in the registry
Solution: Check in_array before calling addRole to prevent duplicates.
4. Nginx Configuration¶
Location: /etc/nginx/sites-available/atom (or similar)
Type: Modified for framework compatibility
Standard AtoM Configuration¶
location ~ ^/(index|qubit_dev)\.php(/|$) {
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
AHG Framework Configuration¶
No changes required to nginx for basic framework operation. The framework integrates through PHP, not nginx.
Optional: PHP-FPM Pool Configuration¶
If using auto_prepend_file (alternative loading method):
Location: /etc/php/8.3/fpm/pool.d/atom.conf
; AtoM Framework - auto-prepend (optional, not currently used)
; php_admin_value[auto_prepend_file] = /usr/share/nginx/atom/atom-framework/prepend.php
Current Method: Framework is loaded via ProjectConfiguration.class.php bootstrap, not auto_prepend.
Applying Patches¶
During Fresh Install¶
The bin/install script automatically applies all patches:
Manual Patch Application¶
If patches need to be reapplied (e.g., after AtoM upgrade):
# 1. ProjectConfiguration - just re-run install
cd /usr/share/nginx/atom/atom-framework
bash bin/install
# 2. themesAction.class.php - comment out the unset loop
# Find lines with: foreach (sfPluginAdminPluginConfiguration::$pluginNames
# Comment out the foreach block
# 3. QubitAcl.class.php - add in_array checks
# The install script includes a PHP patcher for this
After AtoM Upgrades¶
When upgrading AtoM core:
- ProjectConfiguration.class.php - Will be overwritten. Re-run
bash bin/install - themesAction.class.php - May be overwritten. Check and re-patch if needed
- QubitAcl.class.php - May be overwritten. Re-run install (includes auto-patch)
Verification Commands¶
# Check ProjectConfiguration has loadPluginsFromDatabase
grep -c "loadPluginsFromDatabase" /usr/share/nginx/atom/config/ProjectConfiguration.class.php
# Check themesAction has the fix (should show commented lines)
grep -c "Removed: themes should remain" /usr/share/nginx/atom/plugins/sfPluginAdminPlugin/modules/sfPluginAdminPlugin/actions/themesAction.class.php
# Check QubitAcl has the fix
grep -c "check first to avoid duplicate" /usr/share/nginx/atom/plugins/qbAclPlugin/lib/QubitAcl.class.php
File Checksums¶
For verification after upgrades:
# Generate checksums of patched files
md5sum /usr/share/nginx/atom/config/ProjectConfiguration.class.php
md5sum /usr/share/nginx/atom/plugins/sfPluginAdminPlugin/modules/sfPluginAdminPlugin/actions/themesAction.class.php
md5sum /usr/share/nginx/atom/plugins/qbAclPlugin/lib/QubitAcl.class.php
Troubleshooting¶
Plugins Not Loading¶
- Check
ProjectConfiguration.class.phphasloadPluginsFromDatabase() - Verify
atom_plugintable exists and has enabled plugins - Clear cache:
php symfony cc
Theme Not Visible in Admin¶
- Check
themesAction.class.phppatch is applied - Verify symlink exists:
ls -la plugins/ahgThemeB5Plugin - Clear cache and restart PHP-FPM
Role 99 Error on Login¶
- Check
QubitAcl.class.phppatch is applied - Verify with:
grep "check first to avoid duplicate" plugins/qbAclPlugin/lib/QubitAcl.class.php - Re-run install script if patch is missing