<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Faisal Ahammad</title>
    <description>The latest articles on DEV Community by Faisal Ahammad (@faisalahammad).</description>
    <link>https://dev.to/faisalahammad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F276949%2Fbd955134-ab8a-4dcc-b38d-5a84e5c79f3c.jpg</url>
      <title>DEV Community: Faisal Ahammad</title>
      <link>https://dev.to/faisalahammad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/faisalahammad"/>
    <language>en</language>
    <item>
      <title>Open Source WordPress Contribution: My July 2026 Recap</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Mon, 10 Aug 2026 07:11:01 +0000</pubDate>
      <link>https://dev.to/faisalahammad/open-source-wordpress-contribution-my-july-2026-recap-1f28</link>
      <guid>https://dev.to/faisalahammad/open-source-wordpress-contribution-my-july-2026-recap-1f28</guid>
      <description>&lt;p&gt;July felt different from the start. I opened the month with a WooCommerce logging bug and closed it 24 pull requests later, spread across 9 different WordPress repositories. Some fixes took ten minutes. One took a full week of back and forth with a maintainer over a single line of code.&lt;/p&gt;

&lt;p&gt;This post is my open source WordPress contribution recap for July 2026. I am sharing the actual code from each pull request, not just a list of links, so you can see what changed and why it mattered.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fixing WooCommerce, One Bug at a Time
&lt;/h2&gt;

&lt;p&gt;WooCommerce took up the biggest chunk of my month. I merged 10 pull requests into the core plugin, ranging from a one-line performance tweak to a new REST endpoint. I will walk through each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Log Cleanup Was Silently Leaving Files Behind
&lt;/h3&gt;

&lt;p&gt;The month opened with &lt;a href="https://github.com/woocommerce/woocommerce/pull/66073" rel="noopener noreferrer"&gt;PR #66073&lt;/a&gt;. &lt;code&gt;LogHandlerFileV2::delete_logs_before_timestamp()&lt;/code&gt; fetched expired log files without setting a &lt;code&gt;per_page&lt;/code&gt; value, so it inherited the admin UI default of 20. On sites with more than 20 expired log sources, the daily cleanup cron deleted only the first 20 and left the rest sitting in &lt;code&gt;wp-content/uploads/wc-logs/&lt;/code&gt; forever.&lt;/p&gt;

&lt;p&gt;The fix batches the deletion instead of trusting a single page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;file_controller&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'before'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$timestamp&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;delete_log_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER (batched with a no-progress guard):&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;file_controller&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_files&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'before'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$deleted_this_pass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;delete_log_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$deleted_this_pass&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$files&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$deleted_this_pass&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A site with 101 leftover log files now gets all of them removed instead of just 20. I added a no-progress guard so the loop stops if a batch cannot be deleted, which prevents an infinite loop on a stuck file.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Order List Table Cache Ignored Custom Filters
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/woocommerce/woocommerce/pull/66207" rel="noopener noreferrer"&gt;PR #66207&lt;/a&gt; fixed a subtler bug. &lt;code&gt;ListTable::prepare_items()&lt;/code&gt; decides whether to skip &lt;code&gt;SQL_CALC_FOUND_ROWS&lt;/code&gt; by checking the query args before any filters run. If a developer hooked &lt;code&gt;woocommerce_order_list_table_prepare_items_query_args&lt;/code&gt; to add a &lt;code&gt;meta_query&lt;/code&gt;, the cache fast path stayed blind to it and returned a stale total.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE (checked pre-filter args):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;order_query_args&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$safe_keys&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'no_found_rows'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER (checks post-filter args):&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_diff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;array_keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$order_query_args&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nv"&gt;$safe_keys&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'no_found_rows'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving the check to run after the filter means any key a plugin adds correctly disables the cache shortcut. Small change, but it stopped merchants from seeing wrong order counts whenever a custom query filter was active.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combining Six Requests Into One
&lt;/h3&gt;

&lt;p&gt;The most involved WooCommerce PR of the month was &lt;a href="https://github.com/woocommerce/woocommerce/pull/66276" rel="noopener noreferrer"&gt;PR #66276&lt;/a&gt;. Every wp-admin page load fired 6 separate &lt;code&gt;wc-analytics&lt;/code&gt; REST requests just to populate the Activity Panel bell icon and the "Things to do next" homescreen widget. Three endpoints, each called twice by two different components, with no shared cache between them.&lt;/p&gt;

&lt;p&gt;I added a single combined endpoint instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ActivityPanelCounts&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;\WC_REST_Data_Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$namespace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'wc-analytics'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$rest_base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'activity-panel/counts'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;get_counts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;rest_ensure_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="s1"&gt;'orders_to_fulfill_count'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_count_via&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'/wc-analytics/orders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'page'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'status'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'order_statuses'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="s1"&gt;'_fields'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'id'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="s1"&gt;'reviews_to_moderate_count'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_count_via&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'/wc-analytics/products/reviews'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'page'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="s1"&gt;'status'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'review_status'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A matching &lt;code&gt;activityPanelStore&lt;/code&gt; selector in &lt;code&gt;@woocommerce/data&lt;/code&gt; means all three Activity Panel components now read from one place. The resolution cache collapses six network requests into one per page load, and nothing about the counting logic changed since the new endpoint just delegates to the existing ones internally.&lt;/p&gt;

&lt;p&gt;If you want the fuller backstory on how I approach WooCommerce internals like this, my &lt;a href="https://faisalahammad.com/open-source-wordpress-contribution-june-2026/" rel="noopener noreferrer"&gt;June 2026 open source recap&lt;/a&gt; covers a similar REST endpoint consolidation from the month before.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guest Orders Finally Show a Name
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/woocommerce/woocommerce/pull/66279" rel="noopener noreferrer"&gt;PR #66279&lt;/a&gt; fixed something that bugged store owners for a while. The WooCommerce Home Orders panel shows "Order #123 Customer Name" for actionable orders, but guest checkouts have no &lt;code&gt;customer_id&lt;/code&gt; to look up, so the name always came back blank.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE: only checked the registered customer record&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER: falls back to billing details for guest orders&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;customerName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;billing&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;last_name&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The order response already carried the billing address. I just added &lt;code&gt;billing&lt;/code&gt; to the requested fields and used it as a fallback. Registered customers still get their name linked to their profile, guests just show as plain text like the rest of the row.&lt;/p&gt;

&lt;h3&gt;
  
  
  Product Taxonomy Boxes Hidden by Default
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/woocommerce/woocommerce/pull/65990" rel="noopener noreferrer"&gt;PR #65990&lt;/a&gt; addressed a first-run annoyance. On a user's first visit to &lt;strong&gt;Appearance → Menus&lt;/strong&gt;, WordPress hides every meta box except Pages, Posts, Custom Links, and Categories. That default list swallowed the Product Categories, Product Tags, and Brands boxes too, so new users had to dig into Screen Options before they could add these to a menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;filter_default_nav_menu_hidden_meta_boxes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$option&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="nv"&gt;$wp_meta_boxes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$wp_meta_boxes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'nav-menus'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'add-post-type-page'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'add-post-type-post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'add-custom-links'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'add-category'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'add-product_cat'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'add-product_tag'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'woocommerce_endpoints_nav_link'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;taxonomy_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'product_brand'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$visible&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'add-product_brand'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$wp_meta_boxes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'nav-menus'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$priorities&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$priorities&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$boxes&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$boxes&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;in_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nv"&gt;$visible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nv"&gt;$hidden&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'id'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This hooks &lt;code&gt;get_user_option_metaboxhidden_nav-menus&lt;/code&gt; so it only fires when a user has no saved preference yet. Existing users with a saved Screen Options choice are never touched.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Cache Poisoning Bug in the Brand Nav Widget
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/woocommerce/woocommerce/pull/65947" rel="noopener noreferrer"&gt;PR #65947&lt;/a&gt; was the trickiest bug to trace this month. The Brand Nav widget's &lt;code&gt;filter_out_cats()&lt;/code&gt; method hooks &lt;code&gt;woocommerce_product_subcategories_args&lt;/code&gt; and returns an empty taxonomy when a brand filter is active in the URL. That empty-taxonomy query returns zero rows, and WooCommerce cached those zero rows under the same key used by regular, non-filtered requests. Every visitor after that, brand filter or not, read the poisoned cache and saw no subcategories at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE: always cached the result, even an empty taxonomy query&lt;/span&gt;
&lt;span class="nf"&gt;wp_cache_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'product_cat'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER: only cache when the query actually resolved to a taxonomy&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'taxonomy'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;wp_cache_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'product_cat'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty-taxonomy query never produces a meaningful result, so storing it just poisoned the shared cache for no benefit. Skipping the cache write when taxonomy is empty fixed it for every visitor, not just the one who triggered the brand filter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nine Default Colors for Visual Attributes
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/woocommerce/woocommerce/pull/65923" rel="noopener noreferrer"&gt;PR #65923&lt;/a&gt; added a small quality-of-life feature. When a merchant creates a new "Color / image" attribute, the terms list starts empty and they have to add each color by hand. This seeds 9 common colors automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;get_default_color_terms&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'black'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Black'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'woocommerce'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'#121212'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'white'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'White'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'woocommerce'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'#FFFFFF'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'red'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Red'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'woocommerce'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'#D32F2F'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'blue'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Blue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'woocommerce'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'#1976D2'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="s1"&gt;'green'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'Green'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'woocommerce'&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'#388E3C'&lt;/span&gt; &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="c1"&gt;// gray, yellow, pink, and brown follow the same pattern&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The seeder only runs from &lt;code&gt;WC_Admin_Attributes::process_add_attribute()&lt;/code&gt;, so it fires when a merchant creates an attribute through the UI, not through programmatic &lt;code&gt;wc_create_attribute()&lt;/code&gt; calls or CSV imports. That distinction mattered during review since nobody wants a bulk import silently injecting terms nobody asked for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rounding Out the Month: Layout, Cron Status, and jQuery Cleanup
&lt;/h3&gt;

&lt;p&gt;Three smaller WooCommerce fixes closed out the batch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/woocommerce/woocommerce/pull/66280" rel="noopener noreferrer"&gt;PR #66280&lt;/a&gt; fixed missing layout styles on the &lt;code&gt;product_brand_thumbnails_description&lt;/code&gt; shortcode. Its stylesheet never defined &lt;code&gt;list-style: none&lt;/code&gt; or a clearfix, so the shortcode rendered as a bare bulleted list instead of a grid. I also clamped the &lt;code&gt;columns&lt;/code&gt; argument with &lt;code&gt;max( 1, absint( $args['columns'] ) )&lt;/code&gt; so an invalid value like &lt;code&gt;columns="abc"&lt;/code&gt; cannot throw a &lt;code&gt;DivisionByZeroError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/woocommerce/woocommerce/pull/66188" rel="noopener noreferrer"&gt;PR #66188&lt;/a&gt; fixed a false "Not scheduled" message on the WooCommerce Status page. The Daily Cron check looked for the old &lt;code&gt;wp_next_scheduled('wc_admin_daily')&lt;/code&gt; hook, but that migrated to Action Scheduler as &lt;code&gt;wc_admin_daily_wrapper&lt;/code&gt; a while back. Swapping the check to &lt;code&gt;as_next_scheduled_action('wc_admin_daily_wrapper')&lt;/code&gt; fixed the false alarm on fresh installs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/woocommerce/woocommerce/pull/66273" rel="noopener noreferrer"&gt;PR #66273&lt;/a&gt; replaced deprecated jQuery &lt;code&gt;.focus()&lt;/code&gt; shorthand calls with &lt;code&gt;.trigger( focus )&lt;/code&gt; across six legacy JS files, clearing the &lt;code&gt;JQMIGRATE: jQuery.fn.focus() event shorthand is deprecated&lt;/code&gt; warning that showed up on classic checkout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to try submitting a fix like these yourself, the &lt;a href="https://github.com/woocommerce/woocommerce/blob/trunk/.github/CONTRIBUTING.md" rel="noopener noreferrer"&gt;WooCommerce Contributing Guidelines&lt;/a&gt; walk through the coding standards and PR process the core team expects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Security Fixes for LifterLMS
&lt;/h2&gt;

