Contao news

Read the official Contao announcements.

Accessing the active record in the DCA

by Leo Feyer – From practice

Access to the active record in the DCA is another powerful development feature in TYPOlight 2.8. So far, the Data Container Object provides only the ID of the active record, which often required additional database queries when using callback functions.

Using a field callback

The event list and the event menu module both use a drop-down menu to choose the event list format. The options, however, vary depending on the module type. The field callback looks like this:

public function getFormats(DataContainer $dc)
{
$objModule = $this->Database->prepare("SELECT type FROM tl_module WHERE id=?")
->limit(1)
->execute($dc->id);

if ($objModule->type == 'eventmenu')
{
// Return option list A
}
else
{
// Return option list B
}
}

The additional database query was necessary, because you could not access the modul type via the Data Container Object. From version 2.8.RC2, however, you can read the active record and omit the query:

public function getFormats(DataContainer $dc)
{
if ($dc->activeRecord->type == 'eventmenu')
{
// Return option list A
}
else
{
// Return option list B
}
}

Using an onsubmit_callback

If a new member is added, the creation date is stored in the database by means of an onsubmit_callback. Since the Data Container used to provide only the ID of the record, the callback looks like this:

public function storeDateAdded(DataContainer $dc)
{
$objUser = $this->Database->prepare("SELECT * FROM tl_member WHERE id=?")
->limit(1)
->execute($dc->id);

if ($objUser->numRows < 1 || $objUser->dateAdded > 0)
{
return;
}

// Fallback solution for existing accounts
if (objUser->lastLogin > 0)
{
$time = $objUser->lastLogin;
}
else
{
$time = time();
}

$this->Database->prepare("UPDATE tl_member SET dateAdded=? WHERE id=?")
->execute($time, $objUser->id);
}

With the new active record access, you do not need the additional database query anymore:

public function storeDateAdded(DataContainer $dc)
{
if ($dc->activeRecord->dateAdded > 0)
{
return;
}

// Fallback solution for existing accounts
if ($dc->activeRecord->lastLogin > 0)
{
$time = $dc->activeRecord->lastLogin;
}
else
{
$time = time();
}

$this->Database->prepare("UPDATE tl_member SET dateAdded=? WHERE id=?")
->execute($time, $dc->id);
}

Being able to access the active record allows you to write callback functions that do not require additional database queries. And although this might not be applicable in all cases, it should reduce the overall number of queries and thus improve the performance of TYPOlight.

Show all news

Comments

Comment by Angelo Galleja |

In order to make the code compatible with previous versions (while developing for 2.8 version) we can do something like this:

Code:

if (!is_object($dc->activeRecord)) {
$dc->activeRecord = $this->Database("…");
}

Comment by Kamil Kuzminski |

If ondelete_callback you still need to run query manually, since $dc->activeRecord is null.

Comment by Leo Feyer |

That is correct, because there is no active record if you delete an element. Only if you edit a (single) element.

Add a comment

Please calculate 5 plus 6.