Forums / Addon Admin Tools / Preview Email

Preview Email

Views: 12,184

Results 41 to 54 of 54
30 Sep 2026, 10:45 PM
#41
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Preview Email

Scott — thanks for the concrete example; that pins it down.

I checked every Zen Cart from 1.5.7 through 3.0.0, and stock core builds the confirmation-email line as qty x name (model) = price in all of them (in order::create_add_products(), the products_ordered / products_ordered_html build). None put the model first. So 1 x WHS0059 Baby's Breath - Excellence, 250gm Bunch $15.00 — model first, no parentheses, no = — isn't what stock Zen Cart sends; something on your store is reformatting that line. The preview is showing the stock format, which is what a preview rebuilt from order.php can show.

I also checked the common mods that touch orders, in case one of them was rewriting it, and came up empty: One Page Checkout uses the stock order class as-is (it just calls new order() from core, ships no order.php, and never touches the email), and Edit Orders doesn't rebuild the confirmation line at all — its only model formatting is [model] in the change log, not model name. So it isn't one of those; it looks specific to your store. My hunch is a customization on the Portland florist's site changed how its order-confirmation email builds the product line, rather than anything in core — does that match what you've got there?

And here's where your original point lands, fairly: a preview that reproduces core's markup reflects stock Zen Cart, not whatever a given store has changed. That's true of ours, and it was equally true of the 1.x/2.x line — build_checkout_email() hardcoded name (model) as well, so it would show the same stock format on your store, not your model name. Neither approach can mirror a store-side change to the email by copying core.

So the useful question is where your store changes it, because that decides what's possible:

- If it's an edit to includes/classes/order.php (its products_ordered line), we can make the preview read the store's own order.php and render from that, so a customized line shows through. That's the "don't just copy core" direction you've been pointing at.

- If it's a plugin or a notifier reformatting the email as it's sent, then order.php is stock and the change lives only at send time — nothing that inspects a stored order can reproduce it; only an actual send would.

Quickest way to tell which: v3.0.2 ships tests/Unit/CheckoutParityTest.php, which checks the preview against your store's own order.php. If it passes on your store, the change is at send time; if it fails, it's in order.php and we've got a clear target. Or just tell me what's reformatting that line.

Either way, I want to make this right for your case — I just need to know which it is.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

30 Sep 2026, 11:20 PM
#42
swguy avatar

swguy

Administrator

Join Date:
Feb 2006
Location:
Tampa Bay, Florida
Posts:
10,720
Plugin Contributions:
56

Re: Preview Email

- If it's an edit to includes/classes/order.php (its products_ordered line), we can make the preview read the store's own order.php and render from that, so a customized line shows through. That's the "don't just copy core" direction you've been pointing at.

This is what I want you to do.

Quickest way to tell which: v3.0.2 ships tests/Unit/CheckoutParityTest.php ...

No, it doesn't.

That Software Guy. My Store: Zen Cart Support
Available for hire - See my ad in Services
Plugin Moderator, Documentation Curator, Chief Cook and Bottle-Washer.
Do you benefit from Zen Cart? Then please support the project.

1 Oct 2026, 12:35 AM
#43
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

Correct on the test. 3.0.2 strips the tests/ out of the release zip.

Now that we know we are dealing with a modified cart, we have the next problem.

Monitoring a cart's modified order.php uses eval, which fails the security_scan based on info from ZC.

It doesn't mean I can't do it. After all, we would be evaluating the store's own order.php, but will I be able to get it past ZC's security check?

PM sent.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

1 Oct 2026, 2:44 PM
#44
carlwhat avatar

carlwhat

zennedOut

Join Date:
Nov 2005
Location:
los angeles
Posts:
2,969
Plugin Contributions:
8

Re: Preview Email

i think the whole direction of this plugin is wrong.

if a store modifies how a order confirmation email looks, the whole point of the preview is to preview how that store's email looks. even a modified one.

