2

I have a Joomla 3.x module which calls the category name from the database and then shows this in the module position.

It does this with:

    $db = &JFactory::getDBO(); 
    $id = JRequest::getString('id'); 
    $view = JRequest::getString('view'); 

    if ($view == 'category') {
        $sql = "SELECT title FROM #__categories WHERE #__categories.id = $id";
    } else {
        $sql = "SELECT #__categories.title FROM #__content, #__categories WHERE #__content.catid = #__categories.id AND #__content.id = $id";
    }

    $db->setQuery($sql); 
    $category = $db->loadResult(); 
    echo '<h1>' . $category . '</h1>'; 

This works in Joomla 3, but in Joomla 4 I'm getting an error:

Attempted to load class "JRequest" from the global namespace.

What's the best way to get this working in Joomla 4?

1
  • I'd like to recommend that you not use the old-skool comma-JOIN syntax -- it is very easy for a developer to overlook this syntax. In Joomla4, it would be a good idea to consistently implement bind() calls with every query that uses variables for values. When not joining tables, you don't need to bloat your SQL adding the table name before every column.
    – mickmackusa
    Mar 8 at 22:15

3 Answers 3

3

JRequest was deprecated in Joomla 2.5 (I think), so you can now use JInput, like so:

use Joomla\CMS\Factory;

$db = Factory::getDbo();
$input = Factory::getApplication()->input;
$id = $input->get('id');
$view = input->get('view');

You'll definitely want to update your database query, using more modern methods: https://docs.joomla.org/Selecting_data_using_JDatabase

If I'm not mistaken, you're currently prone to SQL injections.

3

Lodder's answer is fully valid, however he did not want to waste time to reformulate the query part of this old script in the question. As a morning drill during my coffee time I corrected that part too:

use Joomla\CMS\Factory; 

// get the Input object if $this->input is not avail
$app = Factory::getApplication();
$input = $app->input; 

// $db = Factory::getDbo();
$db = Factory::getContainer()->get('DatabaseDriver');

$id = $input->get('id', '', 'string');
$view = $input->get('view', '', 'string');    
    
$query = $db->getQuery(true);

if ($view == 'category') {

    $query->select('title')
        ->from($db->quoteName('#__categories'))
        ->where($db->quoteName('id') . ' = :id')
        ->bind(':id', $id);

} else {
    
    $query->select('b.title')
        ->from($db->quoteName('#__content', 'a'))
        ->innerJoin($db->quoteName('#__categories', 'b') . ' ON a.catid = b.id')
        ->where($db->quoteName('a.id') . ' = :id')
        ->bind(':id', $id);
}

$db->setQuery($query);
$category = $db->loadResult(); 
echo '<h1>' . $category . '</h1>';
1

$input = $app->input; is deprecated too. You should use in Joomla 4 $input = $app->getInput(); instead.

Also you can load database form DI container by this code:

use Joomla\Database\DatabaseInterface;
$db = Factory::getContainer()->get(DatabaseInterface::class);
7
  • $app->input is going to be deprecated in Joomla 5, same with the database calls. The question is about refactoring an old script for Joomla4. Your post is not answering the original question but more like a comment on other answers.
    – Zollie
    Mar 11 at 11:18
  • Joomla 5 will come in october 2023. Do you want to update your code again six months later? Why, if you can write immediately using new methods. Mar 11 at 21:36
  • You can of course if you prepare your extension for Jooma 5 already. At Joomla 6 we will get to the Facade system most probably. I am not convinced that they will keep calling the database via containers for a long time in J.5 though…
    – Zollie
    Mar 12 at 5:50
  • We will arrive back to getDb()
    – Zollie
    Mar 12 at 5:57
  • 1
    @Zollie is it the official position of production department about Facade? Where we can get more information? Mar 13 at 7:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.