&lt;p&gt;LifterLMS gave me 7 merged pull requests in July, and most of them came from running the WordPress Plugin Check tool against the plugin and working through what it flagged.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two Open Redirect Fixes for the Same Bug
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/gocodebox/lifterlms/pull/3201" rel="noopener noreferrer"&gt;PR #3201&lt;/a&gt; and &lt;a href="https://github.com/gocodebox/lifterlms/pull/3209" rel="noopener noreferrer"&gt;PR #3209&lt;/a&gt; both replaced &lt;code&gt;wp_redirect()&lt;/code&gt; with &lt;code&gt;wp_safe_redirect()&lt;/code&gt; in the template loader and the lesson progression controller. I submitted the fix twice, once through a direct patch and once through a scan-driven pass, and both landed with the identical change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$redirect&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;nocache_headers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;wp_redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$redirect&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$redirect&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;nocache_headers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;wp_safe_redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$redirect&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;$redirect&lt;/code&gt; value can come from a filter, which means a third-party plugin could pass in an untrusted URL. &lt;code&gt;wp_safe_redirect()&lt;/code&gt; blocks external hosts by default, closing off that open redirect path. The lesson-completion redirect got the same treatment since it also passes through a filter before use.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fifteen Files Missing Direct Access Protection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/gocodebox/lifterlms/pull/3198" rel="noopener noreferrer"&gt;PR #3198&lt;/a&gt; added the standard &lt;code&gt;defined( 'ABSPATH' ) || exit;&lt;/code&gt; guard to 15 PHP files that Plugin Check flagged, mostly builder view templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;// BEFORE:
&lt;span class="cp"&gt;&amp;lt;?php
/**
 * Builder lesson model view
 */
?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/html"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"tmpl-llms-lesson-template"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="cd"&gt;/**
 * Builder lesson model view
 */&lt;/span&gt;
&lt;span class="nb"&gt;defined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'ABSPATH'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tmpl-llms-lesson-template&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two files that Plugin Check flagged already had an equivalent guard, so I left those alone. The fix is mechanical, but it closes off direct HTTP access to files that were never meant to run outside the WordPress bootstrap.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Stale Cache Broke Media Protection
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/gocodebox/lifterlms/pull/3194" rel="noopener noreferrer"&gt;PR #3194&lt;/a&gt; fixed a bug that only showed up with a persistent object cache like Object Cache Pro active. The authorization result for a protected file gets cached with &lt;code&gt;wp_cache_add()&lt;/code&gt;, which only writes when the key does not already exist. If someone viewed an unprotected file first, the &lt;code&gt;'null'&lt;/code&gt; sentinel for "not protected" stayed in cache forever, even after the file was later protected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="nf"&gt;wp_cache_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'null'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'llms_media_authorization'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$cache_expiration&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="nf"&gt;wp_cache_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$cache_key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'null'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'llms_media_authorization'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$cache_expiration&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Switching to &lt;code&gt;wp_cache_set()&lt;/code&gt; means the cache always reflects the current state. I also added an &lt;code&gt;invalidate_authorization_cache()&lt;/code&gt; method and hooked it into the protection-save flow so the cache clears the moment a file's protection status changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Mislabeled File in the Media Library
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/gocodebox/lifterlms/pull/3181" rel="noopener noreferrer"&gt;PR #3181&lt;/a&gt; fixed a labeling bug. When a file was protected through the File block's lock icon, the Media Library attachment screen showed an add-on's label ("protected as an assignment submission") instead of the core label, because the add-on's filter ran for every protected file regardless of who protected it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$auth_filter&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$protector&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get_authorization_filter_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$is_addon_protected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$auth_filter&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="s1"&gt;'llms_attachment_is_access_allowed'&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nv"&gt;$auth_filter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$is_core_protected&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$protector&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;is_media_protected&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="no"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$is_addon_protected&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$is_core_protected&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$form_fields&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Core-protected files now return early with the correct label before the add-on filter ever runs. Add-ons still get to label their own files, since the check compares the actual authorization hook name instead of just checking a boolean.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small Fixes: Voucher Width and Button Styling
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/gocodebox/lifterlms/pull/3236" rel="noopener noreferrer"&gt;PR #3236&lt;/a&gt; widened the "Uses" input on the voucher edit screen from 50px to 80px, since 4-digit redemption counts like &lt;code&gt;1000&lt;/code&gt; were getting clipped. &lt;a href="https://github.com/gocodebox/lifterlms/pull/3237" rel="noopener noreferrer"&gt;PR #3237&lt;/a&gt; added the &lt;code&gt;wp-element-button&lt;/code&gt; CSS class to the access plan button so it correctly inherits theme button styling from &lt;code&gt;theme.json&lt;/code&gt; on block themes, while leaving classic themes untouched.&lt;/p&gt;

&lt;p&gt;Open redirects are a well documented attack pattern outside WordPress too. The &lt;a href="https://owasp.org/www-community/attacks/Unvalidated_Redirects_and_Forwards_Cheat_Sheet" rel="noopener noreferrer"&gt;OWASP Unvalidated Redirects and Forwards Cheat Sheet&lt;/a&gt; explains why letting user input control a redirect target is risky in any web application, not just WordPress plugins.&lt;/p&gt;




&lt;h2&gt;
  
  
  Teaching Plugin Check to Name Names
&lt;/h2&gt;

&lt;p&gt;My single pull request to the official &lt;a href="https://github.com/WordPress/plugin-check/pull/1391" rel="noopener noreferrer"&gt;WordPress Plugin Check&lt;/a&gt; tool, the same scanner behind the &lt;a href="https://wordpress.org/plugins/plugin-check/" rel="noopener noreferrer"&gt;Plugin Check plugin on WordPress.org&lt;/a&gt;, fixed a usability gap in how it validates the &lt;code&gt;Requires Plugins&lt;/code&gt; header. Before this change, a plugin declaring more than one dependency got one generic "header is not valid" error with no hint about which slug was the actual problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;check_requires_plugins_header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$requires_plugins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$label&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$main_file&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$slugs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'trim'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;','&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$requires_plugins&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$slugs&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$slug&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nv"&gt;$slug&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'/^[a-z0-9]+(?:-[a-z0-9]+)*$/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$slug&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// reports an error naming this specific slug&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;check_requires_plugins_slug_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$main_file&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each malformed slug now gets its own error naming that exact slug. Valid slugs get checked against the WordPress.org plugin directory through a transient-cached API call, and a warning appears if a declared dependency cannot be found there. During review, the maintainer pointed out that checking a plugin's local install state was not this check's job. A &lt;code&gt;plugin_repo&lt;/code&gt; category check should validate whether a plugin is ready for the directory, so I dropped the original local-state approach entirely in favor of the directory lookup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Yoast SEO: When a Passing Score Was Still Wrong
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Yoast/wordpress-seo/pull/23466" rel="noopener noreferrer"&gt;Yoast SEO PR #23466&lt;/a&gt; fixed a scoring bug that had been quietly dragging down otherwise perfect SEO analyses. The &lt;code&gt;functionWordsInKeyphrase&lt;/code&gt; assessment correctly returns an empty result when a focus keyphrase contains real content words, so it stays hidden from the UI. But the main SEO and taxonomy assessors still counted that empty row in the overall score denominator, which dropped a fully green analysis from around 99 down to about 94.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SEOScoreAggregator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ValidOnlyResultsScoreAggregator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The related-keyphrase and collection-page assessors already used &lt;code&gt;ValidOnlyResultsScoreAggregator&lt;/code&gt;, which skips results without a real score. Switching the main SEO and taxonomy assessors to the same aggregator brought them in line, and every subclass built on top (cornerstone content, product pages, store blog posts) inherited the fix automatically.&lt;/p&gt;

&lt;p&gt;The official &lt;a href="https://developer.yoast.com/" rel="noopener noreferrer"&gt;Yoast developer documentation&lt;/a&gt; has more detail on how the SEO analysis pipeline scores individual assessments if you want to dig into the aggregator pattern further.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ultimate Member: A Redirect That Broke Every Page
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/ultimatemember/ultimatemember/pull/1833" rel="noopener noreferrer"&gt;Ultimate Member PR #1833&lt;/a&gt; fixed a bug that redirected logged-out visitors to the homepage on every single post, but only on sites running Spectra block themes. The root cause took some digging. Ultimate Member's &lt;code&gt;filter_protected_posts()&lt;/code&gt; hooks &lt;code&gt;the_posts&lt;/code&gt;, which fires on every &lt;code&gt;WP_Query&lt;/code&gt;, not just the main one. During block template resolution, Spectra runs a secondary query for the UM "User" page, and that page's access settings force a redirect. The redirect logic did not check whether it was running on the main query, so it exited the entire request on a background query meant only for template resolution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE: exits on any query, including secondary ones&lt;/span&gt;
&lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;wp_redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;esc_url_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;add_query_arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'redirect_to'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;urlencode_deep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$curr&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;um_get_core_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'login'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER: only exits on the main query&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;is_object&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;WP_Query&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;is_main_query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;query_vars&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'um_main_query'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;wp_redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;esc_url_raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;add_query_arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'redirect_to'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;urlencode_deep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$curr&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;um_get_core_page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'login'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$filtered_post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;maybe_replace_title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nv"&gt;$filtered_posts&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;apply_filters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'um_access_restricted_post_instance'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$filtered_post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Secondary queries still apply content restriction through title replacement and post hiding, they just no longer call &lt;code&gt;exit()&lt;/code&gt; and kill the page. Direct visits to a genuinely restricted page still redirect correctly, since the main-query check preserves that behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  Gutenberg: Bringing Back the Phone-Shaped Preview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/WordPress/gutenberg/pull/80271" rel="noopener noreferrer"&gt;Gutenberg PR #80271&lt;/a&gt; restored something editors had lost a while back. Mobile and tablet previews in the post editor used to show a phone or tablet shaped frame. A prior change deprecated the old &lt;code&gt;useResizeCanvas&lt;/code&gt; hook, which had injected a fixed device height, and replaced it with a width-only model. The width was correct after that change, but the height just collapsed to fill the editor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// New private selector deriving device-shaped preview height&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCanvasHeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCanvasWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ratios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;mobile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;tablet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getDeviceForWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nx"&gt;ratios&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;ratios&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;device&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mobile gets an 8:5 portrait ratio and tablet gets 4:3, both matching how the editor looked before the regression. The height only applies at the exact preset width set by the Preview dropdown, so dragging the frame to a custom width frees it to fill the editor again. Desktop preview and the Site Editor's separate resizable frame are untouched.&lt;/p&gt;




&lt;h2&gt;
  
  
  ElasticPress: Cleaning Up Translator Comments
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/10up/ElasticPress/pull/4323" rel="noopener noreferrer"&gt;ElasticPress PR #4323&lt;/a&gt; fixed two warnings that showed up when running &lt;code&gt;wp i18n make-pot&lt;/code&gt;. One string had two conflicting translator comments attached to it, and one placeholder had no comment at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE: two different comments for the same string literal&lt;/span&gt;
&lt;span class="cm"&gt;/* translators: %1$s: first feature name, %2$s: second feature name */&lt;/span&gt;
&lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%1$s and %2$s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;elasticpress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... elsewhere in the file:&lt;/span&gt;
&lt;span class="cm"&gt;/* translators: %1$s: comma-separated list of feature names, %2$s: last feature name */&lt;/span&gt;
&lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%1$s and %2$s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;elasticpress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER: one consistent comment for both call sites&lt;/span&gt;
&lt;span class="cm"&gt;/* translators: %1$s: feature name(s), %2$s: last feature name */&lt;/span&gt;
&lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;%1$s and %2$s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;elasticpress&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also added a missing &lt;code&gt;/* translators: %d: Page number. */&lt;/code&gt; comment above a pagination string. Translator comments do not affect runtime behavior, but a clean POT file matters a lot to anyone localizing the plugin, since a missing or duplicate comment leaves translators guessing what a placeholder actually represents.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pods Framework: Getting Ahead of PHP 8.5
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/pods-framework/pods/pull/7550" rel="noopener noreferrer"&gt;Pods PR #7550&lt;/a&gt; was the largest single-purpose change of the month by file count. PHP 8.5 deprecates the &lt;code&gt;(boolean)&lt;/code&gt; cast, and it becomes a fatal error in PHP 9.0. I swapped every occurrence to the canonical &lt;code&gt;(bool)&lt;/code&gt; form across 25 files, 139 occurrences total.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;(bool)&lt;/code&gt; has been valid PHP since the language's earliest versions, so this is a pure one-to-one swap with zero behavior change. No new tests were needed since the runtime result is identical either way. I grepped the full repository afterward to confirm zero remaining &lt;code&gt;(boolean)&lt;/code&gt; occurrences.&lt;/p&gt;

&lt;p&gt;The full list of casts and functions PHP is phasing out lives in the &lt;a href="https://www.php.net/manual/en/migration85.deprecated.php" rel="noopener noreferrer"&gt;official PHP migration guide&lt;/a&gt;, which is worth a scan if you maintain a plugin that has not been updated in a while.&lt;/p&gt;




