Today I had a major outage in an OXID-based shop system. The reason is unknown; it did resolve “itself” as quickly as it appeared, leaving behind an almost 3 hour downtime of the system. I assume that it’s a combination of their odd caching, and during debugging what went wrong, I took some notes which I eventually wrote down in this blog entry.
OXID, why do you disable modules without any visual indication on the modules list?
OXID shows that modules are enabled, but some aren’t. Nothing in the error logs. No information on the GUI. After an hour of digging into the code, I found out that there’s a configuration entry in the OXCONFIG table (of course, crypted see below) which holds a serialized PHP array of disabled modules (“adisabledmodules”). I do not know at this point where this array is filled, but if it is, modules are silently ignored – and the worst thing: They are shown as if they are enabled.
OXID, why don’t you give any hints why a module can’t be enabled?
If OXID fails to enable a module, it does so silently. At least, this time you actually see that the module is disabled again, but you get no clue why.
OXID, why you store your config encrypted in the database?
OXID uses DECODE() and ENCODE() with a public known key to store data in the OXCONFIG table. This is next to useless and only makes maintenance harder. The key is actually the same for each installation. Of course, one could change the key, but this isn’t documented. Additionally, some contents of the OXCONFIG table are stored as temporary, unencrypted data in the tmp folder anyways.
OXID, why do you use a custom class extension system?
OXID uses a custom class extension system. Probably to emulate some kind of multiple inheritance. In theory, this doesn’t sound too bad, but in practice, this gives headaches, because it is implemented poorly.
Class names are mangled to lower case in some places, but not in others, causing all sorts of problems, combined with too much or simply wrong caching mechanisms. One needs to add their class extensions into a file called “metadata.php”, which looks like this:
$aModule = array(
'id' => 'test',
'title' => 'Test',
'thumbnail' => '',
'version' => '1.0',
'author' => 'Felicitus',
'extend' => array(
'thankyou' => 'test/core/TestClass'
Don’t ever change the case of _any_ class name. Here’s where the inconsistency begins: The actual PHP class name is “Thankyou”. Most modules so far use “thankyou” as class identifier for the “extend” portion of the array. If you’d use “Thankyou” as identifier, you’d mess up the whole system, resulting in “method not found” errors. And if you did that once, it gets cached in the system, and you have no chance to revert this unless you manually delete the information from the OXCONFIG table.
When I first started out with OXID, it didn’t seem too bad as a shop system: They got unit tests and a wide range of modules. Some of them are available as purchase-only variants, which is okay.
However, the quality of the whole OXID infrastructure is a big problem. It uses smarty templates all over the place, even in their admin backend. Modules assume that they are the only one who extend a template, which is often not the case (example: List headers). There’s no documentation on where you should extend functionality. There’s no overall picture of how the business logic works. You can even purchase two modules, which change the business logic.
The lack of technical documentation is a big no-go. Did you knew that database properties are mapped to an object’s tablename__fieldname property? If you want to retrieve an order’s order date, you need to use:
This is neither documented within the oxBase class nor on their OXIDForge Website. If you decide to step into OXID development, be aware that you’ll be on your own – forums aren’t too much help, and expect to read lots of (odd), undocumented code.