Support

Admin Tools

#41926 Admin Tools & Joomla 4.4.13 - DB Schema Stuck at 4.4.4, #__user_keys Conflict, and "Class ...Feature\Base not found" Error

Posted in ‘Admin Tools for Joomla! 4 & 5’
This is a public ticket

Everybody will be able to see its contents. Do not include usernames, passwords or any other sensitive information.

Environment Information

Joomla! version
4.4.13, DB-Schema: 4.4.4
PHP version
8.2.12
Admin Tools version
7.8.0, 7.4.5-20

Latest post by findMarcel on Tuesday, 27 May 2025 14:04 CDT

findMarcel

Hi Akeeba Support,

We're experiencing a persistent issue on a Joomla 4.4.13 site where the database schema seems to be stuck at version 4.4.4-2024-03-28, preventing Joomla core SQL updates from running correctly. We suspect a conflict involving Admin Tools and the #__user_keys table, and we're also seeing critical errors related to Admin Tools itself. We're using Admin Tools Professional (latest version 7.8.0 but DB-Version is only at 7.4.5-20231214, updated through Joomla updater).

Primary Problem: Joomla Database Schema Stuck
  1. Our Joomla files are at version 4.4.13.
  2. However, the joomla_update.php log consistently shows the following during core file reinstallation or database checks:

INFO ::1 update Start of SQL updates.
INFO ::1 update The current database version (schema) is 4.4.4-2024-03-28.
INFO ::1 update End of SQL updates.

  1. This indicates that SQL update scripts for Joomla versions after 4.4.4 (e.g., 4.4.5, etc., up to 4.4.13) are not being executed.
    In System -> Maintenance -> Database, we see the "Joomla CMS" entry reporting schema 4.4.4 and a message "377 database changes did not alter table structure and were skipped."
Suspected Cause: #__user_keys Table Conflict
  1. Our #__user_keys table has the following structure, which we believe might be due to Admin Tools' "Admin Access Control / admintools_adminaccess" feature:

