Difference between revisions of "Zen Cart observer"
Karl Jones (Talk | contribs) |
Karl Jones (Talk | contribs) (→Example one) |
||
Line 6: | Line 6: | ||
* https://www.zen-cart.com/showthread.php?141092-Using-an-observer-to-require-login-when-accessing-a-certain-custom-page | * https://www.zen-cart.com/showthread.php?141092-Using-an-observer-to-require-login-when-accessing-a-certain-custom-page | ||
+ | |||
+ | I'm using a fairly plain 1.3.8a and wanted to offer my experience today. I hadn't read this thread at all and went about things slightly differently, though by the looks of things I could have used this navigationHistory object referred to. I'm using a modified approach to that seen on http://www.zen-cart.com/forum/showth...login+redirect, which uses the observer/notify feature (http://www.zen-cart.com/wiki/index.p...Observer_Class) and the fact that includes/modules/pages/login/header_php.php fires a NOTIFY_LOGIN_SUCCESS notification event on successful login. | ||
+ | |||
+ | My situation is that, on entry to a custom tpl_somethingorother_default.php page, I want to ensure the customer is logged on. If I redirect to logon, I want them to come back to the current page after logon. | ||
+ | |||
+ | This is not a global solution, but one designed to be used in a specific module, because it relies on a custom session variable login_redirect being set, though I'm sure it could be adapted. | ||
+ | |||
+ | 1/ Create file includes/classes/observers/login.redirector.php: | ||
+ | |||
+ | PHP Code: | ||
+ | <?php | ||
+ | # see http://www.zen-cart.com/forum/showthread.php?t=135312&highlight=login+redirect | ||
+ | class LoginRedirector extends base { | ||
+ | |||
+ | function LoginRedirector() { | ||
+ | global $zco_notifier; | ||
+ | |||
+ | $zco_notifier->attach($this, array('NOTIFY_LOGIN_SUCCESS')); | ||
+ | } | ||
+ | |||
+ | function update(&$class, $eventID) { | ||
+ | # If the login_redirect session variable was set, redirect to it. | ||
+ | if (isset($_SESSION['login_redirect'])) { | ||
+ | $destination = $_SESSION['login_redirect']; | ||
+ | unset($_SESSION['login_redirect']); | ||
+ | zen_redirect($destination); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | ?> | ||
+ | 2/ Create file includes/auto_loaders/config.loginRedirect.php (perhaps the numbers 10 and 90 could be improved, I don't care about their values much as they don't depend on the order of any other instantiation): | ||
+ | |||
+ | PHP Code: | ||
+ | <?php | ||
+ | $autoLoadConfig[10][] = array('autoType'=>'class', | ||
+ | 'loadFile'=>'observers/login.redirector.php'); | ||
+ | $autoLoadConfig[90][] = array('autoType'=>'classInstantiate', | ||
+ | 'className'=>'LoginRedirector', | ||
+ | 'objectName'=>'LoginRedirector'); | ||
+ | ?> | ||
+ | 3/ Then, in the module you want to redirect from (this is on entry to my Warranty form's header_php.php. In this flow of logic, I want to ensure the customer is logged in before proceeding): | ||
+ | |||
+ | PHP Code: | ||
+ | if (!(isset($_SESSION['customer_id']))) { | ||
+ | $_SESSION['login_redirect'] = zen_href_link ( | ||
+ | FILENAME_WARRANTY_FORM, | ||
+ | 'order_no=' . $_REQUEST['order_no'], 'SSL' ); | ||
+ | zen_redirect(zen_href_link ( FILENAME_LOGIN, '', 'SSL' )); | ||
+ | } | ||
+ | So as a visitor tries to go to my warranty form, the first time through the template's header_php.php, if the customer_id is not set in the session, it will set a session login_redirect variable recording where to redirect back to after login, and redirect to login. Once login is complete, the observer jumps in, notices the login_redirect session variable, and redirects back to my warranty form. | ||
+ | |||
+ | You could set $_SESSION['login_redirect'] to any URL you like, and redirect to login, and it will redirect to your URL on successful login. | ||
== Example two == | == Example two == |
Revision as of 11:54, 12 October 2015
A Zen Cart observer is an Observer design pattern in implemented in Zen Cart.
See also Zen Cart API.
Example one
I'm using a fairly plain 1.3.8a and wanted to offer my experience today. I hadn't read this thread at all and went about things slightly differently, though by the looks of things I could have used this navigationHistory object referred to. I'm using a modified approach to that seen on http://www.zen-cart.com/forum/showth...login+redirect, which uses the observer/notify feature (http://www.zen-cart.com/wiki/index.p...Observer_Class) and the fact that includes/modules/pages/login/header_php.php fires a NOTIFY_LOGIN_SUCCESS notification event on successful login.
My situation is that, on entry to a custom tpl_somethingorother_default.php page, I want to ensure the customer is logged on. If I redirect to logon, I want them to come back to the current page after logon.
This is not a global solution, but one designed to be used in a specific module, because it relies on a custom session variable login_redirect being set, though I'm sure it could be adapted.
1/ Create file includes/classes/observers/login.redirector.php:
PHP Code: <?php
class LoginRedirector extends base {
function LoginRedirector() { global $zco_notifier;
$zco_notifier->attach($this, array('NOTIFY_LOGIN_SUCCESS')); }
function update(&$class, $eventID) { # If the login_redirect session variable was set, redirect to it. if (isset($_SESSION['login_redirect'])) { $destination = $_SESSION['login_redirect']; unset($_SESSION['login_redirect']); zen_redirect($destination); } }
} ?> 2/ Create file includes/auto_loaders/config.loginRedirect.php (perhaps the numbers 10 and 90 could be improved, I don't care about their values much as they don't depend on the order of any other instantiation):
PHP Code: <?php $autoLoadConfig[10][] = array('autoType'=>'class',
'loadFile'=>'observers/login.redirector.php');
$autoLoadConfig[90][] = array('autoType'=>'classInstantiate',
'className'=>'LoginRedirector', 'objectName'=>'LoginRedirector');
?> 3/ Then, in the module you want to redirect from (this is on entry to my Warranty form's header_php.php. In this flow of logic, I want to ensure the customer is logged in before proceeding):
PHP Code:
if (!(isset($_SESSION['customer_id']))) { $_SESSION['login_redirect'] = zen_href_link ( FILENAME_WARRANTY_FORM, 'order_no=' . $_REQUEST['order_no'], 'SSL' ); zen_redirect(zen_href_link ( FILENAME_LOGIN, , 'SSL' )); }
So as a visitor tries to go to my warranty form, the first time through the template's header_php.php, if the customer_id is not set in the session, it will set a session login_redirect variable recording where to redirect back to after login, and redirect to login. Once login is complete, the observer jumps in, notices the login_redirect session variable, and redirects back to my warranty form.
You could set $_SESSION['login_redirect'] to any URL you like, and redirect to login, and it will redirect to your URL on successful login.
Example two
Observer/notifier "base" class:
QUESTION:
In the API tutorial it is explained that every class that want to make use of observer/notifier system has to extend the "base" class. However I cannot see how this can work. Maybe it is because I am a C++ guru and not a PHP. The problem as I see it is that we get different instances of the "base" class for every instance of observer or notifier class. Therefore the following observerclass will never get the notification from the shopping_cart class.
class myObserver extends base {
function myObserver() {
$this->attach($this, array('NOTIFIER_CART_ADD_CART_END'));
}
...
}
If the base class was static or was working on some global variables then it would be different. What have I misunderstood?
REPLY:
The documentation is buggy.
Your c'tor should instead say
$_SESSION['cart']->attach($this, array('NOTIFIER_CART_ADD_CART_END'));
for cart stuff. The cart object maintains a list of observers and calls them when the notify() method is called for the events they have registered for. Similarly, zco_notifier, etc.