Repository navigation
Releases: appcoderikbal/crm-tech
Release list
v1.5.2 - line breaks preserved
Fixes single line breaks disappearing from sent email.
"Hi," and the sentence after it arrived on one line, as did "Best," and the name below it. Paragraphs separated correctly; line breaks within a paragraph did not survive at all.
The cause was a guard added alongside the earlier paragraph fix: it skipped wpautop whenever any block-level tag was present. A newline inside a <p> - exactly what the editor stores for Shift+Enter, and what pasted text produces - was then left for HTML to collapse.
That guard was protecting against nothing. wpautop inserts neither <p> nor <br> into a table, leaves existing paragraphs alone, and is idempotent. It now runs on every fragment; only a complete HTML document is skipped.
Existing campaigns are fixed without re-saving, since this applies when the message is rendered.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.5.1 - placeholder insert buttons
Buttons that insert personalisation placeholders.
The campaign editor now has an Insert: row above the content box - First name, Last name, Full name, Email, Company, Website, Country. Clicking one drops the correct token in at your cursor.
Typing {{first_name}} by hand meant remembering the exact spelling, and a near miss fails silently: an unrecognised placeholder is left untouched and goes out as literal braces.
Works in both the Visual and Code tabs - TinyMCE owns an iframe in one and the other is a plain textarea, so the active mode decides where the token goes.
On line breaks
You never need to type <br>. In the Visual tab, Enter starts a new paragraph and Shift+Enter makes a single line break. The hint under the editor now says so - it previously listed placeholder names instead, which read as though hand-written HTML was expected.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.5.0 - personalisation inside links
Placeholders now work inside link URLs.
https://example.com/book?fname={{first_name}}&lname={{last_name}}&e={{email}}
becomes, per recipient:
https://example.com/book?fname=Anne%20Marie&lname=O%27Brien&e=anne%40test.com
Values are percent-encoded, not HTML-escaped - a name containing a space, an apostrophe or an ampersand would otherwise break out of its query parameter.
Available: {{first_name}}, {{last_name}}, {{full_name}}, {{email}}, {{company_name}}, {{website}}, {{country}}.
Click tracking still works
Previously a link containing a placeholder was silently excluded from tracking. It is now tracked as a template, with the real destination resolved at the moment of the click - the only point at which the recipient is known.
Safety
Contact data arrives by CSV and is not trusted to decide where a link points. A placeholder in the host is refused outright, and a resolved destination whose host differs from the template's falls back to the template. The open-pixel and unsubscribe tokens are still never registered as links.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.4.3 - footer permission line off by default
The permission line is now off by default.
v1.4.2 made it configurable but left the sentence as the default, so any site that had not gone and cleared the field kept showing it. The setting existed, but nothing changed for anyone.
The footer is now the unsubscribe link and the postal address alone. If you want the sentence back, type it into Settings -> Email layout -> Permission line - the field suggests it as placeholder text.
Unchanged: the unsubscribe link, which is mandatory, and the postal address, which US commercial email requires.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.4.2 - configurable unsubscribe footer
The footer can now be just the unsubscribe link.
The permission sentence above it was hardcoded. Both it and the link wording are now settings under Settings -> Email layout:
- Permission line - leave blank to show nothing but the link
- Unsubscribe link text - defaults to "Unsubscribe"
Leaving the permission line blank removes the element entirely rather than leaving an empty one that still contributes spacing.
What stays
The link itself is mandatory, and a blank label falls back to "Unsubscribe". An unlabelled unsubscribe is an invisible one - a CAN-SPAM problem, and the fastest way to be reported as spam instead.
The postal address is also untouched: US commercial email requires one, and dropping it is not a styling decision. Set it under Settings if you have not.
Both the HTML and plain-text parts take the same options, so the two halves of a message cannot disagree about how to unsubscribe.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.4.1 - centred email container
Emails now go out in a centred container instead of edge-to-edge.
The message was sent as a bare HTML fragment, so it stretched to whatever width the reading pane happened to be - very long lines on a desktop client, and an amateur look beside anything built from a template.
It is now wrapped in the structure email clients have supported reliably for two decades: an outer table at full width carrying the page background, and an inner table capped at 600px centred inside it. Tables rather than flexbox because Outlook renders through Word, and inline styles rather than a stylesheet because Gmail strips <style> blocks.
Configurable under Settings -> Email layout
- Centred container on or off
- Content width (default 600px)
- Page background and card background, as hex colours
- Corner radius
Content that is already a complete HTML document is left alone rather than nested inside a second shell, so a pasted template keeps its own layout.
Also fixes two regular expressions whose word boundaries had been written as a literal backspace byte, which made the structured-content guard match nothing - a table layout was being passed through wpautop on every render.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.4.0 - pasted layouts and sidebar highlighting
Paste a formatted email and keep its layout
Copying a message out of Gmail and pasting it into the editor now keeps the design, with no hand-written CSS. Use the Visual tab.
The sanitiser already allowed inline styles and tables, but dropped bgcolor on table and tr, dir, and the properties a pasted design leans on - display, border-radius, text-transform among them. Buttons lost their rounding, backgrounds vanished, and the result needed rebuilding by hand.
Scripts and event handlers are still stripped. Widening what a layout may use does not widen what it may execute.
The sidebar stays highlighted
Opening a screen reachable by URL but not listed in the menu - the campaign editor, a report, list members, import, the audit log - left the whole sidebar inactive, with no indication of where you were. Those screens now light up the item they belong under, with Techzapp CRM open.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.3.5 - paragraph formatting preserved
Fixes emails arriving as one run-on block instead of paragraphs.
HTML collapses whitespace, and the editor's Text tab - along with anything pasted into it - stores plain newlines. So the blank lines between paragraphs meant nothing by the time the message was built. WordPress solves exactly this for post content with wpautop; the campaign body never went through it.
Now it does, on the same terms:
- blank lines become separate paragraphs
- single newlines become line breaks
- content that already has
<p>,<div>or a table layout is left untouched, so hand-built HTML email keeps its structure
Applied when rendering as well as when saving, so campaigns already stored in the collapsed form come out correctly without being edited and re-saved.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.3.4 - honest send reporting
Stops the report claiming messages were sent when they were not.
A campaign run with the log transport reported "Accepted by SES: 2" and an otherwise clean report - nothing failed, nothing queued. Nothing had been sent: the log transport writes each message to a file and returns success, which is right for a staging site and indistinguishable from a real send anywhere a count appears.
"Accepted by SES" was also untrue - SES never saw the message - and it is the first number anyone reads after sending.
The report now leads with a warning when no mail is leaving the server, names the TECHZAPP_CRM_MAIL_TRANSPORT constant when that is what is forcing it rather than the setting, and relabels the tile to Written to the log / NOT sent to anyone. The campaigns index and the live sending panel say the same, since either could be the screen you are looking at.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.
v1.3.3 - assigning contacts to a list works
Fixes "That link or form has expired" when assigning contacts to a list.
WP_List_Table::display() emits its own wp_nonce_field('bulk-...') for the bulk actions it manages. On Contacts that table sits inside the plugin's form and renders after it, so the page carried two inputs named _wpnonce. A browser posts both, PHP keeps the last, and the plugin then checked the list table's value against its own action. It could never match - the form was valid every time.
Nonces now travel in techzapp_crm_nonce, which core does not use, so the two cannot collide. Fixed at the single point every form and action link goes through rather than screen by screen: the same clash was already waiting on List members, and would have hit any future screen combining a list table with a plugin form.
Earlier tests missed this because they called the handler directly with a hand-built nonce, never rendering the form. The new test renders the real Contacts screen and posts what a browser posts - list table nonce included - then confirms the contacts actually land on the list. A forged nonce is still rejected.
No schema change.
Tested up to: 6.8
Installing
Download techzapp-crm.zip below. Do not use the auto-generated source archives - they omit vendor/ and the plugin will not load.