CREATE TABLE `joomla_user_keys` (
`id` int(10) UNSIGNED NOT NULL,
`user_id` varchar(150) NOT NULL,
`token` varchar(255) NOT NULL,
`series` varchar(191) NOT NULL,
`time` varchar(200) NOT NULL,
`uastring` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

  1. This structure is missing several columns required by Joomla 4.4.5+ for its core API token functionality (e.g., invalidtime_createdtoken_typemetadata) etc.
  2. We hypothesize that a Joomla core SQL update script (likely 4.4.5-2024-04-29.sql or similar, which attempts to ALTER TABLE #__user_keys) is failing due to this structural mismatch, thereby halting the entire Joomla database schema update sequence.

 

Secondary Problem: Admin Tools Critical Error => Error fixed: by removing admin tools plugin folder and reinstalling latest .zip file

We are also seeing repeated critical errors in our everything.php log file related to Admin Tools:

CRITICAL ::1 error Uncaught Throwable of type Error thrown with message "Class "Joomla\Plugin\System\AdminTools\Feature\Base" not found". Stack trace:
#0 [ROOT]\libraries\vendor\composer\ClassLoader.php(571): include()
#1 [ROOT]\libraries\vendor\composer\ClassLoader.php(428): Composer\Autoload\includeFile('C:\\Web\\xampp\\ht...')
#2 [ROOT]\libraries\src\Autoload\ClassLoader.php(59): Composer\Autoload\ClassLoader->loadClass('Akeeba\\Plugin\\S...')
#3 [internal function]: Joomla\CMS\Autoload\ClassLoader->loadClass('Akeeba\\Plugin\\S...')
#4 [ROOT]\plugins\system\admintools\src\Extension\AdminTools.php(579): class_exists('Akeeba\\Plugin\\S...')
#5 [ROOT]\plugins\system\admintools\src\Extension\AdminTools.php(572): Akeeba\Plugin\System\AdminTools\Extension\AdminTools->loadFeatures()
#6 [ROOT]\plugins\system\admintools\src\Extension\AdminTools.php(171): Akeeba\Plugin\System\AdminTools\Extension\AdminTools->initialize()
#7 [ROOT]\plugins\system\admintools\services\provider.php(45): Akeeba\Plugin\System\AdminTools\Extension\AdminTools->initalisePlugin()
... (further stack trace)

 

This suggests there might be an issue with the Admin Tools installation itself (e.g., missing files, incorrect class loading).

 

Resulting Symptoms:
  • The "API Tokens" tab is missing in User Profiles.
  • The "Web Services" tab is missing in Global Configuration.
  • The persistent "377 database changes ... skipped" message in Joomla Maintenance: Database.
Troubleshooting Steps Taken So Far:
  • Multiple reinstallations of Joomla 4.4.13 core files.
  • Used Admin Tools utilities: "Repair & Optimise Tables," "Clean Temp Directory," and "Reset Joomla Update."
  • Checked Joomla logs (joomla_update.phpeverything.php) and Apache error logs (no explicit SQL errors found during the update process, but the joomla_update.php log confirms the schema update halt, and everything.php shows the Admin Tools critical error).
Our Questions for Akeeba Support:
  1. Could the "Class Joomla\Plugin\System\AdminTools\Feature\Base not found" error be contributing to the Joomla update problems or the #__user_keys table issue? How can we resolve this Admin Tools error?
  2. Is Admin Tools' usage of the #__user_keys table known to conflict with the Joomla 4.4.5+ core API token table structure requirements?
  3. If so, is there a recommended way to configure Admin Tools to avoid this conflict (e.g., use a different table for its "Admin Access Control" feature, or a setting to make it compatible)?
  4. What is the recommended procedure to allow Joomla core to correctly update the #__user_keys table to its required structure while preserving necessary Admin Tools functionality? What data, if any, stored by Admin Tools in the current #__user_keys table is critical to retain?

We are trying to get our Joomla site fully updated and functional, including the core API features, and any guidance on resolving these interconnected issues would be greatly appreciated. We can provide full log files if needed.

Thank you for your time and assistance.

findMarcel

I think the problem is, that I have no 4.4.5-xxxx.sql file in my administrator\components\com_admin\sql\updates\mysql folder.

My latest DB-upgrade file is 4.4.4-2024-03-28.sql.

Is that normal?

If I download the joomla 4.4.13 upgrade package via below links, the SQL-files are only present until 4.4.4 version.

https://downloads.joomla.org/cms/joomla4/4-4-13/
https://downloads.joomla.org/cms/joomla4/4-4-13/Joomla_4-4-13-Stable-Update_Package.zip?format=zip

Very strange...

nicholas
Akeeba Staff
Manager

We're experiencing a persistent issue on a Joomla 4.4.13 site where the database schema seems to be stuck at version 4.4.4-2024-03-28, preventing Joomla core SQL updates from running correctly. We suspect a conflict involving Admin Tools and the #__user_keys table,

You do not actually have any problem.

The Database Version shown in the “Maintenance: Database” page is not the same thing as the software version. The interface even makes it explicit. The database schema version is when the database structure last changed; this is what is listed under Database version. The Joomla version is when the PHP files last changed; this is what is listed under Manifest Version. The database structure does NOT change with each software version.

The last Database Version for Joomla 4.4 at the time of this writing is 4.4.4-2024-03-28 even when the Joomla version (Manifest Version) is 4.4.12. You can confirm this by installing a new site using a fresh Joomla 4.4.12 package downloaded from download.joomla.org.

Also, to dispel any doubt, neither Admin Tools nor any other extension (core or third party) can affect Joomla Update from the moment the update ZIP file has been downloaded to the moment you are taken back to the Joomla backend. The entire update process takes place outside of Joomla, in its own standalone script. I know that for a fact because I wrote Joomla Update myself; it used to be part of Admin Tools.

 Suspected Cause: #__user_keys Table Conflict 

Admin Tools only reads and writes data to this table. It cannot change the structure of this table.

We NEVER change the structure of core Joomla table in our software. Changing datbase table structure, just like changing the content of core Joomla PHP files, is FORBIDDEN. It's called a “core hack” and only leads to trouble. I have been an outspoken advocate against core hacks ever since Joomla existed. I would never have our company release any software whatsoever which hacks core. I am not a hypocite, insane, or idiot.

Your problem is that the id column should have been AUTO_INCREMENT but it's currently not. This is something you did yourself. While you are at it, check if any other AUTO_INCREMENT columns have been squashed to non-incrementing columns. If you ever did a database export and import from XML files, yeah, that would definitely screw up your database. There's a reason I had to write Akeeba Backup (then-called JoomlaPack) back in '06 to transfer sites; it prevented many database transfer snafus like this.

ANyway. This table's history from its introduction in Joomla 3.2.0 to Joomla 4.4.12 is as follows:

  • 3.2.0 Table is introduced
  • 3.5.0 The series column is converted from VARCHAR(255) to a VARCHAR(191) due to the introduction of utf8mb4 support, and the restrictions in MySQL index size.
  • 3.5.1 The user_id is converted from VARCHAR(255) to a VARCHAR(150) due to the introduction of utf8mb4 support, and the restrictions in MySQL index size.
  • 3.8.4 The series_2 and series_3 columns are removed as they were unnecessary
  • 4.0.0 The invalid column is dropped as it's no longer used

Secondary Problem: Admin Tools Critical Error => Error fixed: by removing admin tools plugin folder and reinstalling latest .zip file

When you updated Admin Tools the contents of the plugins/system/admintools folder were not updated. This is a Joomla bug which has existed since Joomla 1.5.5, but it happens very rarely. It's not specific to our software; it can happen with any extension. The correct solution is install the update ZIP package twice in a row. Nobody knows why it happens, exactly because it happens so rarely that it's practically irreproducible. We know it exists, we know how to work around its effects, but it remains unsolved for the past 15 years.

Please note that the change of the namespace from Joomla\Plugin\System\AdminTools to Akeeba\Plugin\System\AdminTools took in the 7.4.0 Admin Tools release in September of 2023. Are you telling me that you had not updated Admin Tools in nearly two years?!

Nicholas K. Dionysopoulos

Lead Developer and Director

🇬🇷Greek: native 🇬🇧English: excellent 🇫🇷French: basic • 🕐 My time zone is Europe / Athens
Please keep in mind my timezone and cultural differences when reading my replies. Thank you!

findMarcel

Thank you very much Nicholas for your great support!

I highly appreciate it!

 

As it seems like, this is not a real problem and intended, the ticket can therefore be closed.
I understand that the DB-Structure warnings / information from the Joomla Maintenance: Database check about skipped DB-changes are not relevant / important because the DB-version can differ from the manifest version.

Some clarifications:

  • I regularly upgrade the plugin (every few weeks at least) - however, the DB-Version is stuck at 7.4.5.
  • The bug did only happen on my local XAMPP, in PROD the error did not occur. :)
  • Autoincrement was added later to the table (not in the create statement itself).
  • A small question: I am building an API based on the Joomla Core API (4.x+ Webservices and joomla access tokens) somewhat started in below link:
    https://docs.joomla.org/J4.x:Joomla_Core_APIs
    https://docs.joomla.org/J4.x:Adding_an_API_to_a_Joomla_Component/en 
    https://magazine.joomla.org/all-issues/march-2023/playing-with-the-joomla-api-part-1

    I also saw your insightful book about the com_api solution, which was probably already introduced before the J4 Core APIs / Webservices some time ago:
    https://www.dionysopoulos.me/book/com-api.html

    Would you consider the Joomla Core API the right approach for using APIs to external applications today or any other approach?

Thank you a lot for everything again and with you a good night!

Marcel

nicholas
Akeeba Staff
Manager

I regularly upgrade the plugin (every few weeks at least) - however, the DB-Version is stuck at 7.4.5.

The database and software versions are not the same. The database version for Admin Tools 7.7.0 is 7.4.5-20231214 because the last time we modified the structure of the database tables of the extension was ahead of version 7.4.5 back in December 2023.

TIP! You can look at the update SQL of any extension to see what is the latest database version. For Admin Tools that would be administrator/components/com_admintools/sql/updates/mysql. If you are looking inside the ZIP package, extract the package, then extract the com_admintools.zip you found in the package and look into the extracted folder backend/sql/updates/mysql. This applies to any Joomla extension. For Joomla itself, the update SQL files are in administrator/componetns/com_admin/sql/updates/mysql. This way you can verify the correct DB version is used by just looking at the files of the extension / Joomla distribution ZIP file. Simple, isn't it? :) I believe this is also covered in the Joomla developer's manual, but I can't vouch for it. I know it was part of the old developers' documentation, I am not sure what has been transferred to the new Joomla Manual site.

My comment about you not having updated in two years came as a response to the error message which was referencing the namespace Joomla\Plugin\System\AdminTools which was replaced in September 2023. Therefore, the code that threw this error was from between March 2021 (when that namespace was first used) to September 2023 (when that namespace stopped being used). It follows that you were updating from a version of Admin Tools that is anywhere between 22 months and 4 years old.

In other words, I did not look at versions; I based my reply on the fact that your error message includes a reference to a namespace that was only used for a short period of time, between March 2021 and September 2023.

The bug did only happen on my local XAMPP, in PROD the error did not occur. :)

