Zen Cart Logo
Forums / Zen Cart Code Suggestions / Request for new notifier in login process

Request for new notifier in login process

Views: 72

Results 1 to 9 of 9
9 Jun 2018, 1:50 PM
#1
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Request for new notifier in login process

It would be useful to implement a new notifier in includes/modules/pages/login/header_php.php after email, banned, and password validation for additional customer login checks that interrupt the login process to display messages to the customer. The notifier, if implemented, avoids custom code in the core file.

In my case, certain customers are "members" who get certain benefits, including discounts, free downloads, and potentially access to special product categories or access to other stores with the same login credentials. But membership may lapse and I want to display a message via $messageStack during login, stating membership has lapsed (if true), but they can continue without the benefits by clicking login. Other notifiers in the header are not appropriate because information is not yet available, bring up inappropriate messages if login is not authorized, or won't display messages because of redirects.

Another reason for a new notifier (for us) is to provide a means to display the "Privacy Notice must be accepted" message to only customers in the EU who have not already checked the accept box in the login form.

Changes to the header must be made to implement a new notifier to avoid conflict with the 3rd party logon notifier. In addition, movement of the check_country_query from the login success path to before the new notifier would be nice so the observer can use entry_country_id. This latter change is desirable, but not necessary, as the extra query could be run in the observer.

Suggested code follows, picking up at the 3rd party login notifier (changes in red):

      $zco_notifier->notify('NOTIFY_PROCESS_3RD_PARTY_LOGINS', $email_address, $password, $loginAuthorized);
      if (!$loginAuthorized) {
        $error = true;
        $messageStack->add('login', TEXT_LOGIN_ERROR);
      }

      // BOF -- change to move query before notifier so observer has access to entry_country_id
      $check_country_query = "SELECT entry_country_id, entry_zone_id
                              FROM " . TABLE_ADDRESS_BOOK . "
                              WHERE customers_id = :customersID
                              AND address_book_id = :addressBookID";

      $check_country_query = $db->bindVars($check_country_query, ':customersID', $check_customer->fields['customers_id'], 'integer');
      $check_country_query = $db->bindVars($check_country_query, ':addressBookID',
      $check_customer->fields['customers_default_address_id'], 'integer');
      $check_country = $db->Execute($check_country_query);
      // EOF -- change to move query before notifier so observer has access to entry_country_id

      // BOF -- change to add notifier for additional login checks
      $zco_notifier->notify('NOTIFY_PROCESS_ADDITIONAL_LOGIN_CHECKS', $error, $loginAuthorized);
      
      if (!$loginAuthorized) {
        $error = true;
      // EOF -- change to add notifier for additional login checks

      } else {

The code continues down the login success path. Passing $error to the observer allows the observer code to be bypassed if there are problems with the email address, customer is banned or a problem with the password. The observer sets $loginAuthorized to false and sets up $message Stack as needed.

9 Jun 2018, 7:19 PM
#2
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Request for new notifier in login process

Forgive me, but it looks to me like the issue is that the desired customized observer code simply needs to load after any other third party notifier, which means it just needs to have a load point that is after any other such third party module.

If it is that this code isn't supposed to trigger the $messageStack->add('login', TEXT_LOGIN_ERROR);
Then that could be addressed later in either the success or failure notifiers by removing that particular message.

Otherwise, could see listening to either or both the success/failure notifiers and if in the success cycle the user really isn't to have been logged in to clear the logged in related aspects, or if in the failure to actually have logged in to then reproduce the login part of the code.

Otherwise, could see that instead of an additional notifier that the message within the not authorized to login portion to be adjustable by the notifier instead of always hard-coded to a define.

Basically, I don't see from the description why anything additional is needed when it seems that the desired operation can be accomplished with what exists. If I'm wrong please explain where I've gone wrong or what operation(s) can't be accomplished with what is there...

11 Jun 2018, 4:38 PM
#3
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Request for new notifier in login process

Thanks again for helping mc12345678, but it seems to me that trying to get the needed logic in login success or login failure observers is overly complex. And any solution there would stretch my coding capabilities. For example, how would you undo the recreate session, and when and why would that be necessary? How would you keep the login page displayed in the login success path? Would a direct includes to the login template in a login success path, keep the login page displayed with the desired messageStack message displayed? And if the logic is in the login failure path, how would I undo the wrong email/password message.

Don’t get me wrong, I’d love to try to implement the logic in the success or failure path. I just don’t have the needed knowledge on how to do it. I need some time to think about how to do what I want in the failure path. A hint on how to delete a message in the stack would be very helpful.

11 Jun 2018, 7:22 PM
#4
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Request for new notifier in login process

In words, can you describe the flow that you are seeking? Including when/whether the user should be actually logged into the ZC platform, how your code is to potentially interact/negate any other 3rd party login process (out-of-the-box), what you want done with any existing cart contents (if processing the ZC login is allowed), and where you want a user to go after successfully logging in?

With regards to a "failure" condition, please describe what constitutes failure for this new to be added handling as it relates to reaching the "end" of processing and also at each of the other failure trigger points if they apply. Consider addressing similar items as above related to success.

And lastly (for this post), the messagestack is a variable that has class actions and data associated with it. While I don't want to leave you with "read the code", I'd like to start off there. Take a look at the process of adding a message to the message stack as provided in: includes/classes/message_stack.php. To remove the last message associated with a given "group" ('login'), one would unset the last message of the array or pop it off. I've looked at what is needed, but some of the above information would help to hone in on this customised solution.

11 Jun 2018, 7:46 PM
#5
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Request for new notifier in login process

mc12345678:

To remove the last message associated with a given "group" ('login'), one would unset the last message of the array or pop it off. I've looked at what is needed, but some of the above information would help to hone in on this customised solution.

Or use the reset method to clear all messages from the stack.```
function updateNotifyLoginFailure(&$class, $eventID, $paramsArray = array()) {
$GLOBALS['messageStack']->reset();
} // end of function update


Starting to get the hang of this stuff...scary!:smile:
11 Jun 2018, 8:08 PM
#6
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Request for new notifier in login process

Dave224:

Or use the reset method to clear all messages from the stack.```
function updateNotifyLoginFailure(&$class, $eventID, $paramsArray = array()) {
$GLOBALS['messageStack']->reset();
} // end of function update

> 
> Starting to get the hang of this stuff...scary!:smile:
Quite true, just remember not to use a bazooka to get a fly. :) 