the code contained in this script does nothing of the sort.

IMO, i would do something like:

$preview = new order($orderNum);
$preview->send_order_email();

and then use the notifier/observer system to actually NOT send the email. and then, again using the notifier/observer system to grab the constructed emails from this notifier: NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL.

that is how i would approach it, which i think is in-line with the goals of @swguy.

author of square Webpay, now with Apple Pay and Google Pay.
mXworks
donations: venmo or paypal accepted.
premium consistent excellent support. available for hire.

1 Oct 2026, 8:02 PM
#45
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

@carlwhat

As always, you have an excellent point about what the plugin should do. I'm not sure I agree that its current state is "wrong."

Perhaps it's better to say it could have been better if the update considered modified core files.

The goal was to find mods that were dormant, popular, and not working on current ZC versions. Some were mods my clients needed; some I just felt the community needed.

Secondary to getting them current was the possibility of encapsulating and "modernizing" them. In this case, like many others, the original mod was the basis for the rejuvenation.

This mod did what the previous version did, and other than pointing out the code involved, it only added the ability to email yourself a copy of the email to see how your email client handled the code.

Sadly, I did not consider modified core files when building the plugin. I don't have a single customer who has wanted the sequence changed in this situation, nor did I ever consider it being overridden during plugin development.

I have a working model that handles this situation, but the method required could be a security risk. Minimal, at most, but it will fail the scan when submitted simply for using that code.

I'm awaiting a ruling on that. We'll see what's next once I receive an answer.

The forum changeover, cross-referenced plugin IDs, and folks bombarding the new site are really straining the devs right now, so I understand if a decision takes a while.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

2 Oct 2026, 9:08 PM
#46
swguy avatar

swguy

Administrator

Join Date:
Feb 2006
Location:
Tampa Bay, Florida
Posts:
10,720
Plugin Contributions:
56

Re: Preview Email

This doesn't render it correctly either. Would you please feed @carlwhat's suggestion to your AI and see what it can come up with?

This was a weakness in the original plugin too but I was hoping you had fixed it. If you can't get this to go, I'll just approve 3.0.2 and work on the checkout email myself; this was on my todo list anyway. Your UI is vastly better than what I did.

That Software Guy. My Store: Zen Cart Support
Available for hire - See my ad in Services
Plugin Moderator, Documentation Curator, Chief Cook and Bottle-Washer.
Do you benefit from Zen Cart? Then please support the project.

3 Oct 2026, 4:01 PM
#47
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

carlwhat — that's the right instinct, and I chased it all the way down. Capturing the built email beats copying it, and there's an even better hook than NOTIFY_ORDER_AFTER_SEND_ORDER_EMAIL: NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND fires just before zen_mail, hands you the finished $email_order and $html_msg, and passes $send_customer_email by reference, so an observer can grab the content and switch the send off. It's in every release from 1.5.8 to 3.0.0.

The product list is where it runs aground for a preview. The preview works from a stored order (new order($oID)), and $products_ordered_html — the one piece we'd need — is built only in create_add_products(). That method isn't read-only: it re-inserts the orders_products rows, decrements stock and bumps the bestsellers counts as it goes, and its $zf_mode argument has been "Deprecated/unused since 1.5.0," so nothing gates those writes. send_order_email() also reads $_SESSION['sendto'], ['customer_id'] and ['payment'] plus the global $order_totals, so for a past order you'd be fabricating the checkout session too.

So core gives a clean capture at the moment of a real checkout, but no read-only "render this stored order's email" path — to drive send_order_email() for a past order you'd either run a real checkout (persisting an order and moving stock on every preview) or rebuild products_ordered_html yourself, which is the copying we're trying to get away from.

If you know a way to get products_ordered_html for a stored order without the create side effects, I'm all ears — that would let the whole email come straight from the store's own code, and I'd drop the reconstruction in a heartbeat

