?
avatar fbally
fbally
4 Jan 2016

Categories can be created programmatically

e.g. from: http://stackoverflow.com/questions/15003979/how-to-add-categories-in-joomla-2-5

Here the code:

$table = JTable::getInstance('category');

$data = array();
$title = 'Some title';
$parent_id = 1; // or any other category id
$extension = 'com_example.some_extension';

// name the category
$data['title'] = $title;
// set the parent category for the new category
$data['parent_id'] = $parent_id;
// set what extension the category is for
$data['extension'] = $extension;
// Set the category to be published by default
$data['published'] = 1;

// setLocation uses the parent_id and updates the nesting columns correctly
$table->setLocation($data['parent_id'], 'last-child');
// push our data into the table object
$table->bind($data);
// some data checks including setting the alias based on the name
if ($table->check()) {
    // and store it!
    $table->store(true); // fails; $table->store(false) does not fail.
    // Success
} else {
    // Error
}

If done so:

  • the call $table->store(true) fails: some fields are missing in the mysql #__assets table definition
  • the call $table->store(false) does not fail because the missing fields are all null

Comment

While storing aJTableCategory class, the store method of superclass JTable handles the asset entries and
creates an $asset by calling in method JTable::store line 822)

$asset = self::getInstance('Asset', 'JTable', array('dbo' => $this->getDbo()));

as a subclass of JTableNested which contains a field alias (and others).
When the asset is stored:

if (!$asset->check() || !$asset->store($updateNulls))
{
   $this->setError($asset->getError());
   return false;
}

it passes on the $updateNulls from its caller.
If this is set to true, $this->_db->updateObject fails later because the mysql #__assets table has no field alias

Workaround

Do not call $table->store(true); (with $updateNulls=true), but $table->store(); (default with $updateNulls=false)
Another possibility would to always set $updateNulls=false to the $asset->store() call (JTable line 855).

System information (as much as possible)

PHP Built On Windows NT NB01550 6.1 build 7601 (Windows 7 Service Pack 1) i586
Database Version 5.6.21
Database Collation utf8_general_ci
PHP Version 5.6.3
Web Server Apache/2.4.10 (Win32) OpenSSL/1.0.1i PHP/5.6.3
WebServer to PHP Interface apache2handler
Joomla! Version Joomla! 3.4.8 Stable [ Ember ] 24-December-2015 19:30 GMT
Joomla! Platform Version Joomla Platform 13.1.0 Stable [ Curiosity ] 24-Apr-2013 00:00 GMT
User Agent Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36

Additional comments

It took me a while to track this down and other users might have the same mishap.
As this is a non-correspondance between the JTableNested object's fields
and the mysql table #__assets definition, it could (should ?) be considered a bug and be fixed.

avatar fbally fbally - open - 4 Jan 2016
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 29 Jan 2017

is this an Issue on 3.7 too?

avatar joomla-cms-bot joomla-cms-bot - change - 29 Jan 2017
The description was changed
avatar joomla-cms-bot joomla-cms-bot - edited - 29 Jan 2017
avatar franz-wohlkoenig franz-wohlkoenig - change - 9 May 2017
Status New Information Required
avatar franz-wohlkoenig
franz-wohlkoenig - comment - 27 May 2017

This has been closed due to lack of response to the requests above – it can always be reopened in the future if it is updated.

avatar franz-wohlkoenig franz-wohlkoenig - change - 27 May 2017
Status Information Required Closed - No Reply
Closed_Date 0000-00-00 00:00:00 2017-05-27 09:27:11
Closed_By franz-wohlkoenig
avatar joomla-cms-bot joomla-cms-bot - change - 27 May 2017
Status Closed - No Reply Closed
Closed_By franz-wohlkoenig joomla-cms-bot
avatar joomla-cms-bot joomla-cms-bot - close - 27 May 2017
avatar joomla-cms-bot
joomla-cms-bot - comment - 27 May 2017
avatar ulvesked
ulvesked - comment - 31 Mar 2020

This is still an issue in version 3.9.16. Trying to call store($updateNulls = true) on a JTable with an asset_id throws an error.
Additionally there is no error handling in this part of JTableAsset::store (not checking the result of updateObject or insertObject) so it will never unlock tables which leads to unexpected database errors on subsequent SELECT:s.

The workaround suggested by @fbally should work but I am unsure whether updateNulls = true makes sense in some edge cases. In that case changes are required to update only fields that actually exists in the database.

EDIT: The error on subsequent selects are similar to this

"Table '#__foo' was not locked with LOCK TABLES"

This is because the query fails and the #__assets table is not unlocked

Add a Comment

Login with GitHub to post a comment