I assume you mean the update issue in Joomla. It can happen anywhere. I've seen it on all sorts of local, testing, development, and production servers. If it was as easy as using a local server we'd have reproduced it and fixed it 15 years ago ;)

Autoincrement was added later to the table (not in the create statement itself).

Unfortunately, you are wrong. The AUTO_INCREMENT property has been there ever since this table was first created on October 10th, 2013.

I also saw your insightful book about the com_api solution, which was probably already introduced before the J4 Core APIs / Webservices some time ago:

I have explicitly stated that the book was written after Joomla 4 was released (in fact, a year after). It's based on my experience updating all of our software for Joomla 4. It tells you how to adapt your Joomla 3 component to work on Joomla 4 and later versions, as well as introduce you to the new features in Joomla 4. One of these features is Joomla's API application.

There is no such thing as "com_api", nor do I make any such claim. The URL slug for the book's chapter is short for "Chapter 2. Components. Section: API application".

If you read the entire section you will see that I take you by the hand and guide you through creating the api section of your component, and the webservices plugin you need to route API requests to your component.

For what it's worth, the Joomla API application was written mostly by George Wilson, and he had me implement software for it to make sure that it fits the needs of third party developers before Joomla 4 was released. I provided feedback for it, and contributed the user authentication scheme which is still in use (George only had a temporary authentication scheme using a raw username and password he knew was wrong and shouldn't be used, but had run out of time to implement something better, and I happened to already have the authentication solution ready as part of another project I was working on at the time). Fun stuff.

