{"id":305874,"date":"2026-05-09T00:50:01","date_gmt":"2026-05-09T00:50:01","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/shed-form\/"},"modified":"2026-05-09T01:42:05","modified_gmt":"2026-05-09T01:42:05","slug":"shed-form","status":"publish","type":"plugin","link":"https:\/\/co.wordpress.org\/plugins\/shed-form\/","author":23489683,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.6.22","stable_tag":"1.6.22","tested":"6.9.4","requires":"6.0","requires_php":"8.1","requires_plugins":null,"header_name":"Shed Form","header_author":"WP Shed","header_description":"\u78ba\u8a8d\u753b\u9762\u4ed8\u304d\u30fb\u55b6\u696d\u30e1\u30fc\u30eb\u81ea\u52d5\u30d6\u30ed\u30c3\u30af\u5bfe\u5fdc\u306e\u304a\u554f\u3044\u5408\u308f\u305b\u30d5\u30a9\u30fc\u30e0\u30d7\u30e9\u30b0\u30a4\u30f3","assets_banners_color":"434952","last_updated":"2026-05-09 01:42:05","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wpshed.jp\/plugins\/shed-form\/","header_author_uri":"https:\/\/wpshed.jp","rating":0,"author_block_rating":0,"active_installs":0,"downloads":55,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.6.21":{"tag":"1.6.21","author":"teamstaccato","date":"2026-05-09 00:49:40"},"1.6.22":{"tag":"1.6.22","author":"teamstaccato","date":"2026-05-09 01:42:05"}},"upgrade_notice":{"1.6.21":"<p>Internal code quality improvements for WordPress.org compliance. Data migration runs automatically on update \u2014 no action required.<\/p>","1.6.15":"<p>All internal prefixes have been renamed from wsf_\/WSF_ to shedform_\/SHEDFORM_. Database tables and options are migrated automatically on update.<\/p>","1.6.0":"<p>This version adds GPL-2.0+ licensing and internationalization support. NG phrase updates are now manual (button in settings) instead of automatic cron.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3526984,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3526984,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3526984,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3526984,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.6.21","1.6.22"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3526942,"resolution":"1","location":"assets","locale":""},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3526942,"resolution":"2","location":"assets","locale":""},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3526942,"resolution":"3","location":"assets","locale":""},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3526942,"resolution":"4","location":"assets","locale":""},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3526942,"resolution":"5","location":"assets","locale":""},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3526942,"resolution":"6","location":"assets","locale":""}},"screenshots":{"1":"Form editor \u2014 drag &amp; drop field arrangement","2":"Frontend form display with confirmation screen","3":"Submission history with status management","4":"Email log with resend functionality","5":"Turnstile and spam protection settings","6":"NG phrase management"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[358,267,361,5622,2419],"plugin_category":[41,42],"plugin_contributors":[262385],"plugin_business_model":[],"class_list":["post-305874","plugin","type-plugin","status-publish","hentry","plugin_tags-contact-form","plugin_tags-email","plugin_tags-form","plugin_tags-japanese","plugin_tags-spam-protection","plugin_category-communication","plugin_category-contact-forms","plugin_contributors-teamstaccato","plugin_committers-teamstaccato"],"banners":{"banner":"https:\/\/ps.w.org\/shed-form\/assets\/banner-772x250.png?rev=3526984","banner_2x":"https:\/\/ps.w.org\/shed-form\/assets\/banner-1544x500.png?rev=3526984","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/shed-form\/assets\/icon-128x128.png?rev=3526984","icon_2x":"https:\/\/ps.w.org\/shed-form\/assets\/icon-256x256.png?rev=3526984","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-1.png?rev=3526942","caption":"Form editor \u2014 drag &amp; drop field arrangement"},{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-2.png?rev=3526942","caption":"Frontend form display with confirmation screen"},{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-3.png?rev=3526942","caption":"Submission history with status management"},{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-4.png?rev=3526942","caption":"Email log with resend functionality"},{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-5.png?rev=3526942","caption":"Turnstile and spam protection settings"},{"src":"https:\/\/ps.w.org\/shed-form\/assets\/screenshot-6.png?rev=3526942","caption":"NG phrase management"}],"raw_content":"<!--section=description-->\n<p>Shed Form is a WordPress contact form plugin specifically designed for Japanese websites. It features a 3-step submission flow (Input \u2192 Confirmation \u2192 Complete), a visual form builder, built-in spam protection, and full submission history management.<\/p>\n\n<p><strong>Key Features:<\/strong><\/p>\n\n<ul>\n<li><strong>3-Step Submission Flow<\/strong> \u2014 Input \u2192 Confirmation \u2192 Complete, the standard expected by Japanese website visitors<\/li>\n<li><strong>Visual Form Builder<\/strong> \u2014 Drag &amp; drop field arrangement with 12 field types<\/li>\n<li><strong>Spam Protection<\/strong> \u2014 Cloudflare Turnstile integration, NG phrase scoring with silent blocking, IP blocking, and rate limiting<\/li>\n<li><strong>Submission History<\/strong> \u2014 View, search, manage status, export to CSV, and review blocked submissions<\/li>\n<li><strong>Email Logging<\/strong> \u2014 Full log of sent emails with one-click resend for failed deliveries<\/li>\n<li><strong>Multiple Layouts<\/strong> \u2014 Table, Stack, Inline, and DL layouts with responsive support<\/li>\n<li><strong>Form Scheduling<\/strong> \u2014 Set start\/end dates to automatically open and close forms<\/li>\n<li><strong>Japanese Validation<\/strong> \u2014 Hiragana, Katakana, postal code, and Japanese phone number validation built in<\/li>\n<\/ul>\n\n<p><strong>Supported Field Types:<\/strong><\/p>\n\n<p>text, textarea, email, tel, number, select, radio, checkbox, consent, date, file, hidden<\/p>\n\n<h4>\u65e5\u672c\u8a9e\u306e\u8aac\u660e<\/h4>\n\n<p>Shed Form \u306f\u3001\u65e5\u672c\u306e Web \u30b5\u30a4\u30c8\u306b\u7279\u5316\u3057\u305f WordPress \u7528\u304a\u554f\u3044\u5408\u308f\u305b\u30d5\u30a9\u30fc\u30e0\u30d7\u30e9\u30b0\u30a4\u30f3\u3067\u3059\u3002<\/p>\n\n<p><strong>\u4e3b\u306a\u6a5f\u80fd:<\/strong><\/p>\n\n<ul>\n<li>\u78ba\u8a8d\u753b\u9762\u4ed8\u304d3\u30b9\u30c6\u30c3\u30d7\u9001\u4fe1\uff08\u5165\u529b\u2192\u78ba\u8a8d\u2192\u5b8c\u4e86\uff09<\/li>\n<li>\u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7\u3067\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u914d\u7f6e\u3059\u308b\u30d5\u30a9\u30fc\u30e0\u30d3\u30eb\u30c0\u30fc<\/li>\n<li>Cloudflare Turnstile \u9023\u643a\u3001NG\u30d5\u30ec\u30fc\u30ba\u30b9\u30b3\u30a2\u30ea\u30f3\u30b0\u3001IP\u30d6\u30ed\u30c3\u30af\u3001\u30ec\u30fc\u30c8\u5236\u9650\u306b\u3088\u308b\u30b9\u30d1\u30e0\u5bfe\u7b56<\/li>\n<li>\u9001\u4fe1\u5c65\u6b74\u7ba1\u7406\uff08\u691c\u7d22\u30fb\u30b9\u30c6\u30fc\u30bf\u30b9\u7ba1\u7406\u30fbCSV\u51fa\u529b\u30fb\u30d6\u30ed\u30c3\u30af\u6e08\u307f\u78ba\u8a8d\uff09<\/li>\n<li>\u30e1\u30fc\u30eb\u9001\u4fe1\u5c65\u6b74\u3068\u518d\u9001\u4fe1\u6a5f\u80fd<\/li>\n<li>4\u7a2e\u985e\u306e\u30ec\u30a4\u30a2\u30a6\u30c8\uff08\u30c6\u30fc\u30d6\u30eb\u30fb\u30b9\u30bf\u30c3\u30af\u30fb\u30a4\u30f3\u30e9\u30a4\u30f3\u30fbDL\u578b\uff09<\/li>\n<li>\u30d5\u30a9\u30fc\u30e0\u6709\u52b9\u671f\u9650\u8a2d\u5b9a<\/li>\n<li>\u3072\u3089\u304c\u306a\u30fb\u30ab\u30bf\u30ab\u30ca\u30fb\u90f5\u4fbf\u756a\u53f7\u30fb\u65e5\u672c\u306e\u96fb\u8a71\u756a\u53f7\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3<\/li>\n<\/ul>\n\n<h3>Third-Party Services<\/h3>\n\n<p>This plugin connects to external services in the following cases:<\/p>\n\n<h4>Cloudflare Turnstile<\/h4>\n\n<p>When Turnstile spam protection is enabled in the form settings, this plugin sends verification requests to Cloudflare's API during form submission.<\/p>\n\n<ul>\n<li>Service: <a href=\"https:\/\/www.cloudflare.com\/products\/turnstile\/\">Cloudflare Turnstile<\/a><\/li>\n<li>Privacy Policy: <a href=\"https:\/\/www.cloudflare.com\/privacypolicy\/\">https:\/\/www.cloudflare.com\/privacypolicy\/<\/a><\/li>\n<li>Terms of Service: <a href=\"https:\/\/www.cloudflare.com\/website-terms\/\">https:\/\/www.cloudflare.com\/website-terms\/<\/a><\/li>\n<li>Data sent: Turnstile token (generated client-side), site key, user IP address<\/li>\n<li>When: Only when Turnstile is enabled and a form is submitted<\/li>\n<\/ul>\n\n<h4>ZipCloud (Postal Code Lookup)<\/h4>\n\n<p>When a form includes a postal code field with auto-fill enabled, this plugin sends the entered postal code to the ZipCloud API to retrieve the corresponding address.<\/p>\n\n<ul>\n<li>Service: <a href=\"https:\/\/zipcloud.ibsnet.co.jp\/\">ZipCloud<\/a><\/li>\n<li>Privacy Policy: <a href=\"https:\/\/zipcloud.ibsnet.co.jp\/\">https:\/\/zipcloud.ibsnet.co.jp\/<\/a><\/li>\n<li>Terms of Service: <a href=\"https:\/\/zipcloud.ibsnet.co.jp\/\">https:\/\/zipcloud.ibsnet.co.jp\/<\/a><\/li>\n<li>Data sent: Postal code (zip code) entered by the user<\/li>\n<li>When: Each time a user enters a postal code in a field with auto-fill enabled<\/li>\n<li>Note: This is a free, publicly available Japanese postal code lookup service. No authentication or personal data is required.<\/li>\n<\/ul>\n\n<h4>NG Phrase Cloud Update<\/h4>\n\n<p>When the administrator manually clicks the \"Update from Cloud\" button in the plugin settings, this plugin fetches the latest spam phrase list from the WP Shed server.<\/p>\n\n<ul>\n<li>Service: <a href=\"https:\/\/wpshed.jp\/\">WP Shed<\/a><\/li>\n<li>Privacy Policy: <a href=\"https:\/\/wpshed.jp\/privacy\/\">https:\/\/wpshed.jp\/privacy\/<\/a><\/li>\n<li>Terms of Service: <a href=\"https:\/\/wpshed.jp\/legal\/\">https:\/\/wpshed.jp\/legal\/<\/a><\/li>\n<li>Data sent: None (one-way download only)<\/li>\n<li>When: Only when the administrator explicitly clicks the update button<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to the <code>\/wp-content\/plugins\/<\/code> directory, or install directly through the WordPress plugin screen.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress.<\/li>\n<li>Go to <strong>Shed Form \u2192 Form List<\/strong> to create your first form.<\/li>\n<li>Copy the generated shortcode (e.g. <code>[shedform_form id=\"1\"]<\/code>) and paste it into any page or post.<\/li>\n<li>(Recommended) Set up Cloudflare Turnstile for spam protection under <strong>Shed Form \u2192 Settings<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20many%20forms%20can%20i%20create%3F\"><h3>How many forms can I create?<\/h3><\/dt>\n<dd><p>There is no limit. You can create as many forms as you need.<\/p><\/dd>\n<dt id=\"can%20i%20place%20multiple%20forms%20on%20the%20same%20page%3F\"><h3>Can I place multiple forms on the same page?<\/h3><\/dt>\n<dd><p>Yes. Use different shortcode IDs, e.g. <code>[shedform_form id=\"1\"]<\/code> and <code>[shedform_form id=\"2\"]<\/code>.<\/p><\/dd>\n<dt id=\"how%20does%20the%20spam%20blocking%20work%3F\"><h3>How does the spam blocking work?<\/h3><\/dt>\n<dd><p>The plugin scores submission content against NG (blocked) phrases. When the score exceeds a threshold, the submission is silently blocked \u2014 the user sees the completion screen, but no email is sent to the administrator. Blocked submissions can be reviewed in the Submission History under the \"Blocked\" tab.<\/p><\/dd>\n<dt id=\"does%20this%20plugin%20support%20cloudflare%20turnstile%3F\"><h3>Does this plugin support Cloudflare Turnstile?<\/h3><\/dt>\n<dd><p>Yes. Create a Turnstile site in your Cloudflare dashboard, enter the Site Key and Secret Key in <strong>Shed Form \u2192 Settings \u2192 Turnstile<\/strong>, and enable it per form in the form editor.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20a%20form%20reaches%20its%20expiration%20date%3F\"><h3>What happens when a form reaches its expiration date?<\/h3><\/dt>\n<dd><p>The form displays a custom message (HTML editable) and rejects all submissions, including direct POST requests.<\/p><\/dd>\n<dt id=\"can%20i%20export%20submission%20data%3F\"><h3>Can I export submission data?<\/h3><\/dt>\n<dd><p>Yes. Go to <strong>Shed Form \u2192 Submission History<\/strong> and click the CSV export button.<\/p><\/dd>\n<dt id=\"the%20admin%20notification%20email%20is%20not%20arriving.%20what%20should%20i%20check%3F\"><h3>The admin notification email is not arriving. What should I check?<\/h3><\/dt>\n<dd><ol>\n<li>Check <strong>Shed Form \u2192 Email Log<\/strong> \u2014 is the email status \"sent\" or \"failed\"?<\/li>\n<li>If blocked, check the \"Blocked\" tab in Submission History.<\/li>\n<li>If \"failed\", check the error message and consider installing an SMTP plugin (e.g. WP Mail SMTP).<\/li>\n<li>Check your spam\/junk folder.<\/li>\n<\/ol><\/dd>\n<dt id=\"is%20there%20a%20paid%20version%3F\"><h3>Is there a paid version?<\/h3><\/dt>\n<dd><p>Shed Form itself is completely free. Optional paid add-ons (MW WP Form Importer, Export\/Import, Performance Profiler) are available at <a href=\"https:\/\/wpshed.jp\/\">wpshed.jp<\/a>.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.6.22<\/h4>\n\n<ul>\n<li>Fix: Corrected Privacy Policy URL for WP Shed NG Phrase service in Third-Party Services section.<\/li>\n<\/ul>\n\n<h4>1.6.21<\/h4>\n\n<ul>\n<li>Code quality: Renamed JS global variable <code>wsfPreview<\/code> to <code>shedformPreview<\/code> to comply with WordPress.org prefix requirements.<\/li>\n<li>Code quality: Renamed <code>wpshed_<\/code> option keys for NG phrase cache to <code>shedform_<\/code> prefix (shedform_default_phrases_cache, shedform_phrases_cache_version, shedform_phrases_cache_updated). Migration runs automatically on update.<\/li>\n<li>Code quality: Removed obsolete <code>wpshed_license_key<\/code> \/ <code>wpshed_license_cache<\/code> option writes from migration function (no longer used after updater removal in v1.6.19).<\/li>\n<li>Code quality: Wrapped hardcoded <code>\u540c\u610f\u3059\u308b<\/code> strings with <code>__()<\/code> for i18n in 3 locations.<\/li>\n<li>Code quality: Added phpcs:disable NonPrefixedVariableFound to page-settings.php and form-complete.php template files.<\/li>\n<li>Disclosure: Added Terms of Service URLs for ZipCloud and WP Shed NG Phrase API in Third-Party Services section.<\/li>\n<\/ul>\n\n<h4>1.6.20<\/h4>\n\n<ul>\n<li>Code quality: Added phpcs:disable for NonPrefixedVariableFound in all template files (view templates included from callbacks \u2014 variables are scoped to each template, not global API).<\/li>\n<li>Code quality: Added PluginCheck.Security.DirectDB.UnescapedDBParameter phpcs:ignore to RENAME TABLE migration query ($old_table\/$new_table are built from $wpdb-&gt;prefix + hardcoded map, no user input).<\/li>\n<\/ul>\n\n<h4>1.6.19<\/h4>\n\n<ul>\n<li>Changed: Removed custom auto-updater (WPShed_Updater) \u2014 plugin is distributed exclusively via WordPress.org.<\/li>\n<\/ul>\n\n<h4>1.6.18<\/h4>\n\n<ul>\n<li>Fixed: Undefined method Shedform_Field_Manager::get_fields() in ajax_restore_submission() \u2014 changed to get_by_form() (caused fatal error on \"process as normal\" action).<\/li>\n<li>Code quality: Wrap consent confirmation label with esc_html__() for i18n.<\/li>\n<li>Code quality: Wrap CSV export status labels with __() for i18n.<\/li>\n<li>Code quality: Add esc_attr() to nav-tab-active and display:none inline style echoes in form editor.<\/li>\n<\/ul>\n\n<h4>1.6.17<\/h4>\n\n<ul>\n<li>Security: Added nonce verification to mail log detail view (auto-read-mark access now CSRF-protected).<\/li>\n<li>Security: \"\u8a73\u7d30\" list links in mail logs now use wp_nonce_url() to include nonce parameter.<\/li>\n<li>Security: Cross-link from mail log detail to submission detail now includes nonce for check_admin_referer() on the submissions page.<\/li>\n<\/ul>\n\n<h4>1.6.16<\/h4>\n\n<ul>\n<li>Security: Added nonce verification to submission detail view (auto-read-mark state change now CSRF-protected).<\/li>\n<li>Security: Sanitize validation and extras JSON field values on save (rule \u2192 sanitize_key, message\/param \u2192 sanitize_text_field, _url keys \u2192 esc_url_raw, regex param validated by shedform_validate_regex_phrase).<\/li>\n<\/ul>\n\n<h4>1.6.15<\/h4>\n\n<ul>\n<li>Changed: All function, class, constant, hook, option, and table prefixes renamed from wsf_\/WSF_ to shedform_\/SHEDFORM_\/Shedform_ to meet WordPress.org 4-character prefix requirement.<\/li>\n<li>Migration: Existing wp_wsf_* database tables automatically renamed to wp_shedform_* on upgrade (data preserved).<\/li>\n<li>Migration: Existing wsf_* WordPress options automatically migrated to shedform_* on upgrade.<\/li>\n<\/ul>\n\n<h4>1.6.14<\/h4>\n\n<ul>\n<li>Changed: Credit display changed to opt-in (default OFF) \u2014 removes Trialware violation. Setting added to Shed Form \u2192 Settings.<\/li>\n<li>Changed: Upload directory moved from wp-content\/shedform-uploads\/ to wp-content\/uploads\/shed-form\/ (wp_upload_dir() based). Automatic migration for existing users.<\/li>\n<li>Fixed: Inline  blocks in page-mail-logs.php replaced with wp_add_inline_script()<\/li>\n<li>Security: options JSON now sanitized recursively with sanitize_text_field(). validation\/extras validated by json_decode() + key whitelist (regex patterns preserved).<\/li>\n<li>Disclosure: Added ZipCloud postal code API to Third-Party Services in readme.txt<\/li>\n<li>Updated: SortableJS 1.15.6 \u2192 1.15.7<\/li>\n<li>Fixed: file_put_contents() replaced with WP_Filesystem API for .htaccess and index.php creation<\/li>\n<\/ul>\n\n<h4>1.6.13<\/h4>\n\n<ul>\n<li>Code quality: Added phpcs:ignore for DirectQuery\/NoCaching\/SchemaChange\/UnescapedDBParameter on migration ALTER TABLE and INFORMATION_SCHEMA queries in shed-form.php<\/li>\n<li>Code quality: Added Squiz.PHP.DiscouragedFunctions.Discouraged to ini_set phpcs:ignore in class-shedform-validator.php (restore-after-finally blocks)<\/li>\n<li>Code quality: Added NoCaching to $wpdb-&gt;update() phpcs:ignore in class-shedform-admin.php<\/li>\n<li>Code quality: Added UnescapedDBParameter to CSV export batch-query phpcs:ignore lines in class-shedform-admin.php<\/li>\n<li>Code quality: Added UnfinishedPrepare to $wpdb-&gt;prepare() with spread-operator placeholder in class-shedform-admin.php<\/li>\n<li>Code quality: Added InputNotSanitized to phpcs:disable block in sanitize_input_for_display() in class-shedform-form.php<\/li>\n<li>Code quality: Added NonceVerification.Recommended phpcs:ignore to read-only list filter GET params in page-submissions.php<\/li>\n<li>Code quality: Added InterpolatedNotPrepared and moved ReplacementsWrongNumber phpcs:ignore to correct lines in page-submissions.php<\/li>\n<\/ul>\n\n<h4>1.6.12<\/h4>\n\n<ul>\n<li>Code quality: Added phpcs:ignore\/disable annotations for PluginCheck.Security.DirectDB.UnescapedDBParameter across all DB-heavy files \u2014 table names from $wpdb-&gt;prefix are safe<\/li>\n<li>Code quality: Added phpcs:disable blocks to manager\/template classes (field-manager, form-manager, row-manager, settings) for repetitive DirectQuery\/NoCaching\/InterpolatedNotPrepared false positives<\/li>\n<li>Code quality: Added phpcs:disable\/enable blocks to sanitize_input() \/ sanitize_input_for_display() for NonceVerification.Missing \u2014 nonce verified by calling functions<\/li>\n<li>Code quality: Fixed remaining ini_set (restore in finally blocks) and set_error_handler phpcs:ignore annotations in shed-form.php and class-shedform-validator.php<\/li>\n<\/ul>\n\n<h4>1.6.11<\/h4>\n\n<ul>\n<li>Code quality: Removed deprecated load_plugin_textdomain() call (auto-loaded since WordPress 6.7)<\/li>\n<li>Code quality: Added missing wp_unslash() to $_GET accesses in admin pages and mail-logs template<\/li>\n<li>Code quality: Added sanitize_url() to HTTP_REFERER handling in template helpers<\/li>\n<li>Code quality: Added phpcs:ignore annotations for justified WPCS false positives (DirectQuery on custom tables, NonceVerification on read-only admin GET params, ini_set\/set_error_handler for ReDoS protection)<\/li>\n<\/ul>\n\n<h4>1.6.10<\/h4>\n\n<ul>\n<li>Version bump for mobile performance investigation testing<\/li>\n<\/ul>\n\n<h4>1.6.9<\/h4>\n\n<ul>\n<li>Added: Field description \u2014 each field can now have supplementary helper text displayed below the input<\/li>\n<\/ul>\n\n<h4>1.6.8<\/h4>\n\n<ul>\n<li>Code quality: Removed wp_kses_post() from JSON fields (options\/validation\/extras) in ajax_save_field() \u2014 prevents silent corruption of regex patterns containing angle brackets<\/li>\n<li>Code quality: Nonce sanitization changed from sanitize_key() to sanitize_text_field() (WPCS compliance)<\/li>\n<li>Code quality: Replaced raw $_GET['status'] access with already-sanitized $filter_status variable in submissions page<\/li>\n<\/ul>\n\n<h4>1.6.7<\/h4>\n\n<ul>\n<li>Security: Session token now stores form_id \u2014 token from form A can no longer be used to complete form B<\/li>\n<li>Security: Session token destroyed immediately after retrieval (was destroyed after DB write) \u2014 eliminates 1-hour replay window<\/li>\n<li>Security: Textarea fields capped at 20,000 characters server-side to prevent spam-scoring DoS via oversized input<\/li>\n<li>Security: Blocked phrase matching now runs per-field in addition to concatenated text, reducing split-phrase bypass risk<\/li>\n<li>Security: File uploads now reject filenames containing PHP\/script extensions in any position (e.g., shell.php.jpg)<\/li>\n<li>Added: Honeypot hidden field \u2014 bots that fill the invisible field are silently blocked regardless of spam score<\/li>\n<\/ul>\n\n<h4>1.6.6<\/h4>\n\n<ul>\n<li>Security: From: display name now encoded with RFC 2047 MIME encoding (mb_encode_mimeheader) \u2014 prevents header injection via non-ASCII characters or special chars<\/li>\n<li>Security: admin_email_to validated with is_email() and CRLF-stripped before passing to wp_mail()<\/li>\n<li>Security: Resend mail CC\/BCC now re-validated with is_email() and CRLF-stripped on restore from DB<\/li>\n<li>Security: ajax_download_file() path check now uses trailing DIRECTORY_SEPARATOR (same pattern as set_attachments()) to prevent sibling-directory bypass<\/li>\n<li>Security: Email subject CRLF stripped at plugin layer in both admin notification and auto-reply<\/li>\n<li>Performance\/Security: CSV export now streams in batches of 500 rows \u2014 prevents memory exhaustion on large datasets; keyword filter moved to SQL layer<\/li>\n<\/ul>\n\n<h4>1.6.5<\/h4>\n\n<ul>\n<li>Security: CSV injection fix \u2014 user-supplied field values starting with =, +, -, @ are prefixed with a single-quote in CSV export<\/li>\n<li>Security: {page_url} tag now uses home_url() instead of $_SERVER['HTTP_HOST'] to prevent host-header injection<\/li>\n<li>Security: ReDoS validation probe improved with near-miss test strings; PCRE control verbs (*LIMIT_BACKTRACK etc.) now rejected at save time<\/li>\n<li>Security: pcre.recursion_limit added alongside backtrack_limit in all regex guards; try\/finally ensures limit is always restored<\/li>\n<li>Security: field validation 'pattern' rule now runs with the same ReDoS guard as blocked-phrase regex matching<\/li>\n<li>Security: set_attachments() path check uses trailing DIRECTORY_SEPARATOR to prevent shedform-uploads-evil prefix bypass<\/li>\n<li>Security: wp_unslash() added to remaining $_POST accesses in admin handlers<\/li>\n<li>Added: Admin notice warning when server is Nginx (where .htaccess upload protection is ineffective)<\/li>\n<\/ul>\n\n<h4>1.6.4<\/h4>\n\n<ul>\n<li>Security: ReDoS protection \u2014 NG phrase regex patterns now validated with length limit (500 chars) and pcre.backtrack_limit guard; malformed\/explosive patterns are skipped with error_log<\/li>\n<li>Security: X-Forwarded-For IP spoofing mitigation \u2014 rightmost IP used instead of leftmost when behind a proxy<\/li>\n<li>Security: Email attachment path traversal prevention \u2014 set_attachments() now validates all paths with realpath() against the shedform-uploads base directory<\/li>\n<\/ul>\n\n<h4>1.6.3<\/h4>\n\n<ul>\n<li>Security: Upload subdirectories (form_id\/year\/month) now get .htaccess and index.php protection on creation<\/li>\n<li>Security: Content-Disposition header uses RFC 5987 (filename*=UTF-8) for correct Japanese filename handling<\/li>\n<li>Fixed: ALTER TABLE migration queries annotated with phpcs:ignore (no user input, WPCS compliance)<\/li>\n<\/ul>\n\n<h4>1.6.2<\/h4>\n\n<ul>\n<li>Security: XSS fix \u2014 {url_param} dynamic tag now uses wp_kses() instead of sanitize_text_field() only<\/li>\n<li>Security: XSS fix \u2014 {page_title} dynamic tag now escaped with esc_html()<\/li>\n<li>Security: File upload \u2014 finfo_file() unavailability now rejects upload instead of skipping MIME check<\/li>\n<li>Security: File upload \u2014 real MIME type passed to wp_handle_upload() instead of client Content-Type<\/li>\n<li>Security: File upload \u2014 file size now measured server-side with filesize() instead of trusting $_FILES['size']<\/li>\n<li>Security: wp_unslash() added to all $_POST access in form input processing (WPCS compliance)<\/li>\n<li>Fixed: Double-escaping in consent scroll content (removed redundant esc_html() inside wp_kses_post())<\/li>\n<\/ul>\n\n<h4>1.6.1<\/h4>\n\n<ul>\n<li>\u30d7\u30e9\u30b0\u30a4\u30f3\u30b9\u30e9\u30c3\u30b0\u3092 shed-form \u306b\u7d71\u4e00\uff08WordPress.org \u7533\u8acb\u5bfe\u5fdc\uff09<\/li>\n<\/ul>\n\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>Added: GPL-2.0+ license for WordPress.org directory compatibility<\/li>\n<li>Added: Privacy policy suggestion via wp_add_privacy_policy_content<\/li>\n<li>Added: Third-party service disclosure in readme.txt<\/li>\n<li>Changed: NG phrase cloud update from automatic cron to manual button<\/li>\n<li>Changed: Bundled SortableJS locally instead of CDN<\/li>\n<li>Improved: Internationalization \u2014 all hardcoded Japanese strings wrapped with __()<\/li>\n<li>Improved: Generated .pot file for translation support<\/li>\n<\/ul>\n\n<h4>1.5.4<\/h4>\n\n<ul>\n<li>Fixed: Reply-To placeholder expansion in admin and auto-reply emails<\/li>\n<li>Improved: Email placeholder handling for field keys<\/li>\n<\/ul>\n\n<h4>1.5.3<\/h4>\n\n<ul>\n<li>Added: Consent field type with scroll-to-enable functionality<\/li>\n<li>Improved: Static caching in settings class to reduce database queries<\/li>\n<\/ul>\n\n<h4>1.5.1<\/h4>\n\n<ul>\n<li>Fixed: Submit button disabled until Turnstile verification completes<\/li>\n<li>Security: Replaced PHP sessions with WordPress transients and one-time tokens<\/li>\n<\/ul>","raw_excerpt":"A contact form plugin for Japanese websites with confirmation screen, spam protection, and submission history.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/305874","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=305874"}],"author":[{"embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/teamstaccato"}],"wp:attachment":[{"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=305874"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=305874"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=305874"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=305874"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=305874"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/co.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=305874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}