[wp-trac] [WordPress Trac] #64830: Introduce a helper function to extract the major.minor "branch" version

WordPress Trac noreply at wordpress.org
Mon Mar 9 07:19:41 UTC 2026


#64830: Introduce a helper function to extract the major.minor "branch" version
-------------------------+-----------------------------
 Reporter:  apermo       |      Owner:  (none)
     Type:  enhancement  |     Status:  new
 Priority:  normal       |  Milestone:  Awaiting Review
Component:  General      |    Version:  3.2
 Severity:  normal       |   Keywords:
  Focuses:               |
-------------------------+-----------------------------
 In PR https://github.com/WordPress/wordpress-develop/pull/11206 we ran
 into the issue that getting a patchless WP version is cluttered throughout
 core and sparked a discussion about introducing a proper helper function
 for extracting the major.minor (x.y) "branch" version.


 == The original problem

 PHPStan flags `(float) get_bloginfo('version')` in `admin-header.php:194`
 because `str_replace()` receives a float instead of a string. The PR
 author initially proposed changing the cast to `(string)`, but this broke
 the existing behavior (the branch- CSS class would include the full
 version instead of just major.minor).

 === Key feedback

 1. @apermo caught the behavior regression and pointed out that the
 `(float)` cast is intentional — it strips the patch version (e.g., 6.9.1 →
 6.9). He proposed get_bloginfo('branch_version') or a helper function.
 2. @siliconforks identified a genuine bug: the `(float)` cast is not
 reliably defined. If PHP's precision ini setting is non-default (e.g.,
 50), version 6.9.1 produces
 branch-6-9000000000000003552713678800500929355621337890625. This affects
 any version where the major.minor isn't exactly representable as a float
 (i.e., most versions except x.0).
 3. @westonruter noted the `(float)` approach is "abuse of a float" and
 proposed a string-based replacement using strtok/explode/array_slice. He
 also noted that for 7.0, the existing behavior produces branch-7 (not
 branch-7-0), and this should be preserved.
 4. @apermo cataloged 4 different approaches used across core to extract
 the `x.y` version, and proposed a single helper function using the robust
 implode/preg_split approach from class-core-upgrader.php that all
 locations could use.


 === Consensus direction

 - A helper function for extracting the branch version would benefit core,
 since at least 10 locations use varied (and sometimes fragile) approaches
 — some of which will break at version 10.0 (substr($ver, 0, 3))
 - The helper function should be a separate enhancement ticket from the
 immediate PHPStan fix


 ----


 == Affected locations

   - (float) cast: admin-header.php, class-wp-site-health-auto-updates.php,
 tests/basic.php
   - substr($ver, 0, 3): theme.php, plugin-install.php, block-template-
 utils.php, tests/basic.php
   - explode('.') with index: class-wp-site-health.php
   - implode/preg_split: class-core-upgrader.php (most robust)


 {{{#!php
 <?php
  /**
    * Returns the major.minor "branch" version for a given WordPress
 version string.
    *
    * Extracts the first two version components (major and minor) from a
 WordPress
    * version string, stripping any patch level and pre-release suffix.
    *
    * @since 7.1.0
    *
    * @param string $version Optional. A WordPress version string. Defaults
 to the
    *                        current WordPress version from
 wp_get_wp_version().
    * @return string The branch version string in "major.minor" format
 (e.g. "6.9").
    */
   function wp_get_branch_version( $version = '' ) {
         if ( '' === $version ) {
                 $version = wp_get_wp_version();
         }

         $parts = preg_split( '/[.-]/', $version, 3 );

         return $parts[0] . '.' . ( $parts[1] ?? '0' );
   }
 }}}


 === Decisions:

   - Reuses the `preg_split('/[.-]/')` approach from `class-core-
 upgrader.php:282` — already proven in core and handles both . and -
 separators in one pass.
   - Accepts an optional $version parameter so callers like class-core-
 upgrader.php (which compares two versions) and class-wp-site-health.php
 can use it too, not just the current WP version.
   - Limit of 3 on `preg_split()` avoids unnecessary splits.
   - Always returns "major.minor" — e.g. "7.0" for "7.0-beta3", "6.9" for
 "6.9.1", "10.1" for "10.1.2-RC1".

 Note: The existing `admin-header.php` behavior drops the .0 in the CSS
 class (producing branch-7 instead of branch-7-0). That's a quirk of the
 (float) cast. This is the main decision that needs to be taken which is
 the correct/expected behavior here.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/64830>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list