&lt;h2&gt;
  
  
  WP Rocket: A Tiny Schema Fix With a Real Impact
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/wp-media/wp-rocket/pull/8583" rel="noopener noreferrer"&gt;WP Rocket PR #8583&lt;/a&gt; was the smallest diff of the month, just one line, but it fixed a real WP-CLI compatibility issue. The &lt;code&gt;wp-rocket/get-recommendations&lt;/code&gt; ability declared its input schema as &lt;code&gt;[ 'type' =&amp;gt; 'null' ]&lt;/code&gt;, which caused WP-CLI's ability command to reject it outright with "input must be an object, null given."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BEFORE:&lt;/span&gt;
&lt;span class="s1"&gt;'input_schema'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'null'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;

&lt;span class="c1"&gt;// AFTER:&lt;/span&gt;
&lt;span class="s1"&gt;'input_schema'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An empty array represents "no input properties" in JSON Schema terms and is what WP-CLI expects for an ability that takes no input. One line, but it unblocked WP-CLI from running the ability at all.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned This Month
&lt;/h2&gt;

&lt;p&gt;Twenty-four pull requests across nine plugins taught me a few things worth writing down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security fixes cluster once you start looking.&lt;/strong&gt; Three separate plugins this month had open redirect or direct-access issues that Plugin Check flagged. Once you run the scan on one plugin, you start spotting the same pattern everywhere else. That is not a coincidence, it is what happens when a whole ecosystem grows organically over a decade.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache bugs are the hardest to find and the easiest to miss in review.&lt;/strong&gt; The Brand Nav cache poisoning issue and the LifterLMS media authorization cache bug both needed a persistent object cache active to reproduce. A plugin can look completely correct in testing and still poison a shared cache key for every visitor on a production site with Redis or Object Cache Pro running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duplicate work happens, and that is fine.&lt;/strong&gt; I submitted the exact same LifterLMS redirect fix through two separate pull requests, and both got merged with identical code. Open source is not always a perfectly coordinated pipeline. Small overlaps happen, and maintainers handle them without much drama.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Small PRs still need real testing.&lt;/strong&gt; The WP Rocket one-liner and the ElasticPress translator comment fix both look trivial. Both still needed a clear repro, a clear fix, and clear test steps, because a maintainer reviewing a "small" PR still needs to trust that it actually works.&lt;/p&gt;




&lt;h2&gt;
  
  
  Looking Ahead
&lt;/h2&gt;

&lt;p&gt;July pushed me across more repositories than any month so far, from a REST endpoint that cuts admin requests by 6x to a one-line JSON Schema fix that unblocks WP-CLI. Every plugin here is used by thousands or millions of WordPress sites, and each fix, no matter how small, chips away at friction someone else was living with.&lt;/p&gt;

&lt;p&gt;If any of these bugs sound familiar from your own site, that is exactly the kind of thing worth reporting on a plugin's issue tracker. You do not need to write the fix yourself. Flagging the problem clearly is often the hardest part.&lt;/p&gt;

&lt;p&gt;If you liked this format, take a look at my &lt;a href="https://faisalahammad.com/open-source-wordpress-contribution-may-2026/" rel="noopener noreferrer"&gt;May 2026 open source recap&lt;/a&gt; and my &lt;a href="https://faisalahammad.com/co-authors-plus-contributions/" rel="noopener noreferrer"&gt;Co-Authors Plus contributions write-up&lt;/a&gt; for more real code from past months.&lt;/p&gt;

&lt;p&gt;For the official rules WordPress.org uses to review plugins, the &lt;a href="https://wordpress.org/plugins/plugin-check/" rel="noopener noreferrer"&gt;Plugin Check plugin page&lt;/a&gt; is the best place to start if you want to run these same checks against your own plugin.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to Allow “www.” in the Website Field in Gravity Forms</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Thu, 29 Jan 2026 03:50:50 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-to-allow-www-in-the-website-field-in-gravity-forms-1b31</link>
      <guid>https://dev.to/faisalahammad/how-to-allow-www-in-the-website-field-in-gravity-forms-1b31</guid>
      <description>&lt;p&gt;Allow "&lt;a href="http://www." rel="noopener noreferrer"&gt;www.&lt;/a&gt;" in the Website Field by accepting URLs that start with "www" even when users omit the protocol. When creating contact forms or user-input forms on websites, it’s common to include a field for users to enter their website URL. Many form plugins, including &lt;a href="https://faisalahammad.com/category/gravity-forms/" rel="noopener noreferrer"&gt;Gravity Forms&lt;/a&gt; for WordPress, validate this website field to ensure users enter a properly formatted URL. However, this validation can sometimes cause issues for users who enter URLs beginning with “www” without specifying the full protocol (e.g., "https://").&lt;/p&gt;

&lt;p&gt;This article explains how to customize Gravity Forms’ website field validation to allow URLs starting with “www.” without requiring the “https://” prefix. You’ll also find step-by-step instructions and code snippets that you can add to your WordPress child theme or via a plugin like Code Snippets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customizing Validation for “www.” URLs
&lt;/h2&gt;

&lt;p&gt;The good news is that Gravity Forms provides hooks and filters that allow developers to customize validation rules. You can add a filter that intercepts the website field validation process and accepts URLs starting with “www.” by automatically prepending the “https://” protocol internally before validating.&lt;/p&gt;

&lt;p&gt;Here is the exact code snippet you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;add_filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'gform_field_validation'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$field&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="s1"&gt;'website'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'is_valid'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;preg_match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'/^www\./i'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$url_with_protocol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'https://'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nb"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;GFCommon&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;is_valid_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$url_with_protocol&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'is_valid'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'message'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How This Code Works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The filter hooks into gform_field_validation, which runs during the validation of each form field.&lt;/li&gt;
&lt;li&gt;It checks if the field is of type website.&lt;/li&gt;
&lt;li&gt;If the validation failed ($result['is_valid'] is false) but the input starts with “www.”, it prepends “https://”.&lt;/li&gt;
&lt;li&gt;Using GFCommon::is_valid_url(), it validates the updated URL.&lt;/li&gt;
&lt;li&gt;If valid, it sets the validation result to true and clears any error message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach ensures that users entering URLs like &lt;a href="http://www.example.com" rel="noopener noreferrer"&gt;www.example.com&lt;/a&gt; will pass validation without needing to type the full protocol.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement This in Your Website
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Method 1: Add to Child Theme’s functions.php File
&lt;/h3&gt;

&lt;p&gt;If you have access to your child theme’s files, add the above code snippet at the end of your functions.php file. Make sure to back up your site before editing theme files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2: Use a Code Snippets Plugin
&lt;/h3&gt;

&lt;p&gt;For a safer and more manageable approach, use a WordPress plugin such as &lt;a href="https://wordpress.org/plugins/code-snippets/" rel="noopener noreferrer"&gt;Code Snippets&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install and activate &lt;a href="https://wordpress.org/plugins/code-snippets/" rel="noopener noreferrer"&gt;Code Snippets&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Go to &lt;em&gt;Snippets &amp;gt; Add New&lt;/em&gt; in your WordPress admin panel.&lt;/li&gt;
&lt;li&gt;Paste the code snippet into the editor.&lt;/li&gt;
&lt;li&gt;Save and activate the snippet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This method avoids touching theme files and makes it easy to manage custom PHP code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu6mdsa6jxlo8c9c4dev.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu6mdsa6jxlo8c9c4dev.jpg" alt="Allow " width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions (FAQ)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Q1: Why does Gravity Forms require URLs to start with “https://”?&lt;/strong&gt;&lt;br&gt;
By default, Gravity Forms validates URLs strictly to ensure proper formatting and security protocols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q2: Can I allow other URL formats besides “www.”?&lt;/strong&gt;&lt;br&gt;
Yes, you can customize validation further using similar filter hooks depending on your needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q3: Will this code affect other types of fields?&lt;/strong&gt;&lt;br&gt;
No, this code only targets fields of type “website” in Gravity Forms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q4: What if users enter invalid URLs starting with “www.”?&lt;/strong&gt;&lt;br&gt;
The code still validates URLs using Gravity Forms’ internal function, so invalid URLs will be rejected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Allowing users to enter URLs starting with “www.” in your Gravity Forms website fields improves user experience and reduces unnecessary validation errors. By adding a simple filter hook in your child theme or using a Code Snippets plugin, you can easily modify Gravity Forms’ default behavior while keeping URL validation robust.&lt;/p&gt;

&lt;p&gt;Feel free to reach out if you encounter any issues or want help with other customization!&lt;/p&gt;

</description>
      <category>gravityforms</category>
      <category>wordpress</category>
      <category>wordpressplugin</category>
      <category>plugindevelopment</category>
    </item>
    <item>
      <title>How to Get Top VPNs for FREE?</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Tue, 25 Nov 2025 05:35:16 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-to-get-top-vpns-for-free-a8b</link>
      <guid>https://dev.to/faisalahammad/how-to-get-top-vpns-for-free-a8b</guid>
      <description>&lt;p&gt;Would you like to get the best VPNs for free or receive a full refund after 3-4 months while still having access to use them for the rest of your purchase plan? The following VPNs currently offer the cashback amounts listed below. These amounts may change when you check.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;ExpressVPN - 100%&lt;/li&gt;
&lt;li&gt;Surfshark VPN - 100%&lt;/li&gt;
&lt;li&gt;Private Internet Access (PIA) - 100%&lt;/li&gt;
&lt;li&gt;CyberGhost VPN - 100%&lt;/li&gt;
&lt;li&gt;FastestVPN - 100%&lt;/li&gt;
&lt;li&gt;NordVPN - 95%&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 1: Create an Account
&lt;/h2&gt;

&lt;p&gt;First, sign up for a free account on &lt;a href="https://faisalahammad.com/go/cashback" rel="noopener noreferrer"&gt;TopCashBack&lt;/a&gt;. If you already have an account, skip to Step 3. TopCashBack handles the cashback process and supports multiple payout methods, including PayPal, Virtual Visa Prepaid Card, ACH-supported bank accounts, and gift cards.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FYI, TopCashBack USA has 13,397 ratings on Trustpilot with a 4.6 out of 5 rating, and TopCashBack UK has 157,001 reviews with a 4.5 out of 5 rating.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 2: Verify Your Account
&lt;/h2&gt;

&lt;p&gt;Complete your account verification by adding the following information:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full name
&lt;/li&gt;
&lt;li&gt;Date of birth&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: You do not need to add &lt;strong&gt;your address&lt;/strong&gt;. Even if you are outside the USA, it will not affect receiving your cashback.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This verification ensures you can claim full cashback on every purchase without issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add Payment Details for Cashback Withdrawal
&lt;/h2&gt;

&lt;p&gt;Go to the &lt;a href="https://www.topcashback.com/account/paymentdetails/" rel="noopener noreferrer"&gt;Payment Details&lt;/a&gt; page and add your withdrawal information. If you want to withdraw via PayPal, just add your PayPal email.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to withdraw cashback to a Virtual Visa Prepaid Card, you don’t need to add payment details now. You can select Virtual Visa later for withdrawal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftil6k1f8k8h4d0v6fwxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftil6k1f8k8h4d0v6fwxq.png" alt="Virtual Visa Prepaid Card" width="799" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  For Bank withdrawals, enter:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Account Holder’s Name (must exactly match your bank account)
&lt;/li&gt;
&lt;li&gt;Account Name (can be any identifier like Wise, Payoneer, nSave, ElevatePay)
&lt;/li&gt;
&lt;li&gt;Routing Number
&lt;/li&gt;
&lt;li&gt;Account Number
&lt;/li&gt;
&lt;li&gt;Account Type (usually “Checking”)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyaj758wgi1pergaa5fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftyaj758wgi1pergaa5fg.png" alt="Bank Details" width="800" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double-check this info to avoid withdrawal failures or delays, ensuring smooth cashback claims on every AppSumo purchase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Temporarily Disable Ads &amp;amp; Tracker Blockers
&lt;/h2&gt;

&lt;p&gt;Disable any ad blockers or tracker blockers in your browser or computer temporarily. These can block the tracking needed for your purchase to qualify for cashback. Disabling blockers increases the chance of receiving VPN cashback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Activate Cashback
&lt;/h2&gt;