Appreciate you digging in on this.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

3 Oct 2026, 4:09 PM
#48
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

Scott — thank you, and I appreciate the kind words on the interface; glad that part's landing well.

On the order line: v3.0.3 does read and render a customized order.php — I had it reproducing a model-first line exactly from a hand-edited products_ordered_html. So the fact that it isn't catching yours tells me your store is shaping the email somewhere the plugin isn't looking yet — most likely the text part on its own, an observer, or the template rather than products_ordered_html.

If you can point me to where that change lives — order.php (products_ordered_html / products_ordered), an observer, or the template — or drop in the few lines that do it, I can almost certainly match it. I'd much rather reproduce exactly what your store does than keep guessing.

On carlwhat's idea, which I like a lot: I worked through it in my previous post. The capture hook is real and genuinely better than copying — the catch is it only has the full email to hand at a live checkout, not when previewing a stored order, because the product list is built only inside create_add_products(), which re-inserts the order's rows and decrements stock. If there's a clean way to rebuild that for a past order, I'll happily switch to capturing the real email outright. Either way, I'm keen to get this right for your store.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

3 Oct 2026, 10:53 PM
#49
carlwhat avatar

carlwhat

zennedOut

Join Date:
Nov 2005
Location:
los angeles
Posts:
2,969
Plugin Contributions:
8

Re: Preview Email

i would create a PR to break this section of code into it's own method within the class:

https://github.com/zencart/zencart/blob/f4e0b0066ab811b75b1ad7153245f92065a0b1a1/includes/classes/order.php#L1310-L1325

and see if the powers that be accept said PR.

it seems like that code is not really part of the method name create_add_products.

it also seems a preview of this email, which is an exact replica of what a customer should see, would be a very crucial element for establishing a brand identity.

author of square Webpay, now with Apple Pay and Google Pay.
mXworks
donations: venmo or paypal accepted.
premium consistent excellent support. available for hire.

4 Oct 2026, 1:01 AM
#50
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

@carlwhat

That's the right call, so I put the PR up: https://github.com/zencart/zencart/pull/8015. Breaking that block out of create_add_products() is exactly where this wants to go, and you're right that it doesn't really belong to a method named for adding products in the first place.

I went back through it to be sure it's safe to lift: lines 1310-1325 are pure string assembly. They read $this->products[$i] and $this->products_ordered_attributes and append to $this->products_ordered and $this->products_ordered_html — no DB writes, no stock moves, no bestsellers bump. All of that lives above it in the same loop. So the build itself extracts cleanly into a read-only method.

The one dependency worth calling out is $this->products_ordered_attributeswhich the block leans on. It's reset per product at the top of the loop, so by the time the email line is built it holds only the current product's attribute string. The PR keeps the method pure by taking that string as a parameter rather than reaching back into class state, so the method has no hidden dependency on the create loop having run — which is exactly what makes it usable for a stored-order preview.

The payoff is the whole point of your earlier idea: once that build is a read-only method, a preview can render the real order email straight from the store's own order.php for any stored order, with zero reconstruction on my end and nothing fabricated. Pair that with NOTIFY_ORDER_INVOICE_CONTENT_READY_TO_SEND for the live-checkout case, and the plugin stops copying core entirely and just shows exactly what core produces.

I kept it to a behavior-preserving extraction — the new method returns byte-identical text and HTML, verified across the model, attribute, and one-time-charge permutations — but the name and return shape are wide open, and I'd value your eye on that since you've clearly thought about where this code should live. Thanks for pushing on this; it's a better answer than the one I walked in with.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

4 Oct 2026, 10:45 AM
#51
swguy avatar

swguy

Administrator

Join Date:
Feb 2006
Location:
Tampa Bay, Florida
Posts:
10,720
Plugin Contributions:
56

Re: Preview Email