Would you consider the Joomla Core API the right approach for using APIs to external applications today or any other approach?

Yes, absolutely. In fact, it's the ONLY approach you should consider for this purpose!

Nicholas K. Dionysopoulos

Lead Developer and Director

🇬🇷Greek: native 🇬🇧English: excellent 🇫🇷French: basic • 🕐 My time zone is Europe / Athens
Please keep in mind my timezone and cultural differences when reading my replies. Thank you!

findMarcel

Hi Nicholas

 

Thank you again for your great recommendations, insights and clarifications - you are the best! :)

 

Resolved problems:

The version problem / misunderstanding has been resovled.

Regarding API & webservices:

I could create a component and plugin with the recommendations from your blog and all seems to work fine so far. :))

Webservices Auth problem:

There is only one problem with authentication.
Guest seem not to be able to get a auth token via webservices (which is probably a good thing).

Here is a discussion about it - do you think my idea is feasable or do you have other recommendations?
https://joomla.stackexchange.com/questions/33327/how-to-authenticate-a-user-with-the-official-joomla-4-rest-api

Here was someone asking the same:
https://groups.google.com/g/joomla-dev-general/c/PBzc6gfvR00

Your blog recommendations about auth:
https://www.dionysopoulos.me/book/com-api-access.html

 

BR,
Marcel

nicholas
Akeeba Staff
Manager

