You chose to answer some side-question three posts down... my original question still stood.
And yes, I EVENTUALLY (after about 12 hours of fighting with it) solved my problem that a little documentation could have solved in 20 seconds.
You chose to answer some side-question three posts down... my original question still stood.
And yes, I EVENTUALLY (after about 12 hours of fighting with it) solved my problem that a little documentation could have solved in 20 seconds.
As we are a community here you can, I believe, add to the wiki what you have foundOriginally Posted by s_mack
Zen-Venom Get Bitten
That sounds all well and good. Where that logic breaks down is then far-from-best-practices get published and [shutter] followed. While I guess it is better than nothing... what if my "solution" has dire consequences for someone? If I knew the code well enough to write an entry for it in the Wiki then I wouldn't have needed the Wiki. I needs to be written by someone actually familiar with the code.
I understand better than most the headache of documenting one's products. It is a daily struggle for me as well. But come on, it has been YEARS and the wiki is basically empty.
This is the entry now:
I'm sorry, but blank would have been just as useful.Introduction
Shipping modules consists of two files.
The shipping class is stored in
includes/modules/shipping/<module name>.php
while all text is stored in the appropriate language file
includes/languages/<current language>/modules/shipping/<module name>.php
Shipping Class
Anatomy of a Shipping Module
Class Names
Constructor Method
quote Method
check Method
install Method
remove Method
keys Method
Tips & Tricks
Trouble Shooting
I have not deeply reviewed various shipping modules; however, to try to answer the overall question about how some things fit into ZC, there are a myriad of aspects that are not covered in detail. With regards to shipping as an overall aspect or any section/type of code not heavily documented (unfortunately), review of the code for where/when the "object" is called and what its return value is can lead to a solution.
The fact that a previous post in this thread indicated that in review of the UPS module the use of $module was not found within the function quote, completely surprised me as having downloaded the latest UPS module, the following is in the first few lines of the quote function:
From that code, seems that the first if statement checks to see that a method has been identified and where it has been identified to the quote code, then it must also have been determined to be an acceptable method to be used, where using potential logic that a method is one of the many methods of $methods and therefore if a $methods is created correctly, then $method is just one of those... But perhaps that is oversimplified...Code:function quote($method = '') { global $_POST, $order, $shipping_weight, $shipping_num_boxes; if ( (zen_not_null($method)) && (isset($this->types[$method])) ) { $prod = $method; // BOF: UPS USPS } else if ($order->delivery['country']['iso_code_2'] == 'CA') { $prod = 'STD'; // EOF: UPS USPS } else { $prod = 'GNDRES'; } if ($method) $this->_upsAction('3'); // return a single quote
At any rate, the last line of the above snippet, indicates that if a method has been provided to the quote code to then access the function _upsAction and pass along the value of '3' into that function for it to do whatever it is going to do (which by inspection is to eventually tell UPS to provide a single quote that uses the method fed to the function identifying the internal variable _upsProductCode to be the method that was used.)
Pretty much to me, the rest is following the bouncing ball through the code to identify what is done to provide UPS the information it needs to be happy and provide a result back. The USPS version appears to be a little cleaner (haven't looked at the DHL code), but all in all, the "how" to do it in my opinion comes from the black box perspective...
There is a larger set of code (ZC) that has "output" and is expecting input. What happens within the shipping (or payment) module has no real affect to the ZC part (or shouldn't) provided it receives the information necessary to move forward and provides the information requested. There may be other "factors" to maintain which can be captured via session variables, or particular settings captured through the operation(s). But the important part is to see what is provided and what is expected...
As to the "potential of leading someone astray"... Well, welcome to open source... We are all trying to do our best, trying to make improvements, and at the same time for the most part will see that while those that contribute stand behind their code, errors happen... But seems most do (should) provide the feedback to correct the mistakes. I know for a fact that it doesn't happen 100% of the time or quickly, but it is through the input, feedback, and self motivation that any of these things get better... Take a step, make a mistake, try again... Backup, backup, backup... Can always recover with backups...
ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...
You're absolutely right.
And I did see that. I think it was early in my investigation and I mistakenly took that comment as meaning that section was if we were only WANTING a single option to show, which wasn't the case for me so I skimmed past in and managed to not see it later when I started looking specifically for that variable.
I'm still not sure relying on vague hints in 3rd party modules is the way to go though. It really should be documented at least to a basic level.
So, I would say, though I am not certain of the possibility that there may not be much more that can be specfically documented about the return of the quote. There is nothing seen yet that requies $method to be a single method as it could be a colmination of multiple methods or other data... Further while not specifcally stated for shipping modules, one of the suggested/posted means of provding code/understanding ZC is review of how the code operates... So all that "negative" to also say, if there is something in your adventure that you think would help the next aspiring contributor may I suggest along the lines of kobra in posting (requesting formally) specific information be appended to somewhere to help the next individual... That and keeping an eye out in the forum to help others as well... Yes a shame you lost time, but hopefully also learned more about how to work with/in ZC.
ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...
If I may also add, shipping and payment are probably the most complicated of "options" to work withandare almost themselves entirely their own entities and trouble...
The basic shipping modules themselves while "simple" are themselves complex... Attempt to combine shipping options and then things start to go sideways... Case in point the number of posts about how to do this or do that with one or more shipping modules... While not impossible addressing every possible combination of varying aspects of the shipping process starts to turn into a mess of possibilities...
A shipping "module" can itself almost turn into a mini ZC, taking the characteristics of the "package(s)" the requirements of the shipping service into account all to simply provide a "price"... And that's before the storeowner really gets involved other than the original setup...
Adding a shipping module? Great!!! Wish you the best of luck...
ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...
It doesn't need luck... it needs documentation. That's all. Just a note giving some hint that the same function is used in two ways. "if $method variable is passed, then the return is a single value array, otherwise a multi-value array..." blah blah.
That is, *IF* that's how it works... I still don't know for sure. If it does, its weird. There is a better way to handle it. In fact, it is already there with the session variable so there's really no reason it can't parse the array and pick out the option that was selected. Right now we pass an array to the calling function showing all the options then, when one is picked, the same quote function again has to pass an array - but this time a different one? Why? Pass the exact same array and have the calling function (which already knows what method or else it couldn't have passed that variable) sort it out. It DOES do this to some extent, because I could see the correct ID was carried over, but not the correct title or cost. The solution was to send a single-value array back the 2nd time. You say it is "complicated" but really "convoluted" is a better term. It doesn't have to be as complicated as it is.
Whew, finally finished this after working on it little by little over the last couple of days.....
Yes, I recall your post "of return" and the same basic can't get things to change discussioon..
So, let's leave that behind for a moment. Here's my perception of how such a module is to work... As far as "previous use" of ZC and coding, well, I looked at a few options when first considering a cart for a non-profit and this seemed like the most flexible for our needs and at no cost to the organization other than additional volunteer time, well... No brainer there.
So, here's my thoughts on what is expected of a shipping module:
1. Upon generic inquiry, provide all possible rates based on the contents of the cart.
2. Provide the potential price(s) and option(s) at any time asked (again based on item(s) in cart).
3. Provide the single cost of shipping based on user selection of options available.
4. Provide the ability to be presented the available options with the previously user selected option indicated.
5. Provide the store owner the ability to restrict the usage of the shipping method based on chosen criteria.
6. Provide the ability for multiple shipping modules to be presented to a customer/owner.
7. Allow sub-options to be selected/presented for additional features/options.
8. Offer means to ship via multiple methods on a single purchase.
9. Price of chosen shipping method to adjust based on cart changes.
So, I'll say this, item(s) 8 is pretty much only covered in commercial mods because of the added complexity/need of the few as compared to the whole, item 7 is somewhat the same.
Item 6 can be offered through multple shipping modules, or just as well through a single one that is diversified to handle multiple.
Item 5 has multiple possibilities as seen through all of the posts by those that want to customize their shipping module(s): min/max purchase price, destination, specific product, combination of product, specific attribute of a product, weight, free item, billing address, quantity of all product, quantity of a specific product, etc...
So turn things around a little and then there is item 1... That is the base quote "process". Whatever the shipping module is designed to support, give all the values that are possible. That seems to be what you were able to retrieve/do.
Item 2 this is accomplished by the shipping module not exactly storing anything but "recalculating" the shipping quotes every time asked to provide one based on the cart contents. (Although could also do so for a "saved" cart if such was necessary to have for a particular store.)
Item 3 is kind of what I think you were getting at with the discussion of all the data is currently available, why send back a single method to be processed... I say because of Item 4...
Item 4 requires the same series of rates to be presented as originally presented; however, to also include selection/default of an existing/previous selection. So for example in the checkout process if one returns to the checkout_shipping page for any reason after making a shipping selection, then it is desired that the previous selection be shown, but also to show all of the other available options (unless one is going to require some sort of "logout/login" process to support a new selection). If the default functionality of the shipping module was to show a single quote if the session variable was set, then the session variable would have to be cleared/deleted but temporarily stored so that the previous selection could be captured/identified and then as the customer moves away from that page, the data would have to be stored again in the session variable. So, a couple of thoughts here, okay the "clearing" could occur in a header_php.page, it could also happen in the module. However, the module would need to have a "knowledge" of what page/content was being displayed so that it would know to clear the value showing multiple rates, or it would have to be told that it should do this. Well, the later is done by exclusion/inclusion of sending the method variable. If the method variable is present, then act differently on the code, if it is absent then just provide a quote of all possibilities... From that point it is a matter of identifying the "typical" usage of requesting a quote in the core code... From there, the same code could be applied elsewhere, or different data could be passed to the function to provide different "style" results...
Okay, so there is also item 9 which I didn't go back and resequence to fit this discussion. This is somewhat covered in the other options above, but seems worthy to state specifically. Basically, at any time the shipping information is "tested" it seems that it would be of value that it was already up-to-date with the current value/price based on 1) any previous selection of shipping method, 2) being updated on changes to the item(s) in the cart. I believe lat9 found some form of discrepancy in accomplishing this based on some fairly specific conditions (although ultimately a possibility and to be addressed), like changing shipping destination as it relates to tax locations after initial selection of the shipping method progressing to verification but to return to somewhere specific in the process to make a change, etc... Well documented and proven to be an issue but I don't recall the specifics at the moment, just that there were enough ifs/buts/whens that it could drive one crazy. :))
ZC Installation/Maintenance Support <- Site
Contribution for contributions welcome...
I took the time to read your post, and you certainly took the time to write it... thanks for that. Unfortunately I didn't quite get what your point is. If it was to illustrate the complexity... I never said it was simple, just that it is convoluted with how the "array" (I put it in quotes because an array with one element is only an array by technicality) is passed back differently depending on whether the "method" variable is present. But that was an aside anyway... yes it could have been done simpler, but that isn't the point. The point is that there is no documentation or comment stating the way that variable is used. It is particularly necessary to have some because a) it is a strange way to do it and b) NO EXAMPLE EXISTS. None of the stock modules reference that variable at all.
Anyway, I did eventually figure it out and I'm 3/4 of the way done my module(s). I actually have to make 3 separate modules for the same service because I want to distinguish between different service "types" (regular, registered, express) and I want some visual distinction. My module(s) is going to be more complex than most because I also want to offer the lowest priced option for free and adjust all other options by that amount, including those in the "other" modules.
This all came about because I started to use a distribution centre for my products and they offer so many shipping options (28, to be exact, depending on destination). Each service has its merits so I want to present at least most of them in a fashion that is digestible to the user.
Anyway, I'm on my way. It was just so much of a stumbling block not having that tiny bit of documentation and (still) no response from someone that has the full understanding of the code.
Bookmarks