I did create a Joomla 4 plugin. The plugin should allow me to publish the value of a specific cell of a specific row identified by a specific colum within a specific dbase table from within the meta description of an article or menu item.
This is the format: {dbv table_prices|item_id|123|price}
Where
- dbv = the plugin name
- table_prices = table name
- item_id = the column to use
- 123 = the id of the row whitin column 'item_id'
- price = the column in the row to get the value from
So in the article the meta description could look like:
Best travel book this week for only € {dbv table_prices|item_id|123|price}
where the plugin should ensure that the meta description after rendering in the front-end should look like this:
Best travel book this week for only € 50
assuming the value in the cell is 50.00
The plugin installs, it is enabled but the plugin snippets stays visible in the front-end. What could possible be wrong in the code?
class plgSystemDbv extends CMSPlugin
{
public function onAfterDispatch()
{
$app = Factory::getApplication();
$menu = $app->getMenu();
$activeItem = $menu->getActive();
if ($activeItem && ($activeItem->type === 'article' || $activeItem->type === 'url')) {
$db = $this->getDbo();
$document = $app->getDocument();
$description = $document->getMetaData('description');
$matches = array();
// Find all occurrences of {dbv ...} tags in the meta description
preg_match_all('/{dbv\s+([^}]+)}/', $description, $matches);
foreach ($matches[1] as $match) {
// Parse the parameters from the {dbv} tag
$params = explode('|', $match);
$table = trim($params[0]);
$column = trim($params[1]);
$row = trim($params[2]);
$cell = trim($params[3]);
// Get the ID value based on the specified column and row
$id = $this->getValueFromColumn($activeItem, $column);
if ($id !== null) {
// Retrieve the value from the specified table, column, row, and cell
$value = $this->getQueryValue($db, $table, $column, $id, $cell);
if (!empty($value)) {
// Replace the {dbv} tag with the retrieved value
$description = str_replace('{dbv ' . $match . '}', $value, $description);
}
}
}
// Update the meta description with the modified content
$document->setMetaData('description', $description);
}
}
private function getValueFromColumn($item, $column)
{
$columns = explode('|', $column);
$currentItem = $item;
foreach ($columns as $column) {
if (isset($currentItem->$column)) {
$currentItem = $currentItem->$column;
} else {
return null;
}
}
return $currentItem;
}
private function getQueryValue($db, $table, $idColumn, $idValue, $valueColumn)
{
$query = $db->getQuery(true)
->select($db->quoteName($valueColumn))
->from($db->quoteName($table))
->where($db->quoteName($idColumn) . ' = ' . $db->quote($idValue));
$db->setQuery($query);
return $db->loadResult();
}
}
`
I tried to use the oncontentprepare event since I am using that in a similar content plugin but that doesn't help either. I had a similar plugin for Joomla 3 that worked fine, though different code and J3 is quite different.