Jump to content
landitus

Session messages (or flash messages) implementation

Recommended Posts

I'm doing a custom login/register in the front end, and flash messages are really useful to inform the user about the process of user registration. I was used to using Codeigniter with their flash message system. I've seen very few messages in the forum where $session->message is used but I haven't seen a full implementation. I've tried my own with some degree of success, but the flash messages persist in a different way that I've expected. It's like there is a "delay". Maybe I'm doing something wrong.

The header.inc has a standard notices loop:

<?php if($notices) :?>
     <?php foreach($notices as $notice) :?>
            <?php $class = $notice->className(); ?>
            <div class="notification <?= $class; ?>">
                <p><?= $notice->text ;?></p>
            </div>
     <?php endforeach ;?>
<?php endif ;?>

This is my register.php:

When submitting the form with errors, the first time no error message are displayed. The second time I submit it with errors, then the error message appears. This is what I describe as the "delay".

<?php

include("./helpers/form_helpers.php");

/**
 * Register template
 *
 */

$out = "";
$errors = "";

// create a new form field (also field wrapper)
$form = $modules->get("InputfieldForm");
$form->action = "./";
$form->method = "post";
$form->attr("id+name",'register-form');

// Name
// $field = $modules->get("InputfieldText");
// $field->label = "Name";
// $field->attr('id+name','name');
// $field->required = 1;
// $form->append($field); // append the field to the form

// Email
$field = $modules->get("InputfieldEmail");
$field->label = "E-Mail";
$field->attr('id+name','email');
$field->required = 1;
$form->append($field); // append the field

// Password
$field = $modules->get("InputfieldPassword");
$field->label = __("Contraseña");
$field->attr("id+name","password");
$field->required = 1;
$form->append($field);

// Submit
$submit = $modules->get("InputfieldSubmit");
$submit->attr("value",__('Crear cuenta'));
$submit->attr("id+name","submit");
$submit->attr("class","btn btn--primary");
$form->append($submit);

// Form submitted: process form
if($input->post->submit) {

    // user submitted the form, process it and check for errors
    $form->processInput($input->post);

    // here is a good point for extra/custom validation and manipulate fields
    if($sanitizer->email($form->get("email")->value) != '') {

        // Email should be unique
        if(!isUniqueUserEmail($form->get("email")->value)){
            $form->email->error(__("El e-mail ingresado ya se encuentra registrado"));
        }
    }

    if($form->getErrors()) {
       // the form is processed and populated but contains errors

       // Render Form
       $session->error(__('There are errors in the form'));
       $out .= $form->render();

    } else {

        // Sanitize inputs
        //$full_name = $sanitizer->text($input->post->name);
        $email = $sanitizer->email($input->post->email);
        $password = $input->post->password;

        // Generate username from email
        $username = $sanitizer->email($input->post->email);

        // Create New User
        $u = new User();
        $u->of(false);
        $u->name = $username;
        $u->pass = $password;
        $u->email = $email;
        $u->addRole("guest");
        $u->addRole("member");
        $u->save();
        $u->of(true);

        // Create hash

        // Email the user with confirmation e-mail

        // Redirect to login page and display success Message
        $session->message(__('User registration sucessfull'));
        $session->redirect('/login');

    }


} else {
    // Form not submitted: render out form without processing
    $out .= $form->render();
}

include("./partials/header.inc"); ?>

<div class="container container--narrow">
    <div class="page">
        <h1>Nuevo usuario</h1>
        <?= $out ;?>
    </div><!-- .page -->
</div><!-- .container -->


<?php include("./partials/footer.inc"); ?>

On a successful submission, the next page displays the correct message, but also the error message "There are errors in the form". It's like the error message get's carried over.

I appreciate any help to sort this out.

Share this post


Link to post
Share on other sites

What you need to understand is that in your example, you are storing the messages/errors in the session. This means you should be redirecting the user to display the message. Or to be precise, for them to be populated in $notices.

If you want to add a message to the current request, you should use the "regular" message/error -methods. You can do this through most PW objects. For an example, change your line 67 to

$form->error(__('There are errors in the form'));

As a bonus, when redirecting, PW automatically stores such notices in the session . This means you could do

$form->message(__('User registration sucessfull'));

...and the message wouldn't be lost. However in my opinion, it's cleaner to use $session->message() on line 98 because you are calling $session->redirect() on the next line.

  • Like 1

Share this post


Link to post
Share on other sites

Should $session->message persist? I have code that says otherwise, unless this is a bug?
I'm just refreshing current page to show message.

if($mail->send()) {
      $session->notices = false;
      $session->message('Thank you, your enquiry has been sent, we will be in touch shortly.', true);
      $session->redirect($page->url);
}

// render notices
$data = array('notices',$notices);
$partials['notices'] = $page->render('views/partials/_notices.php',$data);


