0

I try to add the possibility to my component to unlock content within the component item view.

If you watch the item view page, you see a description and an image and a little button. If you click the button, you reload the page and instead of the button you see the download url.

Now I wonder how to do this unlock button:

I have a simple form + submitbutton + hidden inputfield which reloads the page with an url-parameter. But is there another method which works without url-parameter? I would like to have this parameter invisible...

    <form>
        <input type="hidden" id="unlock" name="unlock">
        <button type="submit">Send</button>
    </form>

Thanks for letting me know ^^

2
  • How is the reload performed? It should be done in the controller, not in the view. The view should never set session variables.
    – Sharky
    Commented Feb 14, 2021 at 14:59
  • I just added a simple form to the view (see above, I added it). How should I do this from the controller?
    – Lord Razen
    Commented Feb 15, 2021 at 7:46

1 Answer 1

0

Session variables should be set and redirects performed only by the controller. I assume you already have some controllers in your components. Add the task to an existing one or create a new one, whichever is more appropriate for your component.

The form:

use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Router\Route;
use Joomla\CMS\Uri\Uri;

?>
<form method="post" action="<?php echo Route::_('index.php', false); ?>">

    <?php // Indicates the component to use ?>
    <input type="hidden" name="option" value="com_example">
    
    <?php // The controller and the method to execute ?>
    <input type="hidden" name="task" value="download.unlock">
    
    <?php // Set the redirect URL ?>
    <input type="hidden" name="return" value="<?php echo base64_encode(Uri::getInstance()); ?>">
    
    <?php // Pass the download ID, assuming there are multiple downloads and each needs to be unlocked separately ?>
    <input type="hidden" name="id" value="<?php echo $id; ?>">
    
    <?php // Renders CSRF token ?>
    <?php echo HTMLHelper::_('form.token'); ?>
    
    <button type="submit">Unlock</button>
</form>

The controller task:

public function unlock()
{
    // Check CSRF token.
    $this->checkToken();

    // Get the application.
    $app = Factory::getApplication();

    // Check that redirect URL is valid. Otherwise set it to index.php.
    $return = $this->input->post->get('return', '', 'BASE64');

    if (is_string($return))
    {
        $return = base64_decode($return);

        if (!Uri::isInternal($return))
        {
            $return = Route::_('index.php', false);
        }
    }
    else
    {
        $return = Route::_('index.php', false);
    }

    // Get the download ID.
    $id = $this->input->post->get('id', null, 'INT');

    // Check that download ID is a valid integer.
    if (!is_integer($id))
    {
        // Invalid ID provided, redirect back.
        $this->setRedirect($return, $app->getLanguage()->_('COM_EXAMPLE_DOWNLOAD_UNLOCK_INVALID_ID'));

        return;
    }

    // Set the session variable. Session key be anything, but make sure it's unique.
    $app->setUserState('com_example.download.unlock.' . $id, true);

    // Redirect back to download page.
    $this->setRedirect($return);
}
1
  • This was extremly helpful! Could solve my problem so far, gonna make a new post if some other probleems appear. Thanks a lot!
    – Lord Razen
    Commented Feb 19, 2021 at 18:06

Your Answer

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

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