<?xml version="1.0" encoding="UTF-8"?>    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title></title>
        <link>https://interactivetools.com/forum/forum-search.php?k=user%3AKennyH</link>
        <description></description>
        <pubDate>Mon, 04 May 2026 15:31:39 -0700</pubDate>
        <language>en-us</language>
        <atom:link href="https://interactivetools.com/forum/forum-search.php?k=user%3AKennyH&amp;rss=1" rel="self" type="application/rss+xml" />

                <item>
          <title>CMSB v3.83 Beta (Show/Hide Fields &amp; MCP Server)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248415#post2248415</link>
          <description><![CDATA[<p>I have spent quite a bit of time trying to recreate this issue or even find the one example I had for you. I must have dreamed the whole thing! If I see it again, I'll report back.</p>
<p><span>echo nl2br(htmlencode($record['name']));</span> should be easy to implement and probably less frustrating because I always forgot to check that box anyway with any new build or schema, and had to go back in and do it.</p>]]></description>
          <pubDate>Fri, 01 May 2026 11:41:16 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248415#post2248415</guid>
        </item>
                <item>
          <title>CMSB v3.83 Beta (Show/Hide Fields &amp; MCP Server)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248412#post2248412</link>
          <description><![CDATA[<p>In 3.83 Beta - I am not finding the textbox option to not insert &lt;br&gt; tags. I saw a button appear that asked if I wanted to remove them and I clicked it. It didn't remove the tags from the 1 entry I saved. I went to the schema and can't find that option any longer.</p>]]></description>
          <pubDate>Wed, 29 Apr 2026 17:53:09 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248412#post2248412</guid>
        </item>
                <item>
          <title>CMSB v3.83 Beta (Show/Hide Fields &amp; MCP Server)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248409#post2248409</link>
          <description><![CDATA[<p>I had my Claude Code do some testing on our end in VS Code. I had developed my own MCP a few months back and we were able to compare that one with with this native one.&nbsp; Here's Claude's take after doing some extensive testing guided by my instructions. I had Claude write the summary for this forum post:</p>
<hr />
<p><strong>MCP Server Beta Feedback — v3.83</strong></p>
<p>We've been testing the new MCP Server hard over the last few days. Big picture: this is a well-designed server. The tool surface is thoughtful, naming is consistent, the layered IP + bearer auth is above typical MCP quality, and the <code>instructions</code> block on <code>initialize</code> is the best I've seen anywhere — you explicitly tell the model when to use CMSB MCP over raw MySQL, warn about hook/timestamp gaps, and point to <code>cmsApiPublic</code> / <code>cmsSignature</code> as guardrails against hallucinated APIs. That's exactly the failure mode those tools should address, and most MCP servers don't bother.</p>
<p>That said, there are some real issues worth flagging before this comes out of beta. Posting them here in severity order so others testing can corroborate or tell me I'm wrong.</p>
<hr />
<p><strong>Security — Pre-auth info disclosure</strong></p>
<p>Bearer auth is currently only enforced on <code>tools/call</code>. With no Authorization header at all, I was still able to get back:</p>
<ul>
<li>The full <code>initialize</code> response including <code>serverInfo.description</code> and the long instructions block</li>
<li>All 19 tool definitions via <code>tools/list</code></li>
<li>Both prompt names and — via <code>prompts/get cms-logs</code> — the entire prompt body, which enumerates internal table names (<code>_error_log</code>, <code>_log_audit</code>, <code>_cron_log</code>, <code>_outgoing_mail</code>) and internal settings keys (<code>serverChangeLog</code>, <code>bgtasks_lastRun</code>, <code>mail.outgoingMail</code>)</li>
</ul>
<p>Tool invocation itself is safe — I correctly got <code>No Bearer token provided</code> / <code>Invalid API key</code> when I tried to call anything. So this isn't a data breach. But it's pre-auth info disclosure against anyone who's already past the IP allowlist, and if a user ever clears the allowlist the whole discovery surface becomes public.</p>
<p><strong>Fix:</strong> require the bearer on every method, not just <code>tools/call</code>.</p>
<hr />
<p><span style="color:#ff0000;"><strong>Bugs</strong></span></p>
<p><strong>1. <code>cmsApiSearch</code> emits raw PHP warnings before the JSON-RPC payload.</strong></p>
<p>Calling <code>cmsApiSearch {"query":"DB::sel"}</code> returns six PHP warnings, then the JSON:</p>
<pre><code>Warning: include(.../vendor/composer/../../lib/ImageFactory.php): Failed to open stream: No such file or directory in .../cmsb/api/mcp.php:1081
Warning: include(.../vendor/composer/../../lib/Validator.php): Failed to open stream: No such file or directory in .../cmsb/api/mcp.php:1081
... (6 warnings total)
{"jsonrpc":"2.0",...}
</code></pre>
<p>Two problems with this:</p>
<ul>
<li>Strict JSON / SSE MCP clients will fail to parse. curl tolerates it; a real MCP client may not.</li>
<li>It leaks absolute filesystem paths.</li>
</ul>
<p><code>cmsErrorSummary</code> confirmed these are real errors — it groups six matching entries on <code>mcp.php:1081</code>. Looks like an autoloader/composer issue where <code>ImageFactory</code> and <code>Validator</code> are referenced but not present. Fresh <code>composer dump-autoload</code> might do it.</p>
<p><strong>2. Unknown methods return a fake tool result instead of a JSON-RPC error.</strong></p>
<p><code>resources/list</code> returns:</p>
<pre><code class="language-json">{"jsonrpc":"2.0","id":51,"result":{"content":[{"type":"text","text":"Unknown method: resources/list"}],"isError":true}}
</code></pre>
<p>Per the JSON-RPC spec this should be <code>{"error":{"code":-32601,"message":"Method not found"}}</code>. Clients that branch on protocol-level errors vs. tool-level errors (most proper MCP clients) will mis-handle this. Same pattern shows up for <code>notifications/initialized</code> returning "Invalid JSON-RPC version" wrapped in a fake result.</p>
<p><strong>3. <code>initialize</code> returns <code>protocolVersion: "2025-11-25"</code> regardless of what the client sent.</strong></p>
<p>I sent <code>"2025-06-18"</code>; the server echoed <code>"2025-11-25"</code>. The MCP spec says the server must return the client's requested version if supported, or the highest it supports that's ≤ the client's. Hardcoding a single (and future-dated) version can break strict clients.</p>
<p><strong>4. <code>selectOne</code> silently coerces string → int.</strong></p>
<p><code>selectOne {"table":"recipes","num":"abc"}</code> returns <code>Record not found: recipes num=abc</code> rather than a validation error. The <code>inputSchema</code> declares <code>num: integer</code> — the server should reject this at schema validation. As-is, "bad input" and "real miss" are indistinguishable to a model.</p>
<hr />
<p><strong>Tool-design suggestions</strong></p>
<ul>
<li><strong><code>listTables</code> and <code>cmsErrorSummary</code> take no args.</strong> A filter/prefix on <code>listTables</code> (98 tables on a small install; could be much larger elsewhere) and <code>limit</code> / <code>since</code> / <code>minCount</code> on <code>cmsErrorSummary</code> would scale better.</li>
<li><strong><code>query</code> / <code>queryWrite</code> take raw SQL</strong>, which means a model that bypasses the safer helpers can still do anything. Documenting that tradeoff in <code>instructions</code> is great. Consider a <code>dryRun</code> option on <code>queryWrite</code> that runs <code>EXPLAIN</code> plus (for <code>DELETE</code>/<code>UPDATE</code>) reports affected-row count without committing.</li>
<li><strong><code>queryWrite</code>'s <code>destructiveHint: true</code></strong> annotation is good, but surfacing affected-rows count on success would make model behavior safer still.</li>
<li><strong>No <code>_meta</code>/version on tool responses.</strong> While the output shape is still changing in beta, a <code>version</code> field would help clients detect drift.</li>
<li><strong><code>cmsApiPublic</code>'s docstring</strong> explicitly says "cheap to call" — that's a nice explicit cost signal to the model. More MCP servers should do this.</li>
</ul>
<hr />
<p><strong>What's working well</strong></p>
<p>Not just being nice — these are design wins worth calling out so they survive the next round of changes:</p>
<ul>
<li><strong>The <code>instructions</code> block.</strong> Already mentioned above; it's genuinely excellent.</li>
<li><strong>Error messages point the human to the fix UI.</strong> "Add it in Admin &gt; Advanced &gt; MCP Server &gt; Allowed IPs" and "Check the Authorization header in your <code>.mcp.json</code> file" tell the human what to do, not just what went wrong. That's the gold standard.</li>
<li><strong><code>cmsApiSearch</code> + <code>cmsSignature</code></strong> is a clever pair. The signature response returns file / line / class / inheritance / signature / docblock — exactly the right shape for keeping models from inventing function signatures against stale training data.</li>
<li><strong><code>cmsInfo.customUploadDirs</code></strong> surfacing per-field upload overrides is a thoughtful touch. Anything touching uploads needs exactly this.</li>
<li><strong>Defense in depth is real here.</strong> Password redaction in settings worked. MySQL system-table denial worked. Read-only <code>query</code> correctly rejected <code>DELETE</code> with a clear message pointing to <code>queryWrite</code>.</li>
<li><strong>The two prompts</strong> (<code>cms-logs</code>, <code>cms-fix</code>) are substantive runbooks, not placeholder stubs.</li>
</ul>
<hr />
<p><strong>Comparison notes — running CMSB MCP alongside our fleet MCP</strong></p>
<p>Some context: we run our own MCP server (<code>mcp.sagentic.dev</code>) for fleet-level portfolio management across 100+ client sites — it's purpose-built endpoints for domain management, support logs, cross-site reports, that kind of thing. Built on the official PHP MCP SDK v0.4.0. It's a very different animal from CMSB MCP (fleet control plane vs. single-site database plane), and we're treating them as complementary, not competing.</p>
<p>Running them side-by-side did surface some patterns worth sharing in both directions.</p>
<p><strong>Things CMSB MCP could borrow</strong></p>
<ol>
<li>
<p><strong>Tiered API keys.</strong> Our server has creator / standard / full / write tiers with field-level visibility differences — e.g., creator-tier responses hide credentials while standard-tier hides sensitive notes. CMSB has one key and a single "Allow write access" checkbox. For site owners wanting to give a lower-trust AI client read-only access to a subset of tables, tiering would be a big deal.</p>
</li>
<li>
<p><strong>Implement MCP Resources.</strong> <code>resources/list</code> currently returns "Unknown method." Natural candidates for CMSB: <code><a>cmsb://schema/index</a></code>, <code><a>cmsb://schema/{table</a>}</code>, <code><a>cmsb://settings</a></code> (non-sensitive subset), <code><a>cmsb://errorlog/recent</a></code>. Resources are proactively loadable, which fits AI workflows better than on-demand tool calls for schema/reference data.</p>
</li>
<li>
<p><strong>Proper JSON-RPC error codes.</strong> Using <code>-32001 Invalid API key</code>, <code>-32600 Invalid request</code>, <code>-32603 Error while executing tool</code> lets strict clients branch on error class. CMSB currently returns everything as a successful result with <code>isError: true</code> and the reason in a prose string. Already covered above but worth reinforcing — this is what the PHP MCP SDK gives you for free.</p>
</li>
<li>
<p><strong>Sessions + <code>Mcp-Session-Id</code>.</strong> Streamable HTTP per the MCP spec expects session management. Stateless is tolerable today but forecloses future features (subscriptions, progress notifications, <code>listChanged</code> events — CMSB advertises both as <code>false</code> on the capability flags, which confirms these haven't been wired up).</p>
</li>
<li>
<p><strong>Moving to the official PHP MCP SDK (<code>mcp/sdk</code> v0.4.0).</strong> The protocol-level quirks I listed above (hardcoded <code>protocolVersion</code>, fake results for unknown methods, PHP warnings in response bodies) all smell like hand-rolled JSON-RPC. The SDK gives you sessions, error codes, and resource/prompt handling for free. There's one known SDK bug — it silently fails to discover <code>#[McpResource]</code> attributes, so you have to register manually via <code>addResource()</code> — but everything else Just Works.</p>
</li>
<li>
<p><strong>Prompts with arguments.</strong> Our prompts take parameters like <code>use_skill(skill, domain, context)</code> to customize the workflow. CMSB's <code>cms-logs</code> / <code>cms-fix</code> are static. Both are valid, but parameterized scales better.</p>
</li>
</ol>
<p><strong>Things our servers should borrow from CMSB</strong></p>
<p>Being honest — CMSB MCP has some patterns our custom servers don't, that we should steal:</p>
<ol>
<li>
<p><strong>Live schema / API introspection (<code>cmsSchema</code>, <code>cmsApiSearch</code>, <code>cmsSignature</code>).</strong> Our own troubleshooting doc literally calls out two schema quirks — "uses <code>skill_content</code>, not <code>content</code>" and "no <code>api_id</code> column." That's the exact failure mode these tools solve. A schema-lookup endpoint would make those quirks discoverable rather than doc-resident.</p>
</li>
<li>
<p><strong>The <code>instructions</code> block.</strong> We have equivalent guidance in our <code>.guides/*.md</code> but it's not wired into the server's <code>initialize</code> response. The PHP SDK supports this — just populate it.</p>
</li>
<li>
<p><strong>UI-pointing error messages.</strong> Ours say "Invalid or missing API key. Provide via X-API-Key header or key query parameter." Yours say "Your IP is 170.000.000.000. Add it in Admin &gt; Advanced &gt; MCP Server &gt; Allowed IPs." The difference in helpfulness is real.</p>
</li>
</ol>
<hr />
<p><strong>Audit logging — question for the devs</strong></p>
<p>CMSB has both <code>_log_audit</code> and <code>api_audit_log</code> tables. Can you confirm MCP writes (<code>insert</code> / <code>update</code> / <code>delete</code> / <code>queryWrite</code> / uploads) are landing in one of them? Didn't see explicit confirmation in the docs and it matters for compliance use cases. If <code>cmsErrorSummary</code> is intended to be the canonical surface for MCP-origin errors specifically (vs. generic PHP errors from the whole site), that'd be worth documenting too.</p>
<hr />
<p>Suggested priority</p>
<ul>
<li><strong>P0</strong> — Require bearer auth on <code>initialize</code> / <code>tools/list</code> / <code>prompts/*</code>.</li>
<li><strong>P0</strong> — Fix whatever's missing at <code>mcp.php:1081</code> so <code>cmsApiSearch</code> stops emitting PHP warnings into the response stream.</li>
<li><strong>P1</strong> — Switch unknown-method / protocol-error paths to real JSON-RPC error objects with proper codes.</li>
<li><strong>P1</strong> — Echo the client's <code>protocolVersion</code> (or negotiate downward) instead of hardcoding <code>2025-11-25</code>.</li>
<li><strong>P2</strong> — Strict type validation on tool inputs (reject <code>num: "abc"</code> rather than coercing).</li>
<li><strong>P3</strong> — Filter/limit args on <code>listTables</code> and <code>cmsErrorSummary</code>; <code>dryRun</code> on <code>queryWrite</code>.</li>
</ul>
<p>I didn't run any write operations (insert / update / delete / upload) against production data.</p>
<p>Overall, really good work on this release. The MCP server is a genuinely useful addition to CMSB and most of what I flagged above is protocol-correctness polish rather than design problems. Looking forward to v3.83 final.<br /><br />Thanks - Claude</p>
<hr />]]></description>
          <pubDate>Tue, 21 Apr 2026 11:24:14 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248409#post2248409</guid>
        </item>
                <item>
          <title>Small BUG for 3.82</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248383#post2248383</link>
          <description><![CDATA[<p>In Database Editor &gt;&gt; *schema* &gt;&gt; <span>Input Validation &gt;&gt; Upload Settings</span>, when unchecking a "<span>Create thumbnail" and it's related "Crop" checkbox, they revert back to being checked on save.&nbsp;</span></p>]]></description>
          <pubDate>Sat, 14 Mar 2026 11:33:53 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248383#post2248383</guid>
        </item>
                <item>
          <title>PermaLinks conflict</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248329#post2248329</link>
          <description><![CDATA[<p>Same here, Jeff. I got tired of Google fighting me with canonical issues so everything gets a slash at the end</p>]]></description>
          <pubDate>Tue, 10 Feb 2026 14:30:15 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248329#post2248329</guid>
        </item>
                <item>
          <title>Free Plugin: Plugin Manager</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248311#post2248311</link>
          <description><![CDATA[<p>Thanks for the report, Jeff! And congrats on filing the first GitHub issue for this plugin.</p>
<p><strong>The Bug:</strong> The update notification cache was storing version comparison results from when the check was performed. The plugin checks the RSS feeds at <a href="https://interactivetools.com/plugins/rss.php" rel="nofollow">https://interactivetools.com/plugins/rss.php</a> and <a href="https://www.sagentic.dev/public/plugins/rss.php" rel="nofollow">https://www.sagentic.dev/public/plugins/rss.php</a> to see if the plugin installed matches the latest version.</p>
<p>When you updated the plugin files, the cache still had the old data showing "you have 1.00, there's 1.01 available" - so it kept showing the update badge even though you were now at 1.01. The cache wouldn't refresh for 24 hours.</p>
<p><strong>The Fix (v1.02):</strong> The plugin now re-validates cached update results against your <em>current</em> installed versions before displaying. Update badges should correctly disappear as soon as you update a plugin - no need to wait for the cache to expire.</p>
<p><strong>GitHub:</strong> <a href="https://github.com/sagentic/cmsb-plugin-manager/issues/1" rel="nofollow">https://github.com/sagentic/cmsb-plugin-manager/issues/1</a></p>
<p>I appreciate you taking the time to report this!</p>]]></description>
          <pubDate>Fri, 23 Jan 2026 08:48:34 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248311#post2248311</guid>
        </item>
                <item>
          <title>Feature Request: Automatic decryption of encrypted fields in MySQL Developer Console</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248308#post2248308</link>
          <description><![CDATA[<p>I've noticed that when querying tables with encrypted fields in the MySQL Developer Console, the results show the encrypted values instead of the decrypted readable text. This makes it difficult to verify data when testing queries or share with AI. Would it be possible to add functionality to automatically decrypt these fields in the console view, similar to how they appear when accessed through the CMS interface?</p>]]></description>
          <pubDate>Thu, 22 Jan 2026 13:59:52 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248308#post2248308</guid>
        </item>
                <item>
          <title>Free Plugin: Plugin Manager</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248307#post2248307</link>
          <description><![CDATA[<p>Thanks Jeff, for the excellent feedback! I've identified and fixed two issues that were affecting the plugin (and the GitHub link to <a href="https://github.com/sagentic/cmsb-plugin-manager" rel="nofollow">https://github.com/sagentic/cmsb-plugin-manager</a>)</p>
<p><strong>What Was Wrong:</strong></p>
<p>The plugin had two separate bugs that both prevented settings from being saved properly:</p>
<ol>
<li>
<p><strong>CSRF Token Compatibility Issue</strong> (Drag-and-Drop Sorting):</p>
<ul>
<li><strong>Field Name Mismatch</strong>: The JavaScript was sending the CSRF token with the field name<code>csrfToken</code>, but CMS Builder's security validation expects it to be named<code>_csrf</code>. This caused all AJAX save operations to fail with "Form _csrf value missing" errors.<br /><br /></li>
<li><strong>Version Compatibility</strong>: CMSB changed the session variable name between versions:
<ul>
<li>CMSB 3.81 uses<code>$_SESSION['_CSRFToken']</code>(capitalized)</li>
<li>CMSB 3.82+ uses<code>$_SESSION['_csrf']</code>(lowercase)<br /><br /></li>
</ul>
</li>
<li>The plugin was only reading from one format, causing it to fail on 3.81 installations.</li>
</ul>
</li>
<li>
<p><strong>Settings Page Checkboxes Not Saving</strong>:</p>
<ul>
<li>When unchecking any setting (Show inactive plugins, Show system plugins, Group by status, Check for updates), the checkbox would revert back to checked after saving.<br /><br /></li>
<li><strong>Root Cause</strong>: The form uses hidden fields with<code>value="0"</code>before each checkbox (proper HTML pattern), but the PHP code was using<code>isset($_POST['fieldname'])</code>which always returns<code>true</code>because the hidden field is always present - even when the checkbox is unchecked.</li>
</ul>
</li>
</ol>
<p><strong>What's Fixed in v1.01:</strong></p>
<p>✅ Corrected CSRF token field name in all AJAX requests (<code>_csrf</code> instead of <code>csrfToken</code>)<br />✅ Added backward compatibility to support both CMSB 3.81 and 3.82+ session variable formats<br />✅ Drag-and-drop sort order now properly saves and persists across page refreshes on all CMSB versions<br />✅ Fixed checkbox settings logic to check actual POST values instead of using <code>isset()</code><br />✅ All settings now properly save both checked and unchecked states<br />✅ Improved error handling for sort order save operations</p>
<p>Both the kanban-style drag-and-drop sorting and the settings page now work correctly on all supported CMSB versions.</p>
<p><strong>To Update:</strong></p>
<p>If you're already running v1.00, simply replace the plugin files with the new version and refresh your browser cache. No database changes or settings modifications needed.</p>
<p>Thanks again to Jeff for taking the time to test and report both issues. This kind of feedback is invaluable for making sure plugins work correctly across all supported CMSB versions!</p>]]></description>
          <pubDate>Thu, 22 Jan 2026 12:22:46 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248307#post2248307</guid>
        </item>
                <item>
          <title>Free Plugin: Plugin Manager</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248304#post2248304</link>
          <description><![CDATA[<p>Hi everyone,</p>
<p>I'm releasing a free plugin that gives you a centralized dashboard for managing all your CMS Builder plugins - with Kanban style drag-and-drop organization and automatic update detection. I have been using it on all my websites for a few days and think it's ready for others to use and test.</p>
<p><strong>The Problem</strong></p>
<p>When you manage lots of plugins, you want quick visual access to everything: a dashboard where you can see all your plugins at once, organize them by importance, jump directly to settings, and know when updates are available.</p>
<p><strong>The Solution</strong></p>
<p>Plugin Manager provides a visual dashboard with all your plugins displayed as cards in a 4-column grid. Activate/deactivate plugins with one click, drag-and-drop to organize them, and see update badges when newer versions are available. I added a link to the top menu (using the free Header Menu Admin plugin - <a href="https://www.sagentic.dev/public/plugins/header-menu-admin/" rel="nofollow">https://www.sagentic.dev/public/plugins/header-menu-admin/</a>) so the Plugins Dashboard is always just a click away.</p>
<p><strong>Features</strong></p>
<ul>
<li>Visual plugin cards with status badges (Active/Inactive/System)</li>
<li>One-click activation/deactivation from the dashboard</li>
<li>Drag-and-drop reordering (saves automatically)</li>
<li>Keyboard navigation support (Alt+Arrow keys)</li>
<li>Direct links to all plugin admin pages</li>
<li>Automatic update detection from Interactive Tools Plugins and Sagentic Plugins RSS feeds</li>
<li>Show/hide inactive or system plugins</li>
<li>Group plugins by active/inactive status</li>
<li>Real-time statistics (total, active, inactive, system)</li>
<li>Customizable display options via Settings page</li>
<li>Security and Accessibility are top-of-mind with all plugins we develop</li>
</ul>
<p><strong>Download</strong></p>
<ul>
<li>GitHub: <a href="https://github.com/sagentic/cmsb-plugin-manager" rel="nofollow">https://github.com/sagentic/cmsb-plugin-manager</a></li>
<li>Screenshots &amp; Direct download: <a href="https://www.sagentic.dev/public/plugins/" rel="nofollow">https://www.sagentic.dev/public/plugins/</a></li>
</ul>
<p><strong>Installation</strong></p>
<ol>
<li>Copy the <code>pluginManager</code> folder to <code>/cmsb/plugins/</code></li>
<li class="whitespace-normal break-words pl-2">Log into CMS admin and activate the plugin</li>
<li class="whitespace-normal break-words pl-2">Access via Admin &gt; Plugins &gt; Plugin Manager (tip: add a link to your header menu or side menu)</li>
</ol>
<p><strong>Requirements</strong></p>
<ul>
<li>CMS Builder 3.50+</li>
<li>PHP 7.1+</li>
<li>JavaScript enabled (for drag-and-drop)</li>
</ul>
<p><strong>Feedback Welcome</strong></p>
<p>I built this because I wanted a better way to access and organize my growing collection of plugins. The dashboard design includes space for future widgets and charts. I'd love to hear your feedback, bug reports, or feature suggestions. MIT licensed - modify as needed.</p>
<p>Thanks, Kenny H</p>]]></description>
          <pubDate>Wed, 21 Jan 2026 10:31:58 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248304#post2248304</guid>
        </item>
                <item>
          <title>PHP 8.3 Compatibility Issue in ZenDB/Config.php</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248297#post2248297</link>
          <description><![CDATA[<p>I was doing some updates on a website and Claude Code insisted on running some checks first and came back with this.&nbsp;<br /><br />PHP 8.3 Compatibility Issue in ZenDB/Config.php</p>
<p><strong>File:</strong> <code>cmsb/lib/ZenDB/Config.php</code></p>
<p><strong>Issue:</strong> The variable variable syntax <code>self::${$key}</code> is deprecated in PHP 8.2+ and will be removed in PHP 9.0.</p>
<p><strong>Affected lines:</strong></p>
<ul>
<li><strong>Line 40:</strong><code>return self::${$key};</code></li>
<li><strong>Line 53:</strong><code>$config[$key] = self::${$key};</code></li>
<li><strong>Line 80:</strong><code>self::${$key} = $value;</code></li>
</ul>
<p><strong>Recommended fix:</strong> Replace with Reflection-based access for static properties:</p>
<pre><code class="language-php">// Line 40 - in get() method
$reflectionProperty = new \ReflectionProperty(__CLASS__, $key);
return $reflectionProperty-&gt;getValue(null);

// Line 53 - in getAll() method
$reflectionProperty = new \ReflectionProperty(__CLASS__, $key);
$config[$key] = $reflectionProperty-&gt;getValue(null);

// Line 80 - in set() method
$reflectionProperty = new \ReflectionProperty(__CLASS__, $key);
$reflectionProperty-&gt;setValue(null, $value);
</code></pre>
<p><strong>Reference:</strong> <a href="https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation" rel="nofollow">https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation</a></p>
<hr />
<p><strong>Bottom line:</strong> Nothing breaks. It's just noisy in your logs until the developer fixes it.</p>
<p>The code won't actually <strong>break</strong> until PHP 9.0 (which is likely 2-3 years away).</p>]]></description>
          <pubDate>Thu, 15 Jan 2026 10:03:17 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248297#post2248297</guid>
        </item>
                <item>
          <title>CMSB v3.82 Released (Improved UI, Menu Count Badges, &amp; .env support)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248296#post2248296</link>
          <description><![CDATA[<p><span>I've been working extensively with the new .env file capability and have migrated all of my websites to use it for encryption keys, API keys, mail credentials, and other sensitive settings data. Everything has been running smoothly with no issues to report.&nbsp;</span></p>
]]></description>
          <pubDate>Wed, 14 Jan 2026 20:15:20 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248296#post2248296</guid>
        </item>
                <item>
          <title>Free Plugin: IndexNow - Instant Search Engine Notifications</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248295#post2248295</link>
          <description><![CDATA[<p><strong>IndexNow Plugin v1.01 Released</strong></p>
<p>Just pushed an update to the IndexNow plugin with enhanced security options.</p>
<p>What's New in v1.01:<br />- Optional .env.php support for secure API key storage (outside web root) for CMSB 3.82+<br />- Configurable environment filename setting<br />- Automatic migration between storage methods<br />- Fully backward compatible</p>
<p>The plugin automatically notifies search engines (Bing, Yandex, etc.) when you create, update, or delete content. Features include automatic submissions on save, manual/bulk URL submission, retry system for failed requests, and full submission logging.</p>
<p>Download &amp; Info: <a href="https://www.sagentic.dev/public/plugins/" rel="nofollow">https://www.sagentic.dev/public/plugins/</a><br />GitHub: <a href="https://github.com/sagentic/cmsb-plugin-indexnow" rel="nofollow">https://github.com/sagentic/cmsb-plugin-indexnow</a></p>
<p>Feedback welcome!</p>]]></description>
          <pubDate>Wed, 14 Jan 2026 17:52:19 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248295#post2248295</guid>
        </item>
                <item>
          <title>CMSB v3.82 Beta (Improved UI, Menu Count Badges, &amp; .env support)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248284#post2248284</link>
          <description><![CDATA[<p>With CMSB 3.82, the AI Schema Exporter plugin throws:</p>
<pre><code>Error: Call to undefined method Itools\Cmsb\Schema::tables()
</code></pre>
<p>The Schema class method was renamed from <code>getTableNames()</code> to <code>tables()</code> in 3.82. The plugin needed to be updated to use the new method name and it works perfectly again.</p>]]></description>
          <pubDate>Sun, 11 Jan 2026 12:49:33 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248284#post2248284</guid>
        </item>
                <item>
          <title>Free Plugin: Conditional Error Checking Pro</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248281#post2248281</link>
          <description><![CDATA[<p>Hi everyone,</p>
<p>I'm releasing a free plugin that lets you create conditional validation rules through the admin UI - no code editing required.</p>
<p><strong>The Problem</strong></p>
<p>Sometimes you need "if this, then that" validation - when one field has a value, another field should be required.</p>
<p><strong>The Solution</strong></p>
<p>Conditional Error Checking Pro provides a visual rule builder where you select a trigger field, a condition, and the field that becomes required. Rules are managed entirely through the admin interface.</p>
<p><strong>Example Rules</strong></p>
<ul>
<li>If <code>contact_name</code> is not empty → require <code>phone</code></li>
<li>If <code>membership_type</code> equals "premium" → require <code>payment_method</code></li>
<li>If <code>shipping_address</code> is not empty → require <code>shipping_city</code></li>
</ul>
<p><strong>Features</strong></p>
<ul>
<li>9 condition types (empty, equals, contains, greater than, regex, etc.)</li>
<li>Works with any CMS table</li>
<li>Activity logging with CSV export</li>
<li>Import/export rules as JSON</li>
<li>Optional email notifications when saves are blocked</li>
<li>Dashboard with statistics</li>
</ul>
<p><strong>Download</strong></p>
<ul>
<li>GitHub: <a href="https://github.com/sagentic/cmsb-plugin-cecp" rel="nofollow">https://github.com/sagentic/cmsb-plugin-cecp</a></li>
<li>Screenshots &amp; Direct download: <a href="https://www.sagentic.dev/public/plugins/" rel="nofollow">https://www.sagentic.dev/public/plugins/</a></li>
</ul>
<p><span style="color:#ff0000;">Note: There are a few other plugins on the download page that are still in BETA testing. Try them out!</span></p>
<p><strong>Installation</strong></p>
<ol>
<li>Copy the <code>conditionalErrorCheckingPro</code> folder to <code>/cmsb/plugins/</code></li>
<li>Log into CMS admin and go to Plugins &gt; Conditional Error Checking Pro</li>
<li>Start creating rules - tables auto-create on first access</li>
</ol>
<p><strong>Requirements</strong></p>
<ul>
<li>CMS Builder 3.59+</li>
<li>PHP 8.0+</li>
</ul>
<p><strong>Feedback Welcome</strong></p>
<p>I'd love to hear your comments, bug reports, or suggestions to improve these plugins. MIT licensed - modify as needed.</p>]]></description>
          <pubDate>Fri, 09 Jan 2026 17:14:42 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248281#post2248281</guid>
        </item>
                <item>
          <title>Free Plugin: IndexNow - Instant Search Engine Notifications</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248280#post2248280</link>
          <description><![CDATA[<p>Hi Dave -&nbsp;</p>
<p>Thanks for pointing out my GitHub visibility - just habit to make them private. It's now public. I have a few other Plugins that I am still testing on several websites and will release shortly - Broken Link Checker and Accessibility Checker. They'll have the same Dashboard interface as this IndexNow plugin so I hope them to be very intuitive.</p>]]></description>
          <pubDate>Fri, 09 Jan 2026 07:17:26 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248280#post2248280</guid>
        </item>
                <item>
          <title>Free Plugin: IndexNow - Instant Search Engine Notifications</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248278#post2248278</link>
          <description><![CDATA[<p>Hi everyone,</p>
<p>I'm releasing a free plugin that automatically notifies search engines (Bing, Yandex, etc.) when you create, update, or delete content in CMS Builder.</p>
<p><strong>The Problem</strong></p>
<p>Search engines can take days or weeks to discover content changes on your site. This is especially frustrating when you publish time-sensitive content or fix errors on existing pages.</p>
<p><strong>The Solution</strong></p>
<p>IndexNow is a protocol supported by Bing, Yandex, and others that lets websites proactively notify search engines of changes instead of waiting for crawlers to find them. This plugin hooks into CMSB's record save/delete events and handles the notifications automatically.</p>
<p><strong>Features</strong></p>
<ul>
<li>Automatic submissions when content is saved or deleted</li>
<li>Manual submission for bulk URL updates</li>
<li>Smart URL detection (handles permalinks, single-record sections, detail pages)</li>
<li>Retry system for temporary failures (rate limits, server errors)</li>
<li>Complete submission logging with statistics</li>
<li>Admin UI for configuration - no code editing required</li>
<li>Settings preserved during plugin updates</li>
</ul>
<p><strong>Download Latest Version</strong></p>
<ul>
<li>GitHub: <a href="https://github.com/sagentic/cmsb-plugin-indexnow" rel="nofollow">https://github.com/sagentic/cmsb-plugin-indexnow</a></li>
<li>Screenshots &amp; Direct download: <a href="https://www.sagentic.dev/public/plugins/" rel="nofollow">https://www.sagentic.dev/public/plugins/</a></li>
</ul>
<p><strong>Installation</strong></p>
<ol>
<li>Copy the <code>indexNow</code> folder to <code>/cmsb/plugins/</code></li>
<li>Log into the CMS admin</li>
<li>Go to Plugins &gt; IndexNow &gt; Settings and select which tables to monitor. Everything is configured through the admin UI - <span style="text-decoration:underline;">no code editing required</span></li>
<li>Optional: Add a sidebar shortcut via Admin &gt; Menu Links pointing to <code class="bg-text-200/5 border border-0.5 border-border-300 text-danger-000 whitespace-pre-wrap rounded-[0.4rem] px-1 py-px text-[0.9rem]">?_pluginAction=IndexNow\adminDashboard</code></li>
</ol>
<p>The plugin auto-generates your API key and creates the verification file at your site root.</p>
<p><strong>Requirements</strong></p>
<ul>
<li>CMS Builder 3.50+</li>
<li>PHP 8.0+</li>
<li>cURL extension</li>
</ul>
<p><strong>Feedback Welcome</strong></p>
<p>I built this to solve an indexing issue with Bing on one of my client sites and figured it would benefit the community. <span style="color:#008000;"><strong>I'd love to hear your feedback, bug reports, or feature suggestions.</strong></span> The plugin is MIT licensed so feel free to modify it for your needs.</p>]]></description>
          <pubDate>Wed, 07 Jan 2026 16:20:58 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248278#post2248278</guid>
        </item>
                <item>
          <title>CMSB v3.82 Beta (Improved UI, Menu Count Badges, &amp; .env support)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248269#post2248269</link>
          <description><![CDATA[<p>The split tabs are just fine and make sense to me. I just wanted make sure.&nbsp;</p>
<p>I was just building a huge schema and am going back to check on which fields should be required and which ones not. I was then thinking a red asterisks on the editor pages would be really nice for required fields. Probably in the same spot as the circle-question icon or even before the label itself.</p>
<p>I'll start testing the new beta today on some projects I am working on. Happy 2026!</p>]]></description>
          <pubDate>Wed, 31 Dec 2025 12:32:18 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248269#post2248269</guid>
        </item>
                <item>
          <title>3.81 User Accounts</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248260#post2248260</link>
          <description><![CDATA[<p>Can confirm this works very well in 3.82 Beta. This is a much cleaner solution</p>]]></description>
          <pubDate>Mon, 29 Dec 2025 16:01:36 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248260#post2248260</guid>
        </item>
                <item>
          <title>CMSB v3.82 Beta (Improved UI, Menu Count Badges, &amp; .env support)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248258#post2248258</link>
          <description><![CDATA[<p>First off, there are some really nice improvements to the UI/UX - really enjoying these changes especially!</p>
<p>I did run into a couple of issues. I took screenshots to help illustrate.</p>
<ol>
<li>When I go to CMS Setup &gt;Database&gt; *<span>Database Table* the last two tabs (Advanced and MySQL Source) are aligned to the right and separated from the first three tabs. Is this intentional?<br /><br /></span></li>
<li><span>When I go to a single-record table &gt; Enabled Actions &gt; Preview (is the only option available). If I click save and try to visit that item, I get "Modifying records has been disabled for this section!"&nbsp;<br />I can manually change it back in the schema, but if I save it through the interface, it reverts back to '_disableModify' =&gt; 1,<br /></span></li>
</ol>
<p><span>Still looking at other stuff, but this is pretty cool so far!</span></p>]]></description>
          <pubDate>Mon, 29 Dec 2025 15:44:56 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248258#post2248258</guid>
        </item>
                <item>
          <title>3.81 User Accounts</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248248#post2248248</link>
          <description><![CDATA[<p>Hi Dave -&nbsp;</p>
<p>That did resolve the issue. I'm not sure how it was before as I rarely check things from this point of view. Most of my websites are locked out from the clients and my CMSB account is the only active account. In the cases where the clients have access, it is very limited (so they don't hurt themselves).</p>
<p>This only came up because I have employees that need access to some of the data in my Development Dashboard, but there is some info I don't want them to see like revenue, API keys, server passwords, etc... HOWEVER, I implemented front-end forms where they can edit limited data and never see the backend of the CMS.&nbsp;</p>
<p>I don't think it's an issue for me. Maybe a note somewhere that "View" must be turned on for a section before you can give someone "View" access. I just realized that I turned off "View" access since they would be able to see sensitive data regardless of being able to edit it.&nbsp; I don't have a case where this affects other websites, so it's all good working the way you have it.</p>]]></description>
          <pubDate>Tue, 23 Dec 2025 15:14:48 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248248#post2248248</guid>
        </item>
                <item>
          <title>3.81 User Accounts</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248244#post2248244</link>
          <description><![CDATA[<p>I just noticed an issue with user permissions on a few 3.81 installs that I have tested specifically for this problem.</p>
<ul>
<li><span style="color:#000000;">If I set a user to <strong>Viewer</strong>, they can't see any records. </span></li>
<li><span style="color:#000000;">If I set them to <strong>Viewer &amp; Author</strong>, they can't see any other records, but can create them.&nbsp;</span></li>
<li><span style="color:#000000;">If I set them to <strong>Editor</strong> or <strong>Author</strong>, everything works as expected.</span></li>
</ul>]]></description>
          <pubDate>Tue, 23 Dec 2025 10:34:42 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248244#post2248244</guid>
        </item>
                <item>
          <title>CMSB v3.81 Beta (PHP 8.5 Support &amp; More)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248220#post2248220</link>
          <description><![CDATA[<p>I have installed it on a few websites that I am heavily in the build process right now, so a great time to test everything. I didn't ever have any issues with Backup and Restore and I have tested a few installations already.</p>
<p>I really enjoy the newest features and can't express just how much they speed things up. Especially these two screens - <b>MySQL Table Schema:</b><span>&nbsp;(show all schemas:&nbsp;</span>MySQL<span>,&nbsp;</span>CMS<span>) - I can feed these into Claude Desktop / Claude Code and it is off and running a lot faster and with a deeper understanding. <span style="color:#ff0000;"><strong>Change request: can you make these two links (MySQL,&nbsp;CMS) open in a new tab?</strong></span></span></p>
<p>I have also been dealing with the Email Templates a lot more so I am wondering if you could place the tools icons next to it in the side menu. I see them when I go to admin.php?menu=_email_templates at the top of the page, but one less click = one less click.</p>
<p>I am loving all of the new changes that help integrate with AI to help make it faster.</p>
<p>Kenny H</p>
<p><strong>EDIT NOTE:</strong> I got legitimately mad when I went to a 3.80 CMSB and saw "<strong>MySQL Table Schema</strong> (show all)" instead of "<b>MySQL Table Schema:</b><span>&nbsp;(show all schemas:&nbsp;</span>MySQL<span>,&nbsp;</span>CMS<span>)" - I updated the CMSB right away. This feature is just too handy.</span></p>]]></description>
          <pubDate>Mon, 08 Dec 2025 14:41:11 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248220#post2248220</guid>
        </item>
                <item>
          <title>CMSB v3.81 Beta (PHP 8.5 Support &amp; More)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248218#post2248218</link>
          <description><![CDATA[<p>I have a lot of good things to say and will get to that after some more testing, but I did want to point this out early in case it is a problem. I unzipped the new BETA 2 files over the the BETA 1 files and got this error:<br /><br /></p>
<blockquote>
<p><span>Parse error: syntax error, unexpected token "&lt;&lt;", expecting "]" in /home/xxxxxx/cmsb/data/cache.data.php on line 11 Parse error: syntax error, unexpected token "&lt;&lt;", expecting "]" in /home/xxxxxx/cmsb/data/cache.data.php on line 11</span></p>
</blockquote>
<p>I deleted <span>cache.data.php and it opened up the program without any issues.</span></p>
<p><span>I did the same for another website and it didn't give me any errors at all, so it may not be an issue at all.</span></p>
<p><span>On a 3rd website update I got the same error until I deleted the cache.data.php</span></p>]]></description>
          <pubDate>Sun, 07 Dec 2025 10:16:30 -0800</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248218#post2248218</guid>
        </item>
                <item>
          <title>CMSB v3.80 Released (Upload Management Features &amp; More)</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248166#post2248166</link>
          <description><![CDATA[<p>The Developer Console is awesome! Thank you for adding the new JSON view link/page. It was helpful immediately!</p>
<p>Kenny</p>]]></description>
          <pubDate>Sat, 11 Oct 2025 15:04:12 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248166#post2248166</guid>
        </item>
                <item>
          <title>CMS Error</title>
          <link>https://interactivetools.com/forum/forum-posts.php?postNum=2248165#post2248165</link>
          <description><![CDATA[<p>In 3.79, I had built some schemas and everything was going along just fine until I broke something. Now when I try to visit that particular list page (all others work) in the CMS, I get a mostly blank screen that says:<br /><br /><span>Showing all 20 records</span><br /><span>explode(): Argument #2 ($string) must be of type string, null given<br /><br />In the developer log:<br /><br />explode(): Argument #2 ($string) must be of type string, null given<br />/home/xxxxxxx/domains/xxxxxxx.com/public_html/cmsb/lib/menus/default/list_functions.php on line 552<br /><a href="https://www.xxxxxxx.com/cmsb/admin.php?menu=tv_shows" rel="nofollow">https://www.xxxxxxx.com/cmsb/admin.php?menu=tv_shows</a><br /></span></p>
<p>so I have done something to run afoul of line 552 of <span>list_functions.php</span>, but I can't figure it out:</p>
<pre class="language-php"><code>// return field label for fieldname in format: articles.title, title, createdBy.username
function _getFieldLabel($fullFieldname) {
  @list($fieldname, $tableName) = array_reverse(explode('.', $fullFieldname));

  // get schema
  $schema = [];
  if  (!$tableName &amp;&amp; $GLOBALS['schema']) {
    $schema = &amp;$GLOBALS['schema'];
  }
  else {
    if ($tableName == 'createdBy') { $tableName = 'accounts'; } // workaround for legacy 'createdBy.fieldname' fieldnames
    $schema = loadSchema($tableName, null, true);
  }

  // get label
  $label = $schema[$fieldname]['label'] ?? null;
  return $label;
}</code></pre>

<p><span>Schema attached. <br /><br />Thanks - Kenny</span></p>]]></description>
          <pubDate>Fri, 10 Oct 2025 17:19:25 -0700</pubDate>
          <guid isPermaLink="true">forum-posts.php?postNum=2248165#post2248165</guid>
        </item>
              </channel>
    </rss>
  