Re: Adding custom notifiers
Absolutely! The admin console makes use of the notifier/observer interface as well.
The admin-side /includes/auto_loaders/config.your_observer_class.php for your observer should use the following load-instructions so the observer's retrieved from the storefront:
Code:
$autoLoadConfig[200][] = array(
'autoType' => 'class',
'loadFile' => 'observers/your_observer_class.php',
'classPath' => DIR_FS_CATALOG . DIR_WS_CLASSES
);
Consider, too, submitting your custom notification to the zencart base (via GitHub PR) so that others can make use of that call-out as well!
Re: Adding custom notifiers
The store-side observer is loaded in the admin (from notifier trace), the notifier call is executed (from debug email just before call), but the update function in the observer does not execute. When the observer is called from a store-side notifier, the update function is executed as expected.
The objective is to send an email if a customers address is changed either by the customer, or by admin logging in to the customers account, or the admin changes the customers address in the admin. The email is sent if the customer changes the address and I'm working on the case where the admin changes the address in admin, file admin/customers.php.
The nofifier code in admin/customers.php is:
Code:
$zco_notifier->notify('NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD', (int)$customers_id, $sql_data_array);
An observer code store-side fragment is:
Code:
class zcObserverEmailDefaultAddressChange extends base {
** constructor method !
*
* Attach observer class to the global $zco_notifier and watch for a single notifier event.
*/
function __construct() {
global $zco_notifier;
$zco_notifier->attach($this, array('NOTIFY_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD',
'NOTIFY_MODULE_ADDRESS_BOOK_UPDATED_PRIMARY_CUSTOMER_RECORD',
'NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD'));
}
/** Actual Method that does the desired activity
*
* Called by observed class when any of the notifiable events occur
*
* @param object $class
* @param string $eventID
* @param array $paramsArray
*/
function update (&$class, $eventID, $paramsArray = array()) {
// ... do stuff
}
}
Thanks,
Dave
Re: Adding custom notifiers
Please also considering writing a short article on how to do this (once you've figured it out) in
https://docs.zen-cart.com/dev/code/
Re: Adding custom notifiers
Quote:
Originally Posted by
Dave224
The store-side observer is loaded in the admin (from notifier trace), the notifier call is executed (from debug email just before call), but the update function in the observer does not execute. When the observer is called from a store-side notifier, the update function
is executed as expected.
The objective is to send an email if a customers address is changed either by the customer, or by admin logging in to the customers account, or the admin changes the customers address in the admin. The email is sent if the customer changes the address and I'm working on the case where the admin changes the address in admin, file admin/customers.php.
The nofifier code in admin/customers.php is:
Code:
$zco_notifier->notify('NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD', (int)$customers_id, $sql_data_array);
An observer code store-side fragment is:
Code:
class zcObserverEmailDefaultAddressChange extends base {
** constructor method !
*
* Attach observer class to the global $zco_notifier and watch for a single notifier event.
*/
function __construct() {
global $zco_notifier;
$zco_notifier->attach($this, array('NOTIFY_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD',
'NOTIFY_MODULE_ADDRESS_BOOK_UPDATED_PRIMARY_CUSTOMER_RECORD',
'NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD'));
}
/** Actual Method that does the desired activity
*
* Called by observed class when any of the notifiable events occur
*
* @param object $class
* @param string $eventID
* @param array $paramsArray
*/
function update (&$class, $eventID, $paramsArray = array()) {
// ... do stuff
}
}
Thanks,
Dave
Dave, first, consider using $this instead of $zco_notifier since your observer has extended the base.
Would you post the contents of your /admin/includes/autoloaders file that (er) auto-loads the observer in the admin?
Re: Adding custom notifiers
Quote:
Originally Posted by
lat9
Dave, first, consider using $this instead of $zco_notifier since your observer has extended the base.
Would you post the contents of your /admin/includes/autoloaders file that (er) auto-loads the observer in the admin?
Changed zco_notifier to $this in the constructor. Still not executing update function.
Auto-load file follows:
Code:
<?php
// -----
// Admin auto-loader for auto.email_default_address_change.php observer
//
if (!defined ('IS_ADMIN_FLAG')) {
die ('Illegal Access');
}
$autoLoadConfig[200][] = array(
'autoType' => 'class',
'loadFile' => 'observers/auto.email_default_address_change.php',
'classPath' => DIR_FS_CATALOG . DIR_WS_CLASSES
);
Dave
Re: Adding custom notifiers
Need to also instantiate (basically activate, construct, or otherwise establish a variable to possible use) the class as well. Right now it is just a class that exists but nothing "uses" it.
Add to that file (after the existing information):
Code:
$autoLoadConfig[200][] = array(
'autoType' => 'classInstantiate',
'className' => 'zcObserverEmailDefaultAddressChange',
'objectName' => 'observerEmailDefaultAddressChange'
);
The objectName basically can be whatever you want it to be, though in this case preferably something that doesn't already exist. Whatever it is called/assigned, that text becomes the variable that can be used to call that class. In this case in other code you could use: $observerEmailDefaultAddressChange->update(.... to call the update class.
BTW, one other thing that will likely need to be updated to take full advantage of what the observer offers is to add additional parameters to your use of the update method, though there are yet additional ways to code the observer ever since ZC 1.5.3.
Re: Adding custom notifiers
Quote:
Originally Posted by
mc12345678
Need to also instantiate (basically activate, construct, or otherwise establish a variable to possible use) the class as well. Right now it is just a class that exists but nothing "uses" it.
Add to that file (after the existing information):
Code:
$autoLoadConfig[200][] = array(
'autoType' => 'classInstantiate',
'className' => 'zcObserverEmailDefaultAddressChange',
'objectName' => 'observerEmailDefaultAddressChange'
);
The objectName basically can be whatever you want it to be, though in this case preferably something that doesn't already exist. Whatever it is called/assigned, that text becomes the variable that can be used to call that class. In this case in other code you could use: $observerEmailDefaultAddressChange->update(.... to call the update class.
BTW, one other thing that will likely need to be updated to take full advantage of what the observer offers is to add additional parameters to your use of the update method, though there are yet additional ways to code the observer ever since ZC 1.5.3.
In what other code do you suggest I call the update function? It seems that this approach suggests to not notify the observer in the usual way but to call update directly, in my case, in admin/customer.php. The class (base), event_id, and params are arguments in the update call. Am I missing something?
Thanks,
Dave
Re: Adding custom notifiers
Sorry everyone...I'm in procedural code, so I deleted "extends base", and went back to zco_notifier->attach... With mc12345678 addition, i now get a fatal error, so I deleted that code too. No errors, but update is still not executing.:blush:
Re: Adding custom notifiers
Quote:
Originally Posted by
Dave224
In what other code do you suggest I call the update function? It seems that this approach suggests to not notify the observer in the usual way but to call update directly, in my case, in admin/customer.php. The class (base), event_id, and params are arguments in the update call. Am I missing something?
Thanks,
Dave
So in the "spirit" of code reuse, an observer class may have more methods than just those necessary for being called by a notifier. Let's say a method to sort items in a specific sequence, or to retrieve data from the database a specific way/format. In that situation, such code could easily be reused by reference to the variable that stands for the observer class and then to specifically call the associated method. As to whether the update method or one of the other methods identified by this portion of the observer/notifier docs is used mostly depends on style of desired coding practice and the ability to provide specific information to the individual reviewing the code: https://docs.zen-cart.com/dev/code/n...update-methods
So for example, when using the update method where a notifier provides 2 or more parameters (beyond the notifier designation):
Code:
$zco_notifier->notify('NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD', (int)$customers_id, $sql_data_array);
both the $customers_id and the $sql_data_array variables need to be "captured" and used if it is desirable to obtain the $customers_id and then to use or modify the $sql_data_array variable.
That third parameter ($sql_data_array) needs to be "caught" on the observer side.
The provided observer method (update) from post #3 only captures the $customers_id and does not directly provide a way to process or receive $sql_data_array.
Code:
function update (&$class, $eventID, $paramsArray = array()) {
This code fragment will receive the designation of the class ($class) that made the call to the notifier (in this case effectively $zco_notifier), the eventID ($eventID) as "translated" to relate back to 'NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD', and the first parameter after the notifier designation ($customers_id)…
To be able to receive the $sql_data_array, an additional parameter is needed in the provided update method:
Code:
function update(&$class, $eventID, $paramsArray = array(), $param2) {
As provided here, $param2 will only be readable. To allow it to be modified it needs to be passed by reference:
Code:
function update(&$class, $eventID, $paramsArray = array(), &$param2) {
In this way, the values of $param2 can be modified within the update method.
Now though, as can be seen, the variables are "non-descript". This is "okay" if the observer is only observing one notifier; however, in the case of two or more notifiers being observed, what would be the "appropriate", code-reader friendly way to identify the variables (See this specific information: https://docs.zen-cart.com/dev/code/n...terpretation)?
In ZC 1.5.7, a "better" way has been implemented (snake-cased) (better because it is easy for a developer to locate the code applicable to the notifier using search tools), but beginning in ZC 1.5.3 (and still available in 1.5.7) a naming convention was implemented to allow discrete methods of code to be implemented. (No need to have if this, then that, if this2 then that2 type coding within the update method). That is identified/described in the above doc: https://docs.zen-cart.com/dev/code/n...update-methods
So in your 1.5.5 observer code you could use this method (camelCased):
Code:
function updateNotifyAdminModuleAddressBookUpdatedCustomerRecord(&$class, $eventID, $customer_id, &$sql_data_array) {
which makes it relatively obvious what the received variables within the code section are or provide.
I find camelCased naming a major problem though as said, because I can't use the developers tool kit to find the specific code section/area where 'NOTIFY_ADMIN_MODULE_ADDRESS_BOOK_UPDATED_CUSTOMER_RECORD' is used... That's where the ZC 1.5.7 version comes in "handy" because the method instead of being: updateNotifyAdminModuleAddressBookUpdatedCustomerRecord() can be identified as: notify_admin_module_address_book_updated_customer_record(). In use of the camelcased code, I have also captured the notifier code as a comment along with the method so that 1) a search would find the specific code area and 2) It would be easier to identify why an observer no longer functions like it "used to" because sometimes notifiers do change in some way or another through Zen Cart versions. Now, also note, "currently" in php code (seen at least in up to PHP 7.4), the method could have whatever capitalization is desired, but I have a sneaky suspicion that at some point in the future the PHP community will enforce capitalization in method calls, so best to stick to the suggestions/current code expectation.
If you wanted to be "future" thinking though adding more code lines, you could put your code in the ZC 1.5.7 version (snake-cased) of the observer method with the updateCamelCased method or update method making a call to that snake-cased code... Then as you move up to the newer version(s) you can effectively drop the extra code leaving behind just the code applicable to the "newer" version. Whatever...
Anyways, **WAY** more than what was asked about, but hopefully the various content on the above referenced docs page is ever more helpful than past documentation. BTW, I've even just looked through that docs page some more and it is fruitful with concepts and examples to help in the development of observer/notifier considerations. E.g., I just found/(re-?)realized that there is a detach method for observing a notifier. This allows an observer class to stop observing after some pre-determined condition has been met during the current page load (or if the observer is a session class after some pre-determined condition has been met).