Event when revisiting the page after further navigation, the message remains. Weird.

EDIT:

Session.php line 117, has remove method commented out: // $this->remove($type);
Enabling this solves the problem, just wondering why it would be commented out?

After rendering notices on the front end I have to call:

$session->removeNotices();
to force removal.
  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By theoretic
      Hi guys and ladies! And thanks for Processwire!
      It appears i've got an interesting issue concerning the template-settings-based PW redirects dealing with access control. Any PW template has some access control options i.e. "Login redirect URL or page ID to render". If this option is used for a page having a template with this option filled, a redirect will occur if user is not logged in and/or has insufficient access rights.
      I like to hook PW events. In one of my current projects i decided to write an addHookBefore('Session::redirect', ...) which should store the page we are being redirected from. With "regular" redirects like $session->redirect('/somewhere/') this hook works like a charm. But it was strange to see that it doesn't work with the template-settings-based redirect.
      I'm too dumb to dive deep inside PW and to examine the whole PW session mechanism. But it could be rather logical if ANY redirect ( no matter template-settings-based or using $session->redirect() ) could be hooked in the same manner.
      Okay okay i can forget about template-settings-based redirect and write my own. Just a couple of lines of code, and it works. But it's less elegant than hooking the template-settings-based redirects.
      So am i missing something? It this behavior a bug, or is it intended by PW team? Thanks in advance for any comment!
    • By fliwire
      Hi, after redirect to payment page processwire session lost because of samesite cookies changed default to "lax".

      https://web.dev/samesite-cookies-explained/

      tried to hook session::init but not works ?
      $wire->addHookBefore("Session::init", function (HookEvent $event) { ini_set('session.cookie_samesite', 'None'); session_set_cookie_params(['samesite' => 'None']); });

      set by htaccess works
       
      <ifmodule mod_headers.c> Header always edit Set-Cookie ^(.*)$ $1;SameSite=None;Secure </ifmodule>  
    • By Entil`zha
      Hi,
      For some reason when I try to read and clear messages or errors in template I'll get the messages but they won't clear and will show after next page load.
      I following code in my head.inc which is included in every template.
      $messages = $wire->messages('clear all'); foreach ($messages as $m) { echo '<div class="alert alert-success alert-dismissible" role="alert">'; echo '<p class="badge badge-pill badge-success">OK</p> ' . $m->text; echo '<button type="button" class="close" data-dismiss="alert" aria-label="Close">'; echo '<span aria-hidden="true">&times;</span>'; echo '</button>'; echo '</div>'; } I'll get all the messages but they don't get cleared.
      Only way to clear messages is to load page from admin area.
       
    • By derelektrischemoench
      Hi guys,
      I'm facing a somewhat strange issue here which I can't quite wrap my head around. 
      I have a PW site in development which runs on three machines simultaneously, one staging server which is accessible as a preview instance for my customer, my PC and my laptop. 
      I have three completely identical settings on each of the three machines (same apache version, same php version, same codebase, same database); however on my PC I am unable to log into the backend. I get no error message or anything, when I try to login; i just get redirected to the login  page. I have already enabled database driven sessions (I enabled them on my laptop, then I dumped the database and copied it to my pc); I have cleared the cache directory; I cleared the sessions in the database; I cleared my browser caches, I tried different browsers, all to no avail; I am unable to login when using my pc, the instances all have the same .htaccess.
      Is there something I'm missing here or does anyone have a clue as to what my issue here might be? I'm using processwire 3.0.123
      Thanks for any input, greetings
      derelektrischemoench
       
      //edit: I've noticed something interesting; despite the directories of my web folders being the same layout; when I open the admin page i get a 404 on the processwire/ resource in the networks panel of chrome; on my laptop I get a  200.... I guess this is where my problem is; but why?
       
       
    • By derelektrischemoench
      Hi guys,
      I'm facing a somewhat strange issue here which I can't quite wrap my head around. 
      I have a PW site in development which runs on three machines simultaneously, one staging server which is accessible as a preview instance for my customer, my PC and my laptop. 
      I have three completely identical settings on each of the three machines (same apache version, same php version, same codebase, same database); however on my PC I am unable to log into the backend. I get no error message or anything, when I try to login; i just get redirected to the login  page. I have already enabled database driven sessions (I enabled them on my laptop, then I dumped the database and copied it to my pc); I have cleared the cache directory; I cleared the sessions in the database; I cleared my browser caches, I tried different browsers, all to no avail; I am unable to login when using my pc, the instances all have the same .htaccess.
      Is there something I'm missing here or does anyone have a clue as to what my issue here might be? I'm using processwire 3.0.123
      Thanks for any input, greetings
      derelektrischemoench
       
       
×
×
  • Create New...