ver-1.0.7
First fork the https://turtleengr.github.io/WP-turtle-template-form-knitter/ repository.
Install these packages
emacs (org-mode) - if you want to edit
the *.org filesgitgit-flow - optionalmakepandoc - convert org files to markdown
formatperl - for the pod2* programs. Needed
by org2html.shphppod2markdown - libpod-markdown-perl
pkgpod2pdf - optionalsedtidy - needed by org2html.shzipThe scripts in ./bin and are used in Makefile
bin/org2html.sh - convert org files to
htmlbin/rm-trailing-sp - an convert tabs to
spacesbin/pre-commit - enforces some basic
formatting (see [gitproj "hook"])Copy bin/pre-commit to WP-turtle-template-form-knitter/.git/hooks
./bin/gitconfig to
./.git/config[alias]
br = branch
ci = commit
co = checkout
df = diff
st = status -s
[gitproj "hook"]
verbose = true
pre-commit-enabled = true
check-file-names = true
check-in-raw = true
check-whitespace = true
check-for-tabs = true
tab-include-list = .sh .inc .pod .md .php
tab-exclude-list = Makefile .phar
check-for-big-files = true
binary-file-size = 40k
git flow initDefine the location of where the plugin's zip file will be saved.
mServer = example.com
mPubDev = /rel/development/$(mProj)
mPubRel = /rel/released/$(mProj)
For details on how this code was generated by Claude, with references to the existing plugins it needs, see the files in the spec/ directory. Note: this plugin was initially named "contact-2-post."
The "save image upload" code was referenced from https://wordpress.org/plugins/store-file-uploads-for-contact-form-7/ by Mircea N. (version 1.3.0). That code was then enhanced to normalize the image file names and to prevent overwriting existing images.
The post's author is the user with the site's admin_email.
If publish-date is valid, the date is fixed (post_date_gmt is set), so publishing keeps it; a
future date makes the post "Scheduled". If there is no valid
publish-date, the post date "floats": it is set when the post is
published.
ttfk_fOnBeforeCf7SendMail() is hooked
to wpcf7_before_send_mail. It saves each
uploaded image with ttfk_fCreateAttachment(), and collects the attachment
IDs with ttfk_fSaveAttachId().
Upload error messages are saved with ttfk_fErrorLog(). Calling ttfk_fErrorLog() with no argument returns the list.
The list is a static variable, and each
form submission is one PHP request with its own memory, so a post only
gets the errors from its own submission, even when several people
submit at the same time. The messages are not kept after the request
ends.
These filters can change how uploads are saved: ttfk_fCreateAttachment_file_name (the destination
path), ttfk_should_skip_save_attachment_to_media_library
(return true to only copy the file), and ttfk_before_insert_attachment (the attachment
array).
Flamingo saves the message in wpcf7_submit, then fires wpcf7_after_flamingo with flamingo_inbound_id. This plugin hooks that action,
so no post is made when Flamingo does not store the message
(do_not_store: true), or for spam.
The form's "create_post" and
"post_template" Additional Settings are
read with WPCF7_ContactForm::is_true()
and pref().
The template page is split with parse_blocks(). Attribute blocks are removed,
{field} is replaced only in the block HTML (not in the
block comment JSON), then serialize_blocks().
Call tree of the functions in turtle-template-form-knitter.php, in the order they run when a Contact Form 7 form is submitted.
Indent = "calls". Functions without a ttfk_ prefix are WordPress, CF7, Flamingo, or PHP functions, listed only where they matter to the flow.
(recursive) marks a function that calls itself.
plugins_loaded (anonymous function)
add_action admin_notices -> error notice; no hooks below are added.
add_filter plugin_row_meta -> ttfk_fMetaLinks (always added)
add_action admin_init -> ttfk_fMakeAttachMeta (always added)
wpcf7_enqueue_scripts
wp_enqueue_script js/ttfk-paste.js (cleans pasted HTML in textareas; shows ttfk_errors popup)
ttfk_fOnBeforeCf7SendMail
wp_check_filetype, wp_get_image_mime (image checks)
ttfk_fErrorLog (on any failure)
ttfk_fNormalizeFileName
apply_filters ttfk_fCreateAttachment_file_name
ttfk_fUniqueFileName
copy() to uploads dir
apply_filters ttfk_should_skip_save_attachment_to_media_library
apply_filters ttfk_before_insert_attachment
wp_insert_attachment (on failure: ttfk_fErrorLog, wp_delete_file)
add_post_meta _ttfk_need_meta (image sizes are made later, see 3)
ttfk_fSaveAttachId (stores the ID in a static list)
ttfk_fAfterFlamingo
ttfk_fErrorLog (not set / page not found)
parse_blocks(template)
for each top-level block:
ttfk_fReplaceFields (plain text, see 2.4)
ttfk_fSplitParagraph (core/paragraph only)
ttfk_fValueToString
ttfk_fCleanHtml
ttfk_fReplaceFields (HTML, see 2.4)
ttfk_fReplaceFields (HTML, see 2.4)
ttfk_fReplaceInBlock (each inner block)
ttfk_fErrorLog (ATTR-END not found)
ttfk_fGetAdminId (post author)
serialize_blocks
ttfk_fParseDate (publish-date)
wp_insert_post (status pending) (on failure: ttfk_fErrorLog)
ttfk_fGetTermIdList (categories, then tags)
ttfk_fParseDate, ttfk_fParseTime (expire-date, expire-time)
for each saved attachment ID:
ttfk_fFeedbackResponse
ttfk_fReplaceFields ({field} -> value, single pass)
ttfk_fCleanHtml (only for textarea fields)
no tags: esc_html, nl2br, encode [ ]
has tags:
ttfk_fHtmlToBlocks
ttfk_fTidyInline
ttfk_fMakeBlock
ttfk_fNodeHtml
ttfk_fTidyInline
ttfk_fMakeBlock (core/list-item, core/list)
admin_init (any admin page)
get_posts (attachments with meta _ttfk_need_meta)
delete_post_meta _ttfk_need_meta
wp_generate_attachment_metadata, wp_update_attachment_metadata
plugin_row_meta (Plugins page)
Each function only depends on functions above it in this list.
ttfk_fOnBeforeCf7SendMail (24)
ttfk_fAfterFlamingo (1, 2, 25)
ttfk_fFeedbackResponse (1)
ttfk_fEnqueuePasteScript
ttfk_fMetaLinks
ttfk_fMakeAttachMeta
This outline traces a submission through three hooks, in the order they run in the same request:
wpcf7_before_send_mail: saves the
uploaded images.wpcf7_after_flamingo: builds the
pending post from the template page.wpcf7_feedback_response: adds any saved
errors to the reply sent to the browser.The outline also has:
a short setup section (plugins_loaded,
plus the script loaded when the form page is shown);
separate sections for the two shared helpers, ttfk_fReplaceFields and the HTML-to-blocks functions;
a numbered list of every function with its dependencies listed before it, so the simplest functions come first.
All 31 ttfk_ functions in
turtle-template-form-knitter.php are reachable from a hook. Three of them
call themselves: ttfk_fReplaceInBlock,
ttfk_fListBlock and ttfk_fNodeHtml.
test/setup.php and test/submit.php are run with wp-cli on a test site with all the plugins active. They are not in the dist zip.
wp eval-file test/setup.php
wp eval-file test/submit.php full attach # post, attachment, expiry
wp eval-file test/submit.php notitle # title UNDEFINED
wp eval-file test/submit.php nostore # no post
wp eval-file test/submit.php nocreate # no post
wp eval-file test/submit.php badslug # no post, error_log
wp eval-file test/submit.php full spam # no post
wp post list --post_type=post --post_status=pending