Oh, as to clearing the login session variables, if so needed/desired, if you noticed all the $_SESSION[] = lines, each is part of identifying that the customer has logged in and carries information related to the specific customer. So, at the heart of things, if those session variables were unset after being set, then the customer would be considered as not logged in at least to the ZC side of the software. 

Then some things from memory at looking through the code, to eliminate the notice of items being "added" to the cart from a previous login, basically if the before and after variables are the same then the default notification would not be made. How could that happen? By "pre-loading" the old cart to be the current cart within the success notifier operations. Thus, old and new would end up being the same and that entire set of code would be bypassed.

With the same thing in mind, you can redirect success to a different destination than the default page by setting the $_SESSION['navigation']->snapshot to go to the place desired.

Overall and to be able to handle any/all of the bouncing around, remember that $_SESSION variables are sustained from page to page, declared/redeclared $_POST variables will only remain if the securityToken accompanies the data, $this-> related data will not be sustained unless $this is a $_SESSION variable that is to remain from page to page, etc... depending on all of the operations/actions expected, it may be necessary to set a variable to support revisiting a page and to have certain actions take place based on the related data... 

All in all, congrats on catching on and digging in. :clap:
11 Jun 2018, 8:10 PM
#7
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Request for new notifier in login process

Oh, and forgot to offer, could also capture the messagestack before a message is added and then after that message is added to be removed could then set/reset the messagestack back to what it was before... this way don't have to necessarily work the message(s) back off, but just leave them as they were and carry on from that point...

12 Jun 2018, 1:41 PM
#8
dave224 avatar

dave224

Zen Follower

Join Date:
Jun 2012
Posts:
481
Plugin Contributions:
0

Re: Request for new notifier in login process

Got it working using an observer tied to the 3rd party login notifier and an observer tied to the login failure notifier. I withdraw my request for a new notifier. Thank you mc12345678 for all your help.

However I could not pass a variable from the first observer to the next observer using the technique you provided in an earlier post in the Code Collaboration forum, quoted below. I had to save the variable in $_SESSION.

If there is something to be captured/held until reaching the next notifier, then store that value in a variable associated with the observer class: ie.
Code:

$this->loginAuthorized = $loginAuthorized;

Then when the next observer (assume the 'NOTIFY_LOGIN_SUCCESS') is reached, it can be retrieved and used from the same variable:
Code:

function updateNotifyLoginSuccess(&$class, $notifier) {
$loginAuthorized = $this->loginAuthorized;
// do other things that should be done when login is still successful
}

This is the code I tried in the 3rd party login notifier observer:

$test_var = true;
$this->test_var = $test_var;

and in the login failure notifier observer:

$test_var = $this->test_var;
exit("test_var: " . $test_var);  

Output was "test_var: "

I also tried declaring $test_var as a public property in the 3rd party login notifier observer under the class statement, but that didn't work either.

12 Jun 2018, 1:45 PM
#9
mc12345678 avatar

mc12345678

Totally Zenned

Join Date:
Jul 2012
Posts:
16,908
Plugin Contributions:
2

Re: Request for new notifier in login process

Dave224:

Got it working using an observer tied to the 3rd party login notifier and an observer tied to the login failure notifier. I withdraw my request for a new notifier. Thank you mc12345678 for all your help.

However I could not pass a variable from the first observer to the next observer using the technique you provided in an earlier post in the Code Collaboration forum, quoted below. I had to save the variable in $_SESSION.

This is the code I tried in the 3rd party login notifier observer:

$test_var = true;
$this->test_var = $test_var;

> 
> and in the login failure notifier observer:
> ```
$test_var = $this->test_var;
exit("test_var: " . $test_var);  

Output was "test_var: "

I also tried declaring $test_var as a public property in the 3rd party login notifier observer under the class statement, but that didn't work either.

Yeah, well, the output test is where the issue resides: a "better" test of proof would be:

 exit("test_var: " . ($test_var ? 'true' : 'false')); 

Because you're trying to "see" the boolean value true rather than the string 'true'.

Or, change the original assignment from true to 'true'. There are other ways to output such useful information about the variable(s) and their value(s). Look into the php function print_r for example.

That said and recalling the code, because a redirect occurs, any internal variable gets reset unless pre-action has been taken to sustain the class' variable. (also discussed in that thread) and that therefore, the session variable would have been necessary because of the redirect.