The authentication token is necessary to tell Joomla which user is accessing the API. It's the equivalent of a username and password.

If you want to make your API accessible to guest users, i.e. when nobody is logged in, what you are trying to implement is unauthenticated (public) access.

As I mentioned in the book, that's possible, and it's up to the webservices plugin. I also explicitly stated that this is how the media manager (com_media) does it. I also linked to https://www.dionysopoulos.me/book/com-api-plugin.html where I talk about it. Look at $publicGets. Set it to true to allow the GET request (and ONLY the GET request!) to work without authentication.

Also note that I explicitly state you will have to override the displayItem and displayList methods in the respective controller to make sure that you return data to unauthenticated users, and that this data is appropriately sanitized.

Also, when creating the route you will need to set ['public'=>true] in $defaults if you want your route to be accessible to guest users. The caveat is that only guest users will be able to access the route.

So, yes, what you want is possible but you need to make a few changes in both the plugin and the component to get there.

Finally, if you really want to authenticate users with their username and password, instead of a token, it is possible and Joomla does provide an API authentication plugin to do that. However, I would strongly advise AGAINST using it as it's insecure; it sends the username and password as a base64-encoded string which is as good as plain-text. It also doesn't (or at least shouldn't) work with user accounts that have MFA enabled. The API token is a much better solution, and something that is used throughout the industry; Joomla didn't invent it. Actually, since I wrote that code myself, I can tell you that it's 100% inspired by API best practices throughout the industry and a lot of thinking went behind it to make sure it's not going to be something that can easily be subverted even if you have a data breach; it requires both file and database data to work.

Nicholas K. Dionysopoulos

Lead Developer and Director

🇬🇷Greek: native 🇬🇧English: excellent 🇫🇷French: basic • 🕐 My time zone is Europe / Athens
Please keep in mind my timezone and cultural differences when reading my replies. Thank you!

findMarcel

Hi Nicholas,

Thanks again for your invaluable insights on public API access. I've been working on implementing a public POST endpoint for user login (/v1/mycomp/users/login) and registration, following your advice.

  • Registration (users.add) with ['public' => true] in the route is working well.
  • For the login endpoint (users.login), also marked ['public' => true]:
    • The Guest user can correctly access the endpoint (permission check passes).
    • Inside my model's authenticateAndGenerateToken($username, $password) method:
      • A direct UserHelper::verifyPassword($password, $user->password, $user->id) for the provided credentials succeeds.
      • However, the subsequent $app = Factory::getApplication(); $app->login(['username' => $username, 'password' => $password], ['silent' => true]); call fails, resulting in a "tokenfailure" log from Joomla's authentication system and a 401 response.
    • This occurs even with MFA disabled for the test user and after temporarily disabling various non-core authentication and MFA-related plugins. The "Authentication - Joomla" plugin is enabled.

Your book and post mention $publicGets for createCRUDRoutes (allowing public GETs) and the caveat that a route with ['public' => true] is "only guest users will be able to access the route."

My questions:
Is there an inherent issue or a specific approach required when a public POST route (like login) attempts to change the user state from Guest to an authenticated user via $app->login()? Could the "guests-only" nature of the public route conflict with the state change caused by a successful $app->login()?

You mentioned that we should only use GET endpoints for public access, however for registration and login we need to POST the information, right?

com_media uses $publicGets for read-only public access, which seems straightforward. My scenario involves a state change on a public POST.

Any clarification on how $app->login() should behave within a public API route, or if there's a recommended pattern for unauthenticated username/password login that results in a token, would be immensely helpful. I'm trying to avoid the less secure Basic Auth plugin if possible.

Thanks for your time and expertise!

Best regards,
Marcel

Support Information

Working hours: We are open Monday to Friday, 9am to 7pm Cyprus timezone (EET / EEST). Support is provided by the same developers writing the software, all of which live in Europe. You can still file tickets outside of our working hours, but we cannot respond to them until we're back at the office.

Support policy: We would like to kindly inform you that when using our support you have already agreed to the Support Policy which is part of our Terms of Service. Thank you for your understanding and for helping us help you!