If you can point me to where that change lives — order.php (products_ordered_html / products_ordered), an observer, or the template — or drop in the few lines that do it, I can almost certainly match it. I'd much rather reproduce exactly what your store does than keep guessing.

A simple test is to just modified $this->products_ordered_html in create_add_products. This one has the first column of the table as

qty X model

(instead of qty X).

That Software Guy. My Store: Zen Cart Support
Available for hire - See my ad in Services
Plugin Moderator, Documentation Curator, Chief Cook and Bottle-Washer.
Do you benefit from Zen Cart? Then please support the project.

4 Oct 2026, 7:35 PM
#52
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

Thanks, Scott — that detail lets me reproduce it exactly. I took a stock order.php, changed the first products_ordered_html cell to qty x model the way you described, and on that clean copy the preview does pick it up: the first cell comes out 1 x WHS0059. So the edit you described reads through here. If it isn't showing on your store, I'd genuinely like to see the exact lines you changed and confirm which build is actually loading — that'll tell me whether it's a difference in the edit itself or something in the install.

That said, you put your finger on the real issue in your very first reply, and I've come around to it. A preview works from a stored order, and the product list only ever gets built inside create_add_products() at checkout — so previewing a past order always means rebuilding that list rather than running the real thing, and a rebuild can match a clean edit but can't reliably track every way a store might change that code. Chasing each variation inside the plugin is a losing game, and I don't want to keep doing it.

The right fix is the one this thread arrived at. Stop rebuilding, and let the preview call the store's own code. I've put the core PR up — https://github.com/zencart/zencart/pull/8015 — it lifts that products_ordered / products_ordered_html block out of create_add_products() into an order method, with no change to what checkout produces, so a preview (or anything else) can build a stored order's lines by calling the store's actual method, formatted however it's written. If it lands, the preview runs your code directly, and this whole class of mismatch goes away.

I'd really value your review on it —you've had the shape of this right from the start.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com

4 Oct 2026, 7:41 PM
#53
swguy avatar

swguy

Administrator

Join Date:
Feb 2006
Location:
Tampa Bay, Florida
Posts:
10,720
Plugin Contributions:
56

Re: Preview Email

Thanks for your PR. I suggested going whole-hog and pulling out the entire customer email build so it lives in one place and can be re-done outside the order flow (i.e. by Preview Email).

That Software Guy. My Store: Zen Cart Support
Available for hire - See my ad in Services
Plugin Moderator, Documentation Curator, Chief Cook and Bottle-Washer.
Do you benefit from Zen Cart? Then please support the project.

6 Oct 2026, 10:13 PM
#54
dbltoe avatar

dbltoe

Totally Zenned

Join Date:
Jan 2004
Location:
N of San Antonio TX
Posts:
9,848
Plugin Contributions:
17

Re: Preview Email

Quick update for anyone following along: v3.0.4 is up on GitHub as a pre-release. The headline is a new, opt-in HTML (Exact) button on the Order Confirmation row. Rather than rebuilding the email, it runs your store's own order-email code — order::send_order_email() — for a recent order and captures exactly what would be sent, with the send switched off so no mail actually goes out. So it reflects whatever your store does to that email rather than a stock approximation. The normal preview is unchanged; the exact view is a separate button you press when you want it, and it's new enough that I'd treat it as a beta.

It pairs with the core PR this thread produced (zencart/zencart#8015): on a Zen Cart that has that read-only method, the product rows come straight from core too, so the whole email is the store's own code end to end. Until that lands, it fills the product rows from the stock layout and takes everything else from your live send path.

Pre-release (zip) here if you'd like to try it and tell me how it reads on your store — especially anyone whose order email is customized: https://github.com/dbltoe/Preview_Email/releases/tag/v3.0.4. The formal release and Library update follow once the core PR is settled.

Need a hand with Zen Cart? Hire the team at myZenCartZone.com for upgrades, repairs, and custom plugins.
Zen Cart Certified hosting at myZenCartHost.com