Page 1 of 2 12 LastLast
Results 1 to 10 of 13
  1. #1
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default $messageStack->add(...) in observer won't work

    I'm writing an observer and need to display an error message under certain conditions. I'm getting a fatal error "Call to a member function add() on null in /includes/classes/observers/class.login_checks.php on line xx". The notifier for this observer is in includes/modules/pages/login/header_php.php (NOTIFY_PROCESS_3RD_PARTY_LOGINS). The logic works perfectly in zc 1.5.1 when the same logic is back in the header_php.php file. The parameters for the add function are not nulls (checked with var_dump). Since zc 1.5.5 has the notifier, I'm trying to move my changes out of this core file and use the observer instead. Code snippet follows:
    Code:
    // notify customer
    $error = true;
    $messageStack->add('login', LOGIN_VALIDATION_ERROR, 'error');
    What does the error mean and how can I fix it?

    zc v155f, PHP 5.6

  2. #2
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default Re: $messageStack->add(...) in observer won't work

    Sorry everyone, problem solved. I forgot to pass $messageStack to the observer and back to the header. Works great now.

  3. #3
    Join Date
    Jul 2012
    Posts
    16,734
    Plugin Contributions
    17

    Default Re: $messageStack->add(...) in observer won't work

    Quote Originally Posted by Dave224 View Post
    Sorry everyone, problem solved. I forgot to pass $messageStack to the observer and back to the header. Works great now.
    Can you be more specific about your method of resolving this? From the description I think you did more than was necessary. If what I thought was done, it seems that to provide similar messages and use other information in the future may require far more editing than what is minimally necessary.

    I could have also misread the description of how it was resolved.
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  4. #4
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default Re: $messageStack->add(...) in observer won't work

    Quote Originally Posted by mc12345678 View Post
    Can you be more specific about your method of resolving this? From the description I think you did more than was necessary. If what I thought was done, it seems that to provide similar messages and use other information in the future may require far more editing than what is minimally necessary.

    I could have also misread the description of how it was resolved.
    Thank you for your interest! My solution was to include $messageStack in the notifier call along with other needed data (shown in red):
    Code:
    $zco_notifier->notify('NOTIFY_PROCESS_3RD_PARTY_LOGINS', $email_address, $password, $loginAuthorized,
     $check_customer->fields['customers_member_number'], $check_customer->fields['customers_id'], $messageStack);
    and in the observer update function:
    Code:
    function update(&$class, $eventID, $paramsArray = array(), &$rwParm2, &$loginAuthorized,
     &$customers_member_number, &$customers_id, &$messageStack) {
    Even though I had to modify the core file to get the data I need into the observer, that change -- add some data to the notifier call -- is better than having all the additional login validation code in the core file. Note: customers_member_number is a store unique variable added to the customers table. Another core file change in the login header file pulls that variable out of the table in the customer query in the file.

    I'd certainly be interested in a simpler approach.

  5. #5
    Join Date
    Sep 2009
    Location
    Stuart, FL
    Posts
    12,492
    Plugin Contributions
    88

    Default Re: $messageStack->add(...) in observer won't work

    Rather than passing $messageStack to the observer-class, you can reference that object in your observer-class using

    Code:
    $GLOBALS['messageStack']->add(whatever);

  6. #6
    Join Date
    Jul 2012
    Posts
    16,734
    Plugin Contributions
    17

    Default Re: $messageStack->add(...) in observer won't work

    The same could be said for the data related to $check_customer variable, though perhaps the associated data could be obtained after the successful login as identified by the notifier 'NOTIFY_LOGIN_SUCCESS' where the data has been captured in the session...

    That part depends on how the information is used to accomplish your desired task.

    The thing to consider and why I commented is that the notifiers have been incorporated to attempt to provide trigger points/hooks where software can monitor operation. This makes the software also more flexible by not having to actually touch the core code. While a lot of thought and consideration has been given to each such notifier, sometimes it is not enough on its own and perhaps a change made, but in many cases where a notifier or group of them have recently been added it is likely that the needed tools are or easily can be made available.

    Sometimes that means letting the code be "patient" for another piece of information to become available, and sometimes to just grab what is needed. :)

    Now as far as using an additional notifier in your observer, instead of just using the update function, you can create a function that is specific to the notifier. In this case (and for all ZC 1.5.3 and above), it would be:
    Code:
    function updateNotifyProcess3rdPartyLogins(&$class, $notifier, &$,&$,&$) {
    }
    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
    }
    Or it can be used without that additional assignment, etc...

    This all depends on what is needed where in the process, but so far there doesn't appear to be any reason to modify the notifier(s) to accomplish/retrieve the desired information. This will make things a little easier for you in the future.

    I also suggest commenting in your observer the format of the notifier considered. While generally they are not expected to change, sometimes they do and comparing the what was to what is becomes much easier with that little bit of information with which to compare.
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  7. #7
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default Re: $messageStack->add(...) in observer won't work

    Wow! Thank you for taking the time to write such a detailed response. Your tips will be very helpful and are greatly appreciated. Could you please expand your tip on the update function name? Under what conditions should I use "update" and when should I use something else? In your example, you used update followed by a form of the notifier name. Is that on purpose or required, or could I use any name, for example, "my_function"? Could I pass a variable to the next notifier if the name were "update"? Could I pass a variable to other following notifiers, even if they are not next?

  8. #8
    Join Date
    Jul 2012
    Posts
    16,734
    Plugin Contributions
    17

    Default Re: $messageStack->add(...) in observer won't work

    Quote Originally Posted by Dave224 View Post
    Wow! Thank you for taking the time to write such a detailed response. Your tips will be very helpful and are greatly appreciated. Could you please expand your tip on the update function name? Under what conditions should I use "update" and when should I use something else? In your example, you used update followed by a form of the notifier name. Is that on purpose or required, or could I use any name, for example, "my_function"? Could I pass a variable to the next notifier if the name were "update"? Could I pass a variable to other following notifiers, even if they are not next?
    Normally, I would prefer to answer questions top down; however, I think that I can address everything along the way but in a different order as I get the feeling by the questions that there is some understanding kicking in and desire to know more.

    So, a little understanding about what's going on... On each page load, basically the entire store is "built". There's an initial page load (first visit where a session hasn't begun) and then there is marching through the store or even jumping to one's favorite location. Before the first visit, session data for the anticipated customer doesn't exist or at least in a default store is not yet directly accessible. Once the individual arrives, a session data marker is attempted to be set, and from that point forward, they are basically associated with a session (related to $_SESSION). Now, though when the first and any subsequent page is loaded, basically the index.php file is loaded, which branches out and loads an entire series of logic as well as base code. In that initial load, the includes/auto_loaders folder is accessed as well as other folders such as includes/init_includes (there are many others, but not exactly pertinent to this notifier/observer discussion). As of ZC 1.5.3, part of loading the notifier/observer system is to allow for a file to "independently" serve as an observer (filename is like auto.xxxx.php). Prior to that, an observer had to be referenced/loaded and typically through a config.yyyy.php file found in the includes/auto_loaders directory.

    The files in the includes/auto_loaders directory are accessed early enough in the load that the associated files can be mapped to a trigger point or load point. The default for the auto.xxxx.php file is a load point of 180. Anyways, that load point value relates to the sequence at which files/information is loaded. The lower the number the sooner it is loaded. Some things have to be loaded before others. For example to use the function zen_not_null, well the function file has to be loaded to memory. Just like you can't access the $messageStack variable before it is declared/built.

    All of this is to say, that the typical generation of an observer is one that is loaded/activated during each page load, and that once the next click is made that basically/generally speaking any information that has been stored in that observer class is wiped to be created/recreated based on the next page load. There are ways around that (ie. $_SESSION, cookie, the database possibly, or if truly necessary written to a file), but the need to get around it depends on the need of the data. If generally just accept that on each page load information will/needs to be created as/where needed then at least won't get hung up on the smaller detail(s). Once something seems functional can consider some memory/time saving techniques.

    So to try to answer the question:
    Could I pass a variable to other following notifiers, even if they are not next?
    Is in essence yes if by not next you still mean that at some point in the current page's load but possibly 1000's of lines of code later with unknown number of notifiers/observers between them, yes they can be "passed" (possibly internally stored to then be retrieved from outside of the current observer or from inside the current observer). If you mean can you store a value inside the observer class during login and on logout expect

    Wait, more than one observer? Well yes, there could be two/three/four plugins/programs that all listen to the same code point. How they interact can be beneficial/problematic, the sequence that they load in may be helpful or a hindrance. But, save that thought for later. This is something likely to occur when two or more plugins deal with similar things. For example the notifier you chose to use relates to third party logins... If there were three different places in which to login using a single set of criteria, all of that could happen within a single notifier. But, the data internally stored to the observer class during the login, would not be accessible during the next page load of say logout... (Again there are ways to store data to persist across page loads, but internal to the class that is itself not maintained across page loads, $this->variable, don't work.)

    So, regarding the two naming conventions of handling notifiers. The update function is generic and ZC 1.5.1 and before only had an update function and only allowed passing a single non-editable variable. The variable could be an array, but any changes made to it stay only in the observer class. As of the production release of ZC 1.5.3, 9 additional variables have become available where each of those variables could be used, edited, and the changes returned to the original function. They don't have to be edited, but they can be. In adding this feature, the Zen Cart developers decided that they would also expand the operation a little. So, they created the possibility for a function to be called that follows the naming convention update+Camelized Notifier, you can look up what camelize means, but basically it removes the underscores and then capitalizes the first character that follows it leaving the remaining characters lower-case. Fortunately for now, PHP doesn't distinguish between capitalization of functions, but does for variables. (ie: $db->Execute($sql); will perform the same as $db->execute($sql); for now...) No telling when the PHP group may go to even more stringent coding expectations and require function capitalization to be consistent between declaration and use.

    Anyways, so you have two options, you can use the new method of updateCamelCase(....) or update(....). This naming convention is governed by code within the ZC system. If you wanted to have a my_func() type function, it would have to be called by some other code which could reside in the update() function. You can even have both functions updateCamelCase() and update() in the same observer class, but the way the code is written it will attempt to execute the camel case version first if found, if not found then attempt to execute the update function.

    So, which is "better"? That really depends. I do know, that if your code is written using the update function only and default values are not set (update(&$class, $notifier, $arraylike, &$firstvalue, &$secondvalue)), and the code is installed to a vanilla install of ZC 1.5.1 or before, then the store will break. This is because in the earlier versions, they didn't know/recognize that there could be other variables, and therefore don't send a default, and then PHP says "HEY! YOU DIDN'T SET A VALUE AND NOW I DON'T KNOW WHAT TO DO!!!".

    If you use the update version and you are observing more than one notifier, then within the update function you would want (maybe) to see what notifier was used to get into the update code so that action A is taken for notifier 1 but action B is taken for notifier 2... If they both have some common action, then the update function may be preferred. Otherwise, if they do different things, it may be desirable to use the camelcase version. I look at it as the code checks for the existence of the camelcase first, so why not use it? Also, the variables being received can be tailored to what they are rather than some generic $var1, $var2, $var3, etc... This improves code readability and can simplify operations. From that/there you can have other functions that are called from either. But this aspect is more about design, intent, and need.

    As to the passing of variables, again, if the class is used in a single load sequence (like using both notifiers identified before), then if you use the camel case version, you'll need to store data internally when reaching the first notifier to be used by the second camelcase function (or update function if the camelcase function doesn't exist). If you just use the update function, then if you make the variable to be kept static it will persist, but otherwise will disappear when the second notifier is reached because the update function will basically be called again for the first time. (a bit of an oxymoron, I know)
    ZC Installation/Maintenance Support <- Site
    Contribution for contributions welcome...

  9. #9
    Join Date
    Jun 2012
    Posts
    412
    Plugin Contributions
    0

    Default Re: $messageStack->add(...) in observer won't work

    Thank you so much MC12345678. Somewhere along the line between zc 1.5.1 and now, I have missed some memos.

  10. #10
    Join Date
    Jul 2012
    Posts
    16,734
    Plugin Contributions
    17

    Default Re: $messageStack->add(...) in observer won't work

    Quote Originally Posted by Dave224 View Post
    Thank you so much MC12345678. Somewhere along the line between zc 1.5.1 and now, I have missed some memos.
    Well, don't know what your level of code comprehension is, but I would suggest looking at (in ZC 1.5.5) includes/init_includes/init_observers.php (pay particular attention to the notes at the top of the file) and includes/classes/class.base.php.
    In the class.base.php suggest searching for observer and begin reading through the code/notes related to the base class and the notify function in there. There likely are some php functions that will need to be read about in the php manual, but that's basically where the nuts and bolts are in addition to the previous file.

    I think I happened across the code when I was doing an upgrade from 1.5.1 and got curious about the changes. I had also previously seen some related discussion/questions on github that finally made sense. :)

 

 
Page 1 of 2 12 LastLast

Similar Threads

  1. How do I add a coupon alert via messageStack for COWAO?
    By Dan123 in forum All Other Contributions/Addons
    Replies: 2
    Last Post: 9 Jul 2011, 01:05 AM
  2. uri mapping won't work on add to cart botton? help..
    By bryanblue in forum All Other Contributions/Addons
    Replies: 14
    Last Post: 25 Jan 2011, 03:27 AM
  3. $messageStack->add('gv_send'...
    By creative_mind in forum General Questions
    Replies: 4
    Last Post: 5 May 2010, 07:11 AM
  4. contact us won't work
    By mex in forum Templates, Stylesheets, Page Layout
    Replies: 1
    Last Post: 23 Mar 2007, 11:30 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
disjunctive-egg
Zen-Cart, Internet Selling Services, Klamath Falls, OR