&lt;p&gt;Visit your desired VPN page through the TopCashBack site and click the “Get up to 100% Cash Back” button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lhufbtp181lj33sl0l2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4lhufbtp181lj33sl0l2.jpg" alt="VPN Cashback" width="800" height="578"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Cashback percentages may vary over time. You will receive the &lt;strong&gt;exact percentage shown at purchase time&lt;/strong&gt;. Following this activation step is crucial to claim full cashback on every AppSumo purchase.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 6: Make the Purchase
&lt;/h2&gt;

&lt;p&gt;Shop for any VPN without limits. You can purchase the same items multiple times using new email addresses. After purchase, cashback will appear in your TopCashBack account within 2-48 hours and will become withdrawable in about 14-16 weeks. Withdrawals typically process in 2 business days.&lt;/p&gt;

&lt;p&gt;When your cashback posts, you can confirm that you successfully claimed VPN cashback for your purchase.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Using third-party coupon codes will void your cashback. Avoid coupons to ensure full cashback and claim full cashback on every VPN purchase. You may use only the coupon codes listed on the TopCashBack VPNs page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Withdraw Your Cashback
&lt;/h2&gt;

&lt;p&gt;After receiving the email confirming your purchase tracking, visit your &lt;a href="https://www.topcashback.com/account/earnings/" rel="noopener noreferrer"&gt;TopCashBack Earnings&lt;/a&gt; page to see important details: retailer’s name, purchase date, purchase amount, and cashback amount. Expanding the details shows the estimated payout speed and order ID.&lt;/p&gt;

&lt;p&gt;After about 14 to 16 weeks, TopCashBack will email you when your balance is available for withdrawal. On the Earnings page, a "Cash Out" button will appear at the top. Click it to choose how much money you want to withdraw or if you want to donate.&lt;/p&gt;

&lt;p&gt;Next, select a payment method. One option is the ACH method, which shows your previously saved bank account info. Confirming this will process your payout; funds should arrive within two days.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3abzsy57zirgezb73f87.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3abzsy57zirgezb73f87.png" alt="Cashback withdraw" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Shopping via computer is recommended. Buying from mobile devices often causes tracking issues.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is there a chance I could be scammed?
&lt;/h3&gt;

&lt;p&gt;You will never be scammed because payments go directly to AppSumo, not TopCashBack. Even if TopCashBack disappears, you will still have access to your purchased products. TopCashBack USA has over 13,397 ratings on Trustpilot with an average rating of 4.6 out of 5 (&lt;a href="https://www.trustpilot.com/review/topcashback.com" rel="noopener noreferrer"&gt;https://www.trustpilot.com/review/topcashback.com&lt;/a&gt;). Their &lt;a href="https://www.trustpilot.com/review/www.topcashback.co.uk" rel="noopener noreferrer"&gt;UK site&lt;/a&gt; has a 4.5 out of 5 rating from over 157,001 reviews. There is no risk of being scammed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do they offer cashback?
&lt;/h3&gt;

&lt;p&gt;They partner with American companies and pay bonuses to drive large volumes of traffic. They then share a portion with customers as cashback. You can find more details about lead generation costs on their help page: &lt;a href="https://www.topcashback.com/help/" rel="noopener noreferrer"&gt;https://www.topcashback.com/help/&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What if my cashback doesn’t show?
&lt;/h3&gt;

&lt;p&gt;If your cashback doesn’t appear after 72 hours, submit a &lt;a href="https://www.topcashback.com/account/enquiries/missingcashbackclaims/submit/" rel="noopener noreferrer"&gt;Missing Cashback Claim form&lt;/a&gt; on TopCashBack. This may delay cashback availability by another 4-6 weeks, but rest assured you will receive it. Filing a claim is how you recover and claim full cashback on any AppSumo purchase that didn’t track initially.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you face any issues, please leave a comment below, so I can help you.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>vpn</category>
      <category>free</category>
      <category>freebies</category>
      <category>tools</category>
    </item>
    <item>
      <title>How much PHP knowledge is needed for WordPress and where can you easily learn PHP for WordPress?</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Tue, 30 Sep 2025 14:51:19 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-much-php-knowledge-is-needed-for-wordpress-and-where-can-you-easily-learn-php-for-wordpress-4708</link>
      <guid>https://dev.to/faisalahammad/how-much-php-knowledge-is-needed-for-wordpress-and-where-can-you-easily-learn-php-for-wordpress-4708</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;💡 To learn WordPress theme and plugin development, the following PHP stuff would be more than sufficient. This guideline is provided by &lt;strong&gt;Kamal Ahmed&lt;/strong&gt;, who has worked for &lt;strong&gt;WPDevelopers, rtCamps, UberSuggest, SiteCare&lt;/strong&gt;, and other companies.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Variables &amp;amp; Data Types&lt;/strong&gt;: (string, integer, float, array, object). Minimum 15 array function &amp;amp; 10 string function.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functions and Scopes.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loops&lt;/strong&gt; (for, foreach, while) &amp;amp; Conditions (if, else, switch, try catch).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working with FORMS&lt;/strong&gt;: get, post, delete, put difference. Validating and Escaping user submitted data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global variables&lt;/strong&gt;: GET, POST, REQUEST differences and usage.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Include and Require&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Object Oriented PHP:&lt;/strong&gt;

&lt;ol&gt;
&lt;li&gt;Class,&lt;/li&gt;
&lt;li&gt;Object,&lt;/li&gt;
&lt;li&gt;Class property,&lt;/li&gt;
&lt;li&gt;Class method,&lt;/li&gt;
&lt;li&gt;Visibility,&lt;/li&gt;
&lt;li&gt;Static,&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A little intermediate&lt;/strong&gt; or relatively less common topics but very important and found sometimes in plugins and themes.

&lt;ol&gt;
&lt;li&gt;Interface, traits, Singleton, Magic Methods, Namespace etc.&lt;/li&gt;
&lt;li&gt;Output Buffering, SESSION, COOKIES, Working with APIs using curl. Date and Times,&lt;/li&gt;
&lt;li&gt;Working with files (opening, reading, writing etc)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The most commonly used Functions for manipulating Arrays in PHP.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Please see the documentation for example and details understanding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Array Functions in PHP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;sizeof($array)&lt;/code&gt;&lt;/strong&gt;: Use this function to find out how many elements an array contains&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_values($array)&lt;/code&gt;&lt;/strong&gt;: Use this function to retrieve all the values from an associative array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_keys($array)&lt;/code&gt;&lt;/strong&gt;: Use this function to retrieve all the keys from an associative array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_pop($array)&lt;/code&gt;&lt;/strong&gt;: Use this function to remove an element from the end of an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_push($array, $value)&lt;/code&gt;&lt;/strong&gt;: This function adds an element to the end of an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_shift($array)&lt;/code&gt;&lt;/strong&gt;: This function removes an element from the beginning of an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_unshift($array, $value)&lt;/code&gt;&lt;/strong&gt;: This function adds an element to the beginning of an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_map($callback, $array1)&lt;/code&gt;&lt;/strong&gt;: This function returns an array containing all the elements of array1 after applying the callback function to each one. You can pass more than one array. The number of parameters that the callback function accepts should match the number of arrays passed to the array_map()&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;sort($array)&lt;/code&gt;&lt;/strong&gt;: This function sorts the elements of an array in ascending order. String values will be arranged in ascending alphabetical order. Other sorting functions include &lt;code&gt;asort()&lt;/code&gt;, &lt;code&gt;arsort()&lt;/code&gt;, &lt;code&gt;ksort()&lt;/code&gt;, &lt;code&gt;krsort()&lt;/code&gt; and &lt;code&gt;rsort()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_reverse($array)&lt;/code&gt;&lt;/strong&gt;: This function reverses the order of elements in an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_merge($array)&lt;/code&gt;&lt;/strong&gt;: Use this function when you need to combine data from two or more arrays into a single structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_rand($array)&lt;/code&gt;&lt;/strong&gt;: This function selects one or more random elements from an array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_search($search, $array)&lt;/code&gt;&lt;/strong&gt;: This function searches the values in an array for a match to the search term, and returns the corresponding key if found. If more than one match exists, the key of the first matching value is returned.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_slice($array, $offset, $length)&lt;/code&gt;&lt;/strong&gt;: Use this function to break a larger array into smaller ones.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_unique($array)&lt;/code&gt;&lt;/strong&gt;: Use this function when you need to remove non-unique elements from an array&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;extract($array)&lt;/code&gt;&lt;/strong&gt;: Import variables into the current symbol table from an array. For Better understanding read the doc about this function. It is very nice. Its opposite is &lt;code&gt;compact()&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;array_key_exists($key, $array)&lt;/code&gt;&lt;/strong&gt;: This functions returns TRUE if the given key is set in the array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;in_array($searched_value, $array)&lt;/code&gt;&lt;/strong&gt;: This functions returns TRUE if the given value exists in the array&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The most commonly used Functions for manipulating Strings in PHP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;substr()&lt;/code&gt;&lt;/strong&gt;: This function returns the part of the string as an output.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;strlen()&lt;/code&gt;&lt;/strong&gt;: This function returns the length of the string&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;trim()&lt;/code&gt;&lt;/strong&gt;: This function removes the white-spaces from both start and the end of the string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;ltrim()&lt;/code&gt;&lt;/strong&gt;: This function removes the white-spaces from the left part of the string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;rtrim()&lt;/code&gt;&lt;/strong&gt;: This function removes the white-spaces from the right part of the string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;strtolower()&lt;/code&gt;&lt;/strong&gt;: This function converts the string to lower case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;strtoupper()&lt;/code&gt;&lt;/strong&gt;: This function converts the string to upper case&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;str_replace()&lt;/code&gt;&lt;/strong&gt;: The str_replace() function replaces some characters with some other characters in a string.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;explode()&lt;/code&gt;&lt;/strong&gt;: This function breaks the string into array on the basis of delimiter passed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;implode()&lt;/code&gt;&lt;/strong&gt;: This function join array elements with a string on the basis of delimiter passed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;PHP for Beginners (2023 Edition)&lt;/strong&gt; by Jeffery Way&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PL3VM-unCzF8ipG50KDjnzhugceoSG3RTC" rel="noopener noreferrer"&gt;PHP for Beginners (2023 Edition)&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Learn PHP The Right Way&lt;/strong&gt; by Gio&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLr3d3QYzkw2xabQRUpcZ_IBk9W50M9pe-" rel="noopener noreferrer"&gt;Learn PHP The Right Way - Full PHP Tutorial For Beginners &amp;amp; Advanced&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Credits: &lt;a href="https://www.facebook.com/kamalahmedpms" rel="noopener noreferrer"&gt;Kamal Ahmed&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>wordpress</category>
      <category>wordpressplugindevelopment</category>
      <category>php</category>
      <category>programming</category>
    </item>
    <item>
      <title>ইংরেজিতে দক্ষতা বাড়ানোর পরিপূর্ণ গাইডলাইন</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Fri, 19 Sep 2025 13:23:54 +0000</pubDate>
      <link>https://dev.to/faisalahammad/inrejite-dksstaa-baaddaanor-pripuurnn-gaaiddlaain-2e3p</link>
      <guid>https://dev.to/faisalahammad/inrejite-dksstaa-baaddaanor-pripuurnn-gaaiddlaain-2e3p</guid>
      <description>&lt;p&gt;ইংরেজি যেহেতু আমাদের মাতৃভাষা না, তাই এই ভাষা শেখা টা একটু কষ্টসাধ্য। তবে বর্তমানে অনেক ফ্রি অ্যাপস, ভিডিও বা কোর্স আছে যেগুলো ইউজ করে দ্রুত সেই সমস্যার কাটিয়ে উঠা সম্ভব। আমাদের উচ্চারণ বা ফ্লুয়েন্সি নেটিভদের মতো হবে না, বা সেটা হয়ত অনেক লং টার্ম গোল হতে পারে। আমাদের উচিত ২য় ভাষা হিসাবে যতটুকু জানলে আমাদের পড়াশোনা বা চাকুরির ক্ষেত্রে সাহায্য করে সেটুকু আগে রপ্ত করা। তারপর ধীরধীরে আরও উন্নতি করতে করতে এক সময় ইংরেজির দক্ষতা আরও উপরে নিয়ে যাওয়া। &lt;/p&gt;

&lt;p&gt;লেখাটা মূলত আমার &lt;a href="https://github.com/faisalahammad/wordpress-support-engineer-resources" rel="noopener noreferrer"&gt;WordPress Support Engineer Resources&lt;/a&gt; এর অংশ বিশেষ। যারা নিজেদের সাপোর্ট ইঞ্জিনিয়ার হিসাবে গড়ে তুলতে চান, তারা উক্ত রিসোর্স ফলো করতে পারেন।&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Learn English: A Structured Approach
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Explanation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;🆓 - Free&lt;/li&gt;
&lt;li&gt;👌 - Recommended&lt;/li&gt;
&lt;li&gt;❤️ - Favorite&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Set Clear Goals
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Determine your desired level (beginner, conversational, fluent).&lt;/li&gt;
&lt;li&gt;Set a daily practice time such as &lt;strong&gt;10-30 minutes&lt;/strong&gt; per day.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Start with Vocabulary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Focus on &lt;strong&gt;high-frequency words&lt;/strong&gt; used in everyday conversations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=mlWbOI7AxcA&amp;amp;list=PLInvtdKpyzgPkvOFxrUBYogvUKLFf5IzU&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Learn Vocabulary&lt;/a&gt; by Maisuns world 🆓 👌&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=4m9tDeLEbI4&amp;amp;list=PLMR3lYBIrUziW6qYc-gccRiGX74AQtzaf" rel="noopener noreferrer"&gt;English Vocabulary&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=SLo1IAQ_U2k&amp;amp;list=PL5bLw9Uguvv3kSpd1tM79vb0DGAG67dab&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Learn Basic English Vocabulary&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=7P-R0Z5zXig&amp;amp;list=PL5bLw9Uguvv1RUj4awa-xeNSn8tnhdwRP&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Learn Basic English Vocabulary - Season 2&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=HpbKigw8yHQ&amp;amp;list=PL5bLw9Uguvv0hbDdFVrxv5UeIXUm6BoJh&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Remember English Vocabulary - Word Association&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=HK7W1qHuTwY&amp;amp;list=PL5bLw9Uguvv2sGuwT2n5cP0ummdvtY0Jd&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Words for Every Day&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=-YMZJ2eM-aA&amp;amp;list=PL5bLw9Uguvv0Tyf6ESCAgqd2gEpyew9D2&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;American Holiday Words&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Move on to Basic Grammar
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Learn &lt;strong&gt;sentence structure&lt;/strong&gt; (Subject + Verb + Object).&lt;/li&gt;
&lt;li&gt;Focus on &lt;strong&gt;common tenses&lt;/strong&gt;: present, past, future.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.freecodecamp.org/learn/a2-english-for-developers/" rel="noopener noreferrer"&gt;A2 English for Developers&lt;/a&gt; by FreeCodeCamp 🆓 👌 ❤️&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://10minuteschool.com/en/product/english-grammar-fundamentals/" rel="noopener noreferrer"&gt;English Grammar Fundamentals&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://10minuteschool.com/en/product/complete-english-grammar-course/" rel="noopener noreferrer"&gt;Academic English Grammar&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=SNWS-LUj0_A&amp;amp;list=PL5bLw9Uguvv1ZK1UDgkcO9IrjoKyP5zT1&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Know Your Verbs!&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=JkURo4oTKNk&amp;amp;list=PL5bLw9Uguvv3XwnldAykX_WOM7T0Mcbp9&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Grammar Made Easy with Alisha&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=yFak2AJEr30&amp;amp;list=PL5bLw9Uguvv1PNOFB6NaiddASdg7ASsmR&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Master English Grammar&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Learn Common Phrases and Idioms
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Practice daily conversation phrases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://10minuteschool.com/en/product/idioms-phrases/" rel="noopener noreferrer"&gt;Idioms and Phrases&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=tnUk19S6hpw&amp;amp;list=PL5bLw9Uguvv2G4L6rlICvI3QfKdEwFu5b&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Conversational Phrases&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=ylHnC1lTODs&amp;amp;list=PLD_5T89Ssbn3F830QF2h_xoJJdbteSeg7&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Learn English Idioms&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Develop Listening Skills
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Listen to &lt;strong&gt;English podcasts&lt;/strong&gt; or &lt;strong&gt;audiobooks&lt;/strong&gt;. Try &lt;a href="https://www.podcastsinenglish.com/" rel="noopener noreferrer"&gt;Podcasts in English&lt;/a&gt; or &lt;a href="https://www.bbc.co.uk/podcasts" rel="noopener noreferrer"&gt;BBC Podcasts&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Watch videos with &lt;strong&gt;subtitles&lt;/strong&gt; (e.g., on &lt;a href="https://www.youtube.com/" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Resourses:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=9cGXFoYjru8&amp;amp;list=PL5bLw9Uguvv11fx6bS68yK5OeXAqLU3mW&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Listening Comprehension for Absolute Beginners&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=i-zpCZRs2Io&amp;amp;list=PL5bLw9Uguvv3Mjnzd0YGmu-lGRWRWv-cU&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Listening Comprehension for Beginners&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=ScZ48qN_ZWA&amp;amp;list=PL5bLw9Uguvv1VRVl3gHBt-FcM__k3UY9L&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Listening Comprehension for Intermediate Learners&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=9IsgusPAFx0&amp;amp;list=PL5bLw9Uguvv0Q6yEZUcNMs0uQDYpffIx4&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;English Listening Comprehension for Advanced Learners&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Practice Speaking
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use language exchange platforms (Mobile Apps) like:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tandem.net/" rel="noopener noreferrer"&gt;Tandem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.hellotalk.com/" rel="noopener noreferrer"&gt;HelloTalk&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://play.google.com/store/apps/details?id=com.amarpartner.app&amp;amp;hl=en_GB" rel="noopener noreferrer"&gt;Amar Partner&lt;/a&gt; 👌 🆓 ❤️&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://10minuteschool.com/product/english-for-everyday/" rel="noopener noreferrer"&gt;English for Everyday&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://interactivecares.com/courseDetails/152" rel="noopener noreferrer"&gt;English Fluency Development&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://interactivecares.com/courseDetails/80" rel="noopener noreferrer"&gt;English Skills for Academic and Corporate Success&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=iizWVpqGHcY&amp;amp;list=PLD_5T89Ssbn0MAiuPFuiibDOzKYMfzgnQ&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Speaking Practice - Speak With Me!&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Enhance Reading Skills
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Gradually read news or short stories.

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.aljazeera.com/" rel="noopener noreferrer"&gt;Al Jazeera&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.dhakatribune.com/" rel="noopener noreferrer"&gt;Dhaka Tribune&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bdnews24.com/" rel="noopener noreferrer"&gt;BDNews24&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://thebangladeshtoday.com/" rel="noopener noreferrer"&gt;The Bangladesh Today&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resourses:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=IfDJ5mgMeQ8&amp;amp;list=PL5bLw9Uguvv1pusxFOXlRr6hKbnyEDPpO&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;American English Reading Practice for Absolute Beginners&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=URXt4Y5xuHc&amp;amp;list=PL5bLw9Uguvv20YNJzjrkEdsrZ5ffG_-eU&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;American English Intermediate Reading Practice&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=vYsCxYrzOls&amp;amp;list=PL5bLw9Uguvv3pJd1FZjbEJbv8qcrIvjgQ&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;American English Advanced Reading Practice&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Work on Writing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Start with simple tasks like a &lt;strong&gt;daily journal&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Progress to &lt;strong&gt;emails&lt;/strong&gt;, &lt;strong&gt;blog posts&lt;/strong&gt;, or even &lt;strong&gt;short essays&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resourses:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/playlist?list=PLz49jcnhCN-iPNYD6RU2xqoik144fEraI" rel="noopener noreferrer"&gt;IELTS - Writing Test Preparation&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Improve Pronunciation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use apps like &lt;a href="https://www.elsaspeak.com/" rel="noopener noreferrer"&gt;Elsa Speak&lt;/a&gt; for phonetics and pronunciation practice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://10minuteschool.com/en/product/pronunciation-mistakes/" rel="noopener noreferrer"&gt;Pronunciation Mistakes&lt;/a&gt; 🆓&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=n4NVPg2kHv4&amp;amp;list=PLD_5T89Ssbn3GrxrT28k9xEKwizeoPCjc&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;Pronunciation Practice!&lt;/a&gt; 🆓&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ❤️ Favorite Resourses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Apps
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=com.duolingo&amp;amp;hl=en_GB" rel="noopener noreferrer"&gt;Doulingo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=us.nobarriers.elsa&amp;amp;hl=en_GB" rel="noopener noreferrer"&gt;Elsa Speak&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://play.google.com/store/apps/details?id=ridmik.dovashiapp&amp;amp;hl=en&amp;amp;gl=US" rel="noopener noreferrer"&gt;দোভাষী: Dovashi Spoken English&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Websites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.englishclass101.com" rel="noopener noreferrer"&gt;EnglishClass101&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://10minuteschool.com/en/categories/language-learning/?tab=free" rel="noopener noreferrer"&gt;10 Minute School&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  YouTube Channels
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@MunzereenShahid" rel="noopener noreferrer"&gt;Munzereen Shahid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@maisunsworld" rel="noopener noreferrer"&gt;Maisuns World&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@EnglishClass101" rel="noopener noreferrer"&gt;Learn English with EnglishClass101.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@EnglishwithLucy/featured" rel="noopener noreferrer"&gt;English with Lucy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@linguamarina" rel="noopener noreferrer"&gt;linguamarina&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/@mmmEnglish_Emma" rel="noopener noreferrer"&gt;mmmEnglish&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This structured plan will help you learn English step-by-step, whether you're aiming for basic conversational skills or advanced fluency. Stay consistent, immerse yourself in the language, and use the recommended resources to track your progress.&lt;/p&gt;

</description>
      <category>english</category>
      <category>learnenglish</category>
      <category>englishlab</category>
      <category>language</category>
    </item>
    <item>
      <title>Let’s find out the best FREE WordPress Form plugin</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Fri, 19 Sep 2025 13:15:15 +0000</pubDate>
      <link>https://dev.to/faisalahammad/lets-find-out-the-best-free-wordpress-form-plugin-dj9</link>
      <guid>https://dev.to/faisalahammad/lets-find-out-the-best-free-wordpress-form-plugin-dj9</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwjz85375kiwutd1nmes.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkwjz85375kiwutd1nmes.jpg" alt="FREE VS Lite (1)|690x388" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WordPress form plugins are no longer limited to just contact forms. Currently, you can use form plugins for booking, subscriptions, CRM integration, product sales, and more! If you want, you can even use the form plugin's API to create your own integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free or Lite?
&lt;/h2&gt;

&lt;p&gt;There are many free form plugins for WordPress. But most are not free, rather lite versions. To be direct, the plugin available on WordPress.org is usually a limited feature lite version, where you won't get many things. You have to purchase the paid version to unlock all features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limited Fields
&lt;/h2&gt;

&lt;p&gt;Even if the plugin name doesn't include "Lite", the following plugins don't allow all fields, settings or options such as form submission, reCaptcha, pre-made form templates, form submission export. Many basic fields are also locked. Only installing the pro version allows using all fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/bit-form/" rel="noopener noreferrer"&gt;Bit Form&lt;/a&gt; (43 total fields, 7 locked fields)

&lt;ul&gt;
&lt;li&gt;Mollie, Advanced, Singature, PayPal, RazorPay, Stripe, Draft Button&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/fluentform/" rel="noopener noreferrer"&gt;Fluent Forms&lt;/a&gt; (48 total fields, 27 locked fields)

&lt;ul&gt;
&lt;li&gt;Image Upload, File Upload, Phone, reCaptcha, hCaptcha, Turnstile, Shortcode, Action Hook, Form Step, Ratings, Checkable Grid, Range Slider, Net Promoter Score, Chained Select, Color Picker, Repeat Field, Post/CPT Selection, Quiz Score, Rich Text Input, Save &amp;amp; Resume, Payment Item, Subscription, Custom Payment Amount, Item Quantity, Payment Method, Payment Summary, Coupon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/formidable/" rel="noopener noreferrer"&gt;Formidable Forms&lt;/a&gt; (42 total fields, 27 locked fields)

&lt;ul&gt;
&lt;li&gt;File Upload, Rich Text, Time, Star Rating, Toggle, Lookup, Section, Embed Form, NPS, Tags, Summary, AI, Ranking, Date, Scale, Slider, Dynamic, Repeater, Page Break, Likert Scale, Password, Address, Signature, Appointment, Product, Quantity, Total&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/forminator/" rel="noopener noreferrer"&gt;Forminator Forms&lt;/a&gt; (29 total fields, 1 locked field)

&lt;ul&gt;
&lt;li&gt;eSignature&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/ninja-forms/" rel="noopener noreferrer"&gt;Ninja Forms&lt;/a&gt; (30 total fields, 2 locked fields)

&lt;ul&gt;
&lt;li&gt;File Upload, Save&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/weforms/" rel="noopener noreferrer"&gt;weForms&lt;/a&gt; (31 total fields, 16 locked fields)

&lt;ul&gt;
&lt;li&gt;Repeat Field, Numeric Field, File Upload, Address Field, Country List, Google Map, Step Start, reCaptcha, Shortcode, HP Anti-Spam, Action Hooks, Terms and Conditions, Ratings, Linear Scale, Checkbox Grid, Multiple Choice Grid&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/wpforms-lite/" rel="noopener noreferrer"&gt;WPForms Lite&lt;/a&gt; (40 total fields, 24 locked fields)

&lt;ul&gt;
&lt;li&gt;Phone, Date / Time, File Upload, Layout, Page Break, Rich Text, HTML, Rating, Custom Captcha, Likert Scale, Address, Website / URL, Password, Repeater, Section Divider, Content, Entry Preview, Hidden Field, Signature, Net Promoter Score, PayPal Commerce, Square, Authorize.net, Coupon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/ws-form/" rel="noopener noreferrer"&gt;WS Form Lite&lt;/a&gt; (55 total fields, 35 unavailable field)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a51yuc5toubtpmuaacq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9a51yuc5toubtpmuaacq.jpg" alt="Formidable Forms|690x406" width="800" height="472"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Formidable Forms Date field locked&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn19sbuh3m2b8786w14gn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn19sbuh3m2b8786w14gn.jpg" alt="WPForms|690x478" width="799" height="555"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;WPForms Entries locked&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz2uwqxb0u4od6wfzy1m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frz2uwqxb0u4od6wfzy1m.jpg" alt="weForms|690x347" width="800" height="403"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;weForms locked some essential fields&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Free Add-ons
&lt;/h2&gt;

&lt;p&gt;How developer-friendly a form plugin is can be somewhat gauged by looking at community add-ons. Many form plugins have very rich documentation, but they don't provide developer licenses or any support for add-on development for third-party developers. On WordPress.org, you can find quite a few third-party plugins or add-ons for Fluent Forms, Formidable, Forminator, Ninja Forms, and WPForms plugins, which help extend the default features of the plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Support
&lt;/h2&gt;

&lt;p&gt;Another important issue is plugin support. It turns out I got into trouble, but there's no chance of getting help. Free form plugins will only support you in the WordPress.org support forum, and that's always low priority. As a result, you often have to sit with an open ticket for a long time on urgent issues. Also, since WordPress forums have some specific rules, outside of which plugin companies can't offer support, you have many limitations in terms of getting support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Plugin Name&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;View Entries&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Export Entries&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Embed Entries&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Import/Export Form&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Free Templates&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Forum Support&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Ticket Support&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;WPML Support&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Gutenberg Block&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bit Form&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fluent Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formidable Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forminator Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ninja Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;weForms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WPForms Lite&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WS Form Lite&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Selection
&lt;/h2&gt;

&lt;p&gt;Considering all the above issues, the Ninja Forms plugin allows us to use all fields for free. You don't need a pro version to access any features, and they don't sell a pro version either. You'll get everything from reCaptcha, form submission, submission export to pre-made templates for free. &lt;em&gt;You won't see any notice to upgrade to the pro version anywhere.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And even if you're a free user, you'll get &lt;a href="https://ninjaforms.com/account/support/" rel="noopener noreferrer"&gt;free support&lt;/a&gt; from their website along with the WordPress.org support forum. This means you won't have to sit with an open ticket for &lt;em&gt;limited&lt;/em&gt; support on any urgent issue.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If any information above is incorrect, please let me know in the comments, I'll edit it. You can also inform me if any new features have been added to any form after I wrote my post. Thank you.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>wordpress</category>
      <category>wordpressform</category>
      <category>formplugin</category>
      <category>formbuilder</category>
    </item>
    <item>
      <title>How to Protect Sensitive Ninja Forms File Uploads in WordPress</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Fri, 31 Jan 2025 05:07:28 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-to-protect-sensitive-ninja-forms-file-uploads-in-wordpress-49bj</link>
      <guid>https://dev.to/faisalahammad/how-to-protect-sensitive-ninja-forms-file-uploads-in-wordpress-49bj</guid>
      <description>&lt;p&gt;When handling Ninja Forms file uploads on WordPress websites, ensuring the privacy of sensitive documents becomes paramount. This guide explores how to secure these uploaded files, making them inaccessible to search engines while maintaining full functionality of your forms.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Security Concern
&lt;/h2&gt;

&lt;p&gt;When users upload files through Ninja Forms, these documents are stored in your website's &lt;code&gt;wp-content/uploads/ninja-forms&lt;/code&gt; directory. While Ninja Forms implements basic security measures, there's always a possibility that these files could be discovered through search engines if additional precautions aren't taken.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Simple Yet Effective Solution
&lt;/h2&gt;

&lt;p&gt;You can implement two powerful methods to prevent search engines from indexing your sensitive uploads. These methods work together to create a robust security layer that keeps your files private.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Utilizing robots.txt
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;robots.txt&lt;/code&gt; file is like a set of instructions for search engines, telling them which parts of your website they should or shouldn't look at. To protect your Ninja Forms uploads, you'll need to add a simple directive to your &lt;code&gt;robots.txt&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User-agent: *
Disallow: /wp-content/uploads/ninja-forms/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code tells all search engines (that's what the asterisk means) to stay away from your Ninja Forms upload directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCleanShot-2025-01-31-at-10.52.59%402x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCleanShot-2025-01-31-at-10.52.59%402x.jpg" title="robots.txt file" alt="robots.txt file" width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2: Implementing .htaccess Protection
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;.htaccess&lt;/code&gt; file provides an additional layer of security by sending special headers to browsers and search engines. Create or edit the &lt;code&gt;.htaccess&lt;/code&gt; file in your &lt;code&gt;wp-content/uploads/ninja-forms/&lt;/code&gt; directory and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;IfModule mod_headers.c&amp;gt;
    Header set X-Robots-Tag "noindex, nofollow"
&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code explicitly tells search engines not to index or follow any links to files in this directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCleanShot-2025-01-31-at-10.57.43%402x.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCleanShot-2025-01-31-at-10.57.43%402x.jpg" title=".htaccess file" alt=".htaccess file" width="800" height="173"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Two-Layer Approach Works
&lt;/h2&gt;

&lt;p&gt;Think of it like having both a fence and a security system for your house. The &lt;code&gt;robots.txt&lt;/code&gt; file acts as your fence, providing the first line of defense, while the &lt;code&gt;.htaccess&lt;/code&gt; file works like your security system, adding an extra layer of protection.&lt;/p&gt;

&lt;p&gt;This combination is particularly effective because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It works with all major search engines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It requires no ongoing maintenance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It doesn't affect the functionality of your forms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It keeps your uploads secure without using external services&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Best Practices for File Upload Security
&lt;/h2&gt;

&lt;p&gt;While implementing these protective measures, consider these additional tips:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Regularly review and clean up old uploads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use strong file upload restrictions in Ninja Forms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Monitor your server logs for any unusual access attempts&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Keep WordPress, Ninja Forms, and all plugins updated&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Implementation Tips for Non-Technical Users
&lt;/h2&gt;

&lt;p&gt;If you're not comfortable working with website files, don't worry. Here are your options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ask your web developer to implement these changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Contact your hosting provider's support team&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a website management service&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most hosting providers can implement these changes in just a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Are uploaded files automatically protected in Ninja Forms?
&lt;/h4&gt;

&lt;p&gt;While Ninja Forms has basic security measures, implementing these additional protections ensures maximum security for your uploads.&lt;/p&gt;

&lt;h4&gt;
  
  
  Will these changes affect how my forms work?
&lt;/h4&gt;

&lt;p&gt;No, these security measures only affect how search engines interact with your uploaded files. Your forms will continue to work normally.&lt;/p&gt;

&lt;h4&gt;
  
  
  Do I need both robots.txt and .htaccess files?
&lt;/h4&gt;

&lt;p&gt;While using either method alone provides some protection, implementing both creates a more robust security solution.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can I still access the uploaded files myself?
&lt;/h4&gt;

&lt;p&gt;Yes, these measures only prevent search engines from indexing the files. You can still access them through your WordPress dashboard or direct links.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Implementing these security measures is a crucial step in protecting sensitive information uploaded through your WordPress forms. It's a simple yet effective solution that provides peace of mind for both you and your users, ensuring that confidential documents remain private and secure.&lt;/p&gt;

&lt;p&gt;Remember, when it comes to handling sensitive information, it's always better to implement more security rather than less. These measures help maintain trust with your users while protecting their private information from unauthorized access.&lt;/p&gt;

&lt;p&gt;The post previously published in my blog post here: &lt;a href="https://www.faisalahammad.com/protect-sensitive-ninja-forms-file-uploads-in-wordpress/" rel="noopener noreferrer"&gt;How to Protect Sensitive Ninja Forms File Uploads in WordPress&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>ninjaforms</category>
      <category>wordpressform</category>
      <category>codesnippets</category>
    </item>
    <item>
      <title>How to Disable WordPress RSS Feeds</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Wed, 08 Jan 2025 04:41:39 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-to-disable-wordpress-rss-feeds-1gdg</link>
      <guid>https://dev.to/faisalahammad/how-to-disable-wordpress-rss-feeds-1gdg</guid>
      <description>&lt;p&gt;In today’s digital landscape, website owners often seek ways to manage and control the content available to their audience. One such method is disabling RSS feeds in WordPress. This article will walk you through a simple code snippet that effectively disables all WordPress RSS feeds, ensuring that your content remains exclusive to your website visitors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding RSS Feeds
&lt;/h2&gt;

&lt;p&gt;RSS (Really Simple Syndication) feeds allow users to receive updates from their favorite websites without having to visit them directly. While this feature can be beneficial for some, it may not be suitable for all website owners. Disabling RSS feeds can prevent content scraping and help maintain control over how your content is shared.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Disable RSS Feeds?
&lt;/h2&gt;

&lt;p&gt;There are several reasons why you might consider disabling RSS feeds on your WordPress site:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Content Control&lt;/strong&gt;: By disabling RSS feeds, you retain more control over your content. Visitors will need to visit your site to access your posts and updates, which can increase traffic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prevent Content Scraping&lt;/strong&gt;: Disabling feeds can help protect your content from being copied or scraped by other sites, which is a prevalent issue in the online space.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;User Experience&lt;/strong&gt;: If you prefer that users engage directly with your website rather than through third-party aggregators, disabling feeds can enhance their experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;SEO Considerations&lt;/strong&gt;: While RSS feeds are generally good for SEO, some website owners may feel that they dilute the uniqueness of their content, leading to a stronger focus on direct engagement.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Code Snippet
&lt;/h2&gt;

&lt;p&gt;To disable RSS feeds on your WordPress site, you can use the following PHP code snippet. This code should be added to your theme’s &lt;code&gt;functions.php&lt;/code&gt; file or a custom plugin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Disable WordPress RSS Feeds
 * Description: Completely disables all WordPress RSS feeds, including feeds for posts, comments, and categories.
 * @author Faisal Ahammad &amp;lt;me@faisalahammad.com&amp;gt;
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;wpb_disable_feed&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;wp_die&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'No feed available, please visit our &amp;lt;a href="'&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;get_bloginfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'"&amp;gt;homepage&amp;lt;/a&amp;gt;!'&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_rdf'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_rss'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_rss2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_atom'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_rss2_comments'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;'do_feed_atom_comments'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wpb_disable_feed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Breaking Down the Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Function Definition:&lt;/strong&gt; The function &lt;code&gt;wpb_disable_feed()&lt;/code&gt; is defined to stop the feed from being displayed. It uses &lt;code&gt;wp_die()&lt;/code&gt; to display a message indicating that no feed is available and prompts users to visit the homepage instead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action Hooks:&lt;/strong&gt; The following action hooks are used:

&lt;ul&gt;
&lt;li&gt;do_feed&lt;/li&gt;
&lt;li&gt;do_feed_rdf&lt;/li&gt;
&lt;li&gt;do_feed_rss&lt;/li&gt;
&lt;li&gt;do_feed_rss2&lt;/li&gt;
&lt;li&gt;do_feed_atom&lt;/li&gt;
&lt;li&gt;do_feed_rss2_comments&lt;/li&gt;
&lt;li&gt;do_feed_atom_comments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By adding these hooks, you ensure that all types of feeds are disabled across your site.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement the Solution
&lt;/h2&gt;

&lt;p&gt;You have several options to implement this code:&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Using Code Snippets Plugin (Recommended)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install and activate the &lt;a href="https://wordpress.org/plugins/code-snippets" rel="noopener noreferrer"&gt;Code Snippets&lt;/a&gt; plugin&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Snippets → Add New&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Paste the complete code&lt;/li&gt;
&lt;li&gt;Enable "Only run in admin area"&lt;/li&gt;
&lt;li&gt;Save and activate&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Method 2: Via functions.php
&lt;/h3&gt;

&lt;p&gt;You can add this code to your theme's &lt;code&gt;functions.php&lt;/code&gt; file, but remember that it will stop working if you change themes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Q1: What happens if I disable RSS feeds?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A1:&lt;/strong&gt; Disabling RSS feeds means users will not receive updates through feed readers. They will need to visit your site directly for new content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q2: Can I enable RSS feeds again after disabling them?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A2:&lt;/strong&gt; Yes, you can remove the code snippet from your &lt;code&gt;functions.php&lt;/code&gt; file or Code Snippets plugin to re-enable RSS feeds at any time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q3: Will disabling RSS feeds affect my SEO?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A3:&lt;/strong&gt; Disabling RSS feeds may affect SEO positively or negatively depending on your content strategy. It could lead to increased direct traffic while reducing visibility through feed readers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q4: Is it safe to edit the functions.php file?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A4:&lt;/strong&gt; Yes, but always ensure you have a backup before making changes as incorrect modifications can break your site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Q5: Can I disable specific types of feeds instead of all?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A5:&lt;/strong&gt; Yes, you can choose to disable only specific types of feeds by removing or modifying corresponding action hooks in the code snippet provided.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Disabling RSS feeds in WordPress can be an effective strategy for certain website owners who want to maintain control over their content and enhance user engagement directly on their site. By using the simple PHP code provided, you can easily disable all RSS feeds and redirect visitors to your homepage.&lt;/p&gt;

&lt;p&gt;For more tips on managing your WordPress site, feel free to check out &lt;a href="https://faisalahammad.com" rel="noopener noreferrer"&gt;Faisal Ahammad's blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>codesnippet</category>
      <category>phpoop</category>
    </item>
    <item>
      <title>How to Completely Disable WordPress Admin Notices</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Tue, 07 Jan 2025 08:52:52 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-to-completely-disable-wordpress-admin-notices-50k8</link>
      <guid>https://dev.to/faisalahammad/how-to-completely-disable-wordpress-admin-notices-50k8</guid>
      <description>&lt;p&gt;Are you tired of seeing endless notifications cluttering your WordPress dashboard? Those pesky admin notices from plugins and themes can be distracting and sometimes even overwhelming. Today, I'll show you a practical solution to remove all WordPress admin notices permanently while following best practices.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with WordPress Admin Notices
&lt;/h2&gt;

&lt;p&gt;WordPress admin notices serve an important purpose – they keep us informed about updates, warnings, and important messages. However, when you're managing multiple websites or using several plugins, these notifications can quickly get out of hand. They can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Distract you from important tasks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make it harder to focus on essential dashboard elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a cluttered and messy admin interface&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Slow down your workflow significantly&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The worst part? Some plugins bypass WordPress's standard notification system, making it challenging to manage them effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Disable WordPress Admin Notices
&lt;/h2&gt;

&lt;p&gt;I've developed a simple yet powerful code snippet that completely removes all admin notices from your WordPress dashboard. This solution is different from others because it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Removes ALL types of admin notices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prevents plugins from bypassing the removal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uses multiple approaches to ensure complete removal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follows WordPress coding standards&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Works with the latest WordPress version&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Final Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="cd"&gt;/**
 * Disable Admin Notices WordPress
 * Description: Completely removes all admin notices from the WordPress dashboard,
 * including core WordPress notices and those added by plugins and themes.
 * @author Faisal Ahammad &amp;lt;me@faisalahammad.com&amp;gt;
 */&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Remove all notice actions
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;disable_all_admin_notices&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'all_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'network_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'disable_all_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Add CSS to hide notice elements
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hide_admin_notices_css&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nc"&gt;.notice&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-warning&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-info&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.updated&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.update-nag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_head'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hide_admin_notices_css'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Disable notice output
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;return_false&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'return_false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'all_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'return_false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'return_false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'network_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'return_false'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cd"&gt;/**
 * Remove update nags
 */&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;remove_core_update_notices&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;remove_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'update_nag'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'maintenance_nag'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;add_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_init'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'remove_core_update_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Code Explained
&lt;/h3&gt;

&lt;p&gt;Let's break down the key components of our solution:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Notice Action Removal
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;disable_all_admin_notices&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'all_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'user_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_all_actions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'network_admin_notices'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This function removes all action hooks related to admin notices, preventing them from being displayed in the first place.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. CSS-based Notice Hiding
&lt;/h4&gt;

&lt;p&gt;The snippet includes CSS rules to hide any notices that might slip through:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;function hide_admin_notices_css() {
    ?&amp;gt;
    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="nc"&gt;.notice&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-warning&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.notice-info&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.updated&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.error&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
        &lt;span class="nc"&gt;.update-nag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Update Nag Removal
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;remove_core_update_notices&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;remove_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'update_nag'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;remove_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'admin_notices'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'maintenance_nag'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This specifically targets and removes WordPress core update notifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement the Solution
&lt;/h2&gt;

&lt;p&gt;You have several options to implement this code:&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 1: Using Code Snippets Plugin (Recommended)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install and activate the &lt;a href="https://wordpress.org/plugins/code-snippets" rel="noopener noreferrer"&gt;Code Snippets&lt;/a&gt; plugin&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Navigate to &lt;strong&gt;&lt;em&gt;Snippets → Add New&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the complete code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable "&lt;strong&gt;Only run in administration area&lt;/strong&gt;"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save and activate&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCode-Snippets-scaled.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.faisalahammad.com%2Fwp-content%2Fuploads%2F2025%2F01%2FCode-Snippets-scaled.jpeg" title="Code Snippets" alt="Code Snippets" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Method 2: Via &lt;code&gt;functions.php&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;You can add this code to your theme's &lt;code&gt;functions.php&lt;/code&gt; file, but remember that it will stop working if you change themes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance Impact
&lt;/h2&gt;

&lt;p&gt;The good news is that this solution has minimal impact on your website's performance. It only runs in the admin area and uses efficient hooks and methods to remove notices. The CSS rules are also lightweight and only loaded in the dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Will this remove important security notifications as well?
&lt;/h4&gt;

&lt;p&gt;Yes, this will remove all notifications, including security ones. If you need to keep security notices, you'll need to modify the code to exclude specific notice types.&lt;/p&gt;

&lt;h4&gt;
  
  
  Is it safe to remove all admin notices?
&lt;/h4&gt;

&lt;p&gt;While it's generally safe, you should ensure you have alternative ways to stay updated about important changes and updates on your WordPress site.&lt;/p&gt;

&lt;h4&gt;
  
  
  Will this affect my website's front end?
&lt;/h4&gt;

&lt;p&gt;No, this code only affects the admin dashboard. Your website's front end remains completely unchanged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This solution provides a clean, efficient way to declutter your WordPress dashboard by removing all admin notices. While it's important to stay informed about your website's status, having a clean, distraction-free admin interface can significantly improve your workflow efficiency.&lt;/p&gt;

&lt;p&gt;Remember to regularly check your site's updates and maintenance needs through other means if you implement this solution, as you won't receive the standard WordPress notifications anymore.&lt;/p&gt;

&lt;p&gt;The Post previously published on my blog here: &lt;a href="https://www.faisalahammad.com/completely-disable-wordpress-admin-notices/" rel="noopener noreferrer"&gt;How to Completely Disable WordPress Admin Notices&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>codesnippet</category>
      <category>wordpressnotice</category>
    </item>
    <item>
      <title>কিভাবে ওয়ার্ডপ্রেসের বিভিন্ন টিমে কন্ট্রিবিউশন শুরু করবেন?</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Wed, 23 Oct 2024 16:18:27 +0000</pubDate>
      <link>https://dev.to/faisalahammad/kibhaabe-oyaarddpreser-bibhinn-ttime-knttribiushn-shuru-krben-pmb</link>
      <guid>https://dev.to/faisalahammad/kibhaabe-oyaarddpreser-bibhinn-ttime-knttribiushn-shuru-krben-pmb</guid>
      <description>&lt;p&gt;ওয়ার্ডপ্রেসে বিভিন্ন ভাবে কান্ট্রিবিউট করা যায়। আপনি একজন নন টেক পারসন হলেও সহজেই কান্ট্রিবিউট করতে পারবেন কোন প্রকার কোড না করেই। চলেন তাহলে দেখি কোন কোন রিসোর্স ফলো করে কিভাবে কন্ট্রিবিউট শুরু করতে পারেন।&lt;/p&gt;

&lt;p&gt;আমি #bn_BD polyglots টাইমে GTE হিসাবে আছি। সহজ ভাষার আপনদের থিম/প্লাগিনে কাউকে PTE হিসাবে অ্যাড করতে, কিংবা আপনাদের ট্রান্সলেট করা কোন পেন্ডিং স্ট্রিং আমি অ্যাপ্রুভ করতে পারি। আমার আরেকটা পরিচয় সামনে শেয়ার করব ইনশাআল্লাহ।&lt;/p&gt;

&lt;h2&gt;
  
  
  ১। ছবি তুলে সাবমিট করা
&lt;/h2&gt;

&lt;p&gt;লিঙ্ক: &lt;a href="http://wordpress.org/photos/" rel="noopener noreferrer"&gt;WordPress Photos&lt;/a&gt;&lt;br&gt;&lt;br&gt;
রিসোর্স: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=HC3Cg4qBiQk&amp;amp;list=PLu00CB7MWA3MXvFOkUNdzQ7kXBFrAUDAC&amp;amp;index=2&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz04ic03j70mrsrj7nis5.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ২। থিম/প্লাগিনের ইংলিশ শব্দ গুলো বাংলায় অনুবাদ করা।
&lt;/h2&gt;

&lt;p&gt;লিংক: &lt;a href="https://make.wordpress.org/polyglots/" rel="noopener noreferrer"&gt;Polyglots&lt;/a&gt;&lt;br&gt;&lt;br&gt;
রিসোর্স: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=e5FzKXJ1RJw&amp;amp;list=PLu00CB7MWA3MXvFOkUNdzQ7kXBFrAUDAC&amp;amp;index=4&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1vwtb7zh6yx02xg5dw4.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ৩। বেশি বেশি অনুবাদ করে প্রজেক্ট ট্রান্সলেশন এডিটর (PTE) হওয়া:
&lt;/h2&gt;

&lt;p&gt;লিংক: ❌&lt;br&gt;&lt;br&gt;
রিসোর্স:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=Xrilg8_3QpU&amp;amp;list=PLu00CB7MWA3MXvFOkUNdzQ7kXBFrAUDAC&amp;amp;index=5&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyhw2tqmrvxr9mpup7flf.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ৪। প্যাটার্ন ডিজাইন করা
&lt;/h2&gt;

&lt;p&gt;লিংক: &lt;a href="https://wordpress.org/patterns/new-pattern/" rel="noopener noreferrer"&gt;Create New Pattern&lt;/a&gt;&lt;br&gt;&lt;br&gt;
রিসোর্স: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=7ccBdstfb3U&amp;amp;list=PLu00CB7MWA3MXvFOkUNdzQ7kXBFrAUDAC&amp;amp;index=7&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33evhe45iit8w4ii1m3o.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ৫। ফোরামে সাপোর্ট দেওয়া
&lt;/h2&gt;

&lt;p&gt;লিংক: &lt;a href="https://wordpress.org/support/forums/" rel="noopener noreferrer"&gt;WordPress Support Forums&lt;/a&gt;&lt;br&gt;&lt;br&gt;
রিসোর্স:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=yUtcmgOAbCY&amp;amp;list=PLu00CB7MWA3MXvFOkUNdzQ7kXBFrAUDAC&amp;amp;index=8&amp;amp;pp=gAQBiAQB" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F805m2y0nbcbh9y2pfuxb.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ৬। ওয়ার্ডপ্রেস কোরে কন্ট্রিবিউট করা
&lt;/h2&gt;

&lt;p&gt;লিংক: ❌&lt;br&gt;&lt;br&gt;
রিসোর্স:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/ubBnTek2jII?si=HyXkIUgBGhGDdu0n" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn42d7ynccstneobct7tr.jpg" alt="YouTube Video" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;কোন কিছু জানার থাকলে নিচে কমেন্ট করবেন। আপনার কোন পেন্ডিং ট্রান্সলেশন থাকলেও জানাতে পারেন। আমি শনি - রবিবার ফ্রি থাকি। তখন সব অ্যাপ্রুভ করে দেওয়ার চেষ্ঠা করব, ইনশাআল্লাহ।&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How and where to start learning free WordPress theme and plugin development?</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Tue, 08 Oct 2024 08:38:09 +0000</pubDate>
      <link>https://dev.to/faisalahammad/how-and-where-to-start-learning-free-wordpress-theme-and-plugin-development-5c1j</link>
      <guid>https://dev.to/faisalahammad/how-and-where-to-start-learning-free-wordpress-theme-and-plugin-development-5c1j</guid>
      <description>&lt;h2&gt;
  
  
  Resource Sharing - Sharing is Caring
&lt;/h2&gt;

&lt;p&gt;I have been involved with WordPress plugin and theme development for a long time. Currently, I'm working full-time as a plugin developer for one of the most renowned companies in the WordPress world, based in Florida, USA, for almost 2 years now. There's hardly anyone who uses WordPress but hasn't used our plugins or resource site! Before this, I worked for 2 years at another popular Australian-based WordPress company.&lt;/p&gt;

&lt;p&gt;Today, I'll share some resources for getting involved in WordPress development.&lt;/p&gt;

&lt;p&gt;WordPress development now uses many advanced and cutting-edge technologies. For example, object-oriented PHP, serverless development, React and Vue.js for plugin dashboard UIs, and much more.&lt;/p&gt;

&lt;p&gt;To get into WordPress development, you first need to have basic programming knowledge and know basic web design. You'll find these resources at the end of the post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theme Development:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Absolute Basics: Advanced WordPress Theme Development Course by Imran Sayed:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLD8nQCAhR3tT3ehpyOpoYeUj3KHDEVK9h" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLD8nQCAhR3tT3ehpyOpoYeUj3KHDEVK9h&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(This shows the very fundamentals of WordPress development)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Headless WordPress Theme Development: Advanced React WordPress Theme Development by Imran Sayed:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLD8nQCAhR3tQSv-U_LNdiHEViB1kj6LrM" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLD8nQCAhR3tQSv-U_LNdiHEViB1kj6LrM&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(This tutorial shows how to create a headless site using React on the frontend and WordPress theme on the backend. Headless sites are in high demand)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Headless WooCommerce: React WooCommerce Theme With Nextjs and REST API by Imran Sayed:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLD8nQCAhR3tSRwsvzRtogv9MFkEWo5d9c" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLD8nQCAhR3tSRwsvzRtogv9MFkEWo5d9c&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Same thing, but shows in detail about WooCommerce REST endpoints on the backend)&lt;/p&gt;

&lt;h2&gt;
  
  
  Plugin Development:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Basic WordPress Plugin Development Bangla by Robiz Show:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=HxoVIpBfufQ&amp;amp;list=PLFsAA7EWSBTIkLxZDhumQMlfQqNrDyLhP&amp;amp;pp=iAQB" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=HxoVIpBfufQ&amp;amp;list=PLFsAA7EWSBTIkLxZDhumQMlfQqNrDyLhP&amp;amp;pp=iAQB&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Absolute Basics: WordPress Plugins Development Tutorials by Alessandro Castellani:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLriKzYyLb28kR_CPMz8uierDWC2y3znI2" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLriKzYyLb28kR_CPMz8uierDWC2y3znI2&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  GitHub Source code:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Alecaddd/WordPressPlugin101" rel="noopener noreferrer"&gt;https://github.com/Alecaddd/WordPressPlugin101&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Advanced: Advanced WordPress Plugin Development by Imran Sayed:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLD8nQCAhR3tTjCulq0Fw3wZxIoN1wVOaV" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLD8nQCAhR3tTjCulq0Fw3wZxIoN1wVOaV&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;WordPress Plugin UI Development with React:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=XMJrdhvW4vs" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=XMJrdhvW4vs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=k2W5W_I4_H4" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=k2W5W_I4_H4&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Gutenberg Block Development:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Gutenberg Block Development by Robiz Show:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLFsAA7EWSBTLd7OREET_-O72lPkxz1GJV" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLFsAA7EWSBTLd7OREET_-O72lPkxz1GJV&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Custom Gutenberg Blocks by Alessandro Castellani:&lt;/strong&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLriKzYyLb28lHhftzU7Z_DJ32mvLy4KKH" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLriKzYyLb28lHhftzU7Z_DJ32mvLy4KKH&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  For Learning React JS:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3" rel="noopener noreferrer"&gt;https://www.youtube.com/playlist?list=PLC3y8-rFHvwgg3vaYJgHGnModB54rxOk3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(I personally learned React from Viswas of Codevalution)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(Let me share a secret, the React beginner tutorial by Sumit Bhai on YouTube - all the examples he gives are taken from Codevalution's tutorial. This suggests that his Bangla playlist is kind of a copy of Codevalution)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Thank you everyone. If you need any more resources, let me know in the comments.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This resource is collected from &lt;a href="https://www.facebook.com/Ohid.jsr" rel="noopener noreferrer"&gt;Ohidul Islam&lt;/a&gt;'s Facebook post. Full credit goes to him.&lt;/p&gt;

&lt;p&gt;Main Post: &lt;a href="https://www.faisalahammad.com/learn-wordpress-theme-plugin-development/" rel="noopener noreferrer"&gt;Learn Wordpress Theme Plugin Development&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>wordpressplugin</category>
      <category>wordpressthemedevelopment</category>
      <category>wordpressplugindevelopment</category>
    </item>
    <item>
      <title>Let’s find out the best FREE WordPress Form plugin</title>
      <dc:creator>Faisal Ahammad</dc:creator>
      <pubDate>Mon, 30 Sep 2024 05:03:50 +0000</pubDate>
      <link>https://dev.to/faisalahammad/lets-find-out-the-best-free-wordpress-form-plugin-1ade</link>
      <guid>https://dev.to/faisalahammad/lets-find-out-the-best-free-wordpress-form-plugin-1ade</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc24hpt7ftvpsz63its5r.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc24hpt7ftvpsz63its5r.jpg" alt="WordPress Form Plugins" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;WordPress form plugins are no longer limited to just contact forms. Currently, you can use form plugins for booking, subscriptions, CRM integration, product sales, and more! If you want, you can even use the form plugin's API to create your own integrations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free or Lite?
&lt;/h2&gt;

&lt;p&gt;There are many free form plugins for WordPress. But most are not free, rather lite versions. To be direct, the plugin available on WordPress.org is usually a limited feature lite version, where you won't get many things. You have to purchase the paid version to unlock all features.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limited Fields
&lt;/h2&gt;

&lt;p&gt;Even if the plugin name doesn't include "Lite", the following plugins don't allow all fields, settings or options such as form submission, reCaptcha, pre-made form templates, form submission export. Many basic fields are also locked. Only installing the pro version allows using all fields.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/bit-form/" rel="noopener noreferrer"&gt;Bit Form&lt;/a&gt; (43 total fields, 7 locked fields)

&lt;ul&gt;
&lt;li&gt;Mollie, Advanced, Singature, PayPal, RazorPay, Stripe, Draft Button&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/fluentform/" rel="noopener noreferrer"&gt;Fluent Forms&lt;/a&gt; (48 total fields, 27 locked fields)

&lt;ul&gt;
&lt;li&gt;Image Upload, File Upload, Phone, reCaptcha, hCaptcha, Turnstile, Shortcode, Action Hook, Form Step, Ratings, Checkable Grid, Range Slider, Net Promoter Score, Chained Select, Color Picker, Repeat Field, Post/CPT Selection, Quiz Score, Rich Text Input, Save &amp;amp; Resume, Payment Item, Subscription, Custom Payment Amount, Item Quantity, Payment Method, Payment Summary, Coupon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/formidable/" rel="noopener noreferrer"&gt;Formidable Forms&lt;/a&gt; (42 total fields, 27 locked fields)

&lt;ul&gt;
&lt;li&gt;File Upload, Rich Text, Time, Star Rating, Toggle, Lookup, Section, Embed Form, NPS, Tags, Summary, AI, Ranking, Date, Scale, Slider, Dynamic, Repeater, Page Break, Likert Scale, Password, Address, Signature, Appointment, Product, Quantity, Total&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/forminator/" rel="noopener noreferrer"&gt;Forminator Forms&lt;/a&gt; (29 total fields, 1 locked field)

&lt;ul&gt;
&lt;li&gt;eSignature&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/ninja-forms/" rel="noopener noreferrer"&gt;Ninja Forms&lt;/a&gt; (30 total fields, 2 locked fields)

&lt;ul&gt;
&lt;li&gt;File Upload, Save&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/weforms/" rel="noopener noreferrer"&gt;weForms&lt;/a&gt; (31 total fields, 16 locked fields)

&lt;ul&gt;
&lt;li&gt;Repeat Field, Numeric Field, File Upload, Address Field, Country List, Google Map, Step Start, reCaptcha, Shortcode, HP Anti-Spam, Action Hooks, Terms and Conditions, Ratings, Linear Scale, Checkbox Grid, Multiple Choice Grid&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/wpforms-lite/" rel="noopener noreferrer"&gt;WPForms Lite&lt;/a&gt; (40 total fields, 24 locked fields)

&lt;ul&gt;
&lt;li&gt;Phone, Date / Time, File Upload, Layout, Page Break, Rich Text, HTML, Rating, Custom Captcha, Likert Scale, Address, Website / URL, Password, Repeater, Section Divider, Content, Entry Preview, Hidden Field, Signature, Net Promoter Score, PayPal Commerce, Square, Authorize.net, Coupon&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://wordpress.org/plugins/ws-form/" rel="noopener noreferrer"&gt;WS Form Lite&lt;/a&gt; (55 total fields, 35 unavailable field)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2bpoi7n6hv1a1rbkrsc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk2bpoi7n6hv1a1rbkrsc.jpg" alt="Formidable Forms|690x406" width="800" height="472"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Formidable Forms Date field locked&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuww3l9ji59ch0vyczxj0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuww3l9ji59ch0vyczxj0.jpg" alt="WPForms|690x478" width="799" height="555"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;WPForms Entries locked&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfl3zwagn5hbbdr6vuqu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfl3zwagn5hbbdr6vuqu.jpg" alt="weForms|690x347" width="800" height="403"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;weForms locked some essential fields&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Free Add-ons
&lt;/h2&gt;

&lt;p&gt;How developer-friendly a form plugin is can be somewhat gauged by looking at community add-ons. Many form plugins have very rich documentation, but they don't provide developer licenses or any support for add-on development for third-party developers. On WordPress.org, you can find quite a few third-party plugins or add-ons for Fluent Forms, Formidable, Forminator, Ninja Forms, and WPForms plugins, which help extend the default features of the plugin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Customer Support
&lt;/h2&gt;

&lt;p&gt;Another important issue is plugin support. It turns out I got into trouble, but there's no chance of getting help. Free form plugins will only support you in the WordPress.org support forum, and that's always low priority. As a result, you often have to sit with an open ticket for a long time on urgent issues. Also, since WordPress forums have some specific rules, outside of which plugin companies can't offer support, you have many limitations in terms of getting support.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison of Free Features
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Plugin Name&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Math Calculation&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Manage Entries&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Embed Entries&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Free Templates&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Input Mask&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Support Channel&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;WPML Support&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bit Form&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fluent Forms&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Formidable Forms&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forminator Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ninja Forms&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Forum &amp;amp; Ticket&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;weForms&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WPForms Lite&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WS Form Lite&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;All&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;Forum&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Form Selection
&lt;/h2&gt;

&lt;p&gt;Considering all the above issues, the Ninja Forms plugin allows us to use all fields for free. You don't need a pro version to access any features, and they don't sell a pro version either. You'll get everything from reCaptcha, form submission, submission export to pre-made templates for free. &lt;em&gt;You won't see any notice to upgrade to the pro version anywhere.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And even if you're a free user, you'll get &lt;a href="https://ninjaforms.com/account/support/" rel="noopener noreferrer"&gt;free support&lt;/a&gt; from their website along with the WordPress.org support forum. This means you won't have to sit with an open ticket for &lt;em&gt;limited&lt;/em&gt; support on any urgent issue.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If any information above is incorrect, please let me know in the comments, I'll edit it. You can also inform me if any new features have been added to any form after I wrote my post. Thank you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Main Post: &lt;a href="https://www.faisalahammad.com/the-best-free-wordpress-form-plugin/" rel="noopener noreferrer"&gt;Let's find out the best FREE WordPress Form plugin&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>wordpressplugin</category>
      <category>formplugin</category>
      <category>contactform</category>
    </item>
  </channel>
</rss>
