diff --git a/packages/env/lib/wordpress.js b/packages/env/lib/wordpress.js index 423547fad688b..bd3c4a23f8ff5 100644 --- a/packages/env/lib/wordpress.js +++ b/packages/env/lib/wordpress.js @@ -27,6 +27,30 @@ const { getCache, setCache } = require( './cache' ); * @typedef {'development'|'tests'|'all'} WPEnvironmentSelection */ +/** + * Utility function to check if a WordPress version is lower than another version. + * + * This is a non-comprehensive check only intended for this usage, to avoid pulling in a full semver library. + * It only considers the major and minor portions of the version and ignores the rest. Additionally, it assumes that + * the minor version is always a single digit (i.e. 0-9). + * + * Do not use this function for general version comparison, as it will not work for all cases. + * + * @param {string} version The version to check. + * @param {string} compareVersion The compare version to check whether the version is lower than. + * @return {boolean} True if the version is lower than the compare version, false otherwise. + */ +function isWPMajorMinorVersionLower( version, compareVersion ) { + const versionNumber = Number.parseFloat( + version.match( /^[0-9]+(\.[0-9]+)?/ )[ 0 ] + ); + const compareVersionNumber = Number.parseFloat( + compareVersion.match( /^[0-9]+(\.[0-9]+)?/ )[ 0 ] + ); + + return versionNumber < compareVersionNumber; +} + /** * Checks a WordPress database connection. An error is thrown if the test is * unsuccessful. @@ -51,11 +75,28 @@ async function checkDatabaseConnection( { dockerComposeConfigPath, debug } ) { * @param {Object} spinner A CLI spinner which indicates progress. */ async function configureWordPress( environment, config, spinner ) { + let wpVersion = ''; + try { + wpVersion = await readWordPressVersion( + config.env[ environment ].coreSource, + spinner, + config.debug + ); + } catch ( err ) { + // Ignore error. + } + const installCommand = `wp core install --url="${ config.env[ environment ].config.WP_SITEURL }" --title="${ config.name }" --admin_user=admin --admin_password=password --admin_email=wordpress@example.com --skip-email`; // -eo pipefail exits the command as soon as anything fails in bash. const setupCommands = [ 'set -eo pipefail', installCommand ]; + // WordPress versions below 5.1 didn't use proper spacing in wp-config. + const configAnchor = + wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.1' ) + ? `"define('WP_DEBUG',"` + : `"define( 'WP_DEBUG',"`; + // Set wp-config.php values. for ( let [ key, value ] of Object.entries( config.env[ environment ].config @@ -68,7 +109,7 @@ async function configureWordPress( environment, config, spinner ) { // Add quotes around string values to work with multi-word strings better. value = typeof value === 'string' ? `"${ value }"` : value; setupCommands.push( - `wp config set ${ key } ${ value } --anchor="define( 'WP_DEBUG',"${ + `wp config set ${ key } ${ value } --anchor=${ configAnchor }${ typeof value !== 'string' ? ' --raw' : '' }` ); @@ -98,6 +139,15 @@ async function configureWordPress( environment, config, spinner ) { } ); + // WordPress versions below 5.1 didn't use proper spacing in wp-config. + // Additionally, WordPress versions below 5.4 used `dirname( __FILE__ )` instead of `__DIR__`. + let abspathDef = `define( 'ABSPATH', __DIR__ . '\\/' );`; + if ( wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.1' ) ) { + abspathDef = `define('ABSPATH', dirname(__FILE__) . '\\/');`; + } else if ( wpVersion && isWPMajorMinorVersionLower( wpVersion, '5.4' ) ) { + abspathDef = `define( 'ABSPATH', dirname( __FILE__ ) . '\\/' );`; + } + // WordPress' PHPUnit suite expects a `wp-tests-config.php` in // the directory that the test suite is contained within. // Make sure ABSPATH points to the WordPress install. @@ -106,7 +156,7 @@ async function configureWordPress( environment, config, spinner ) { [ 'sh', '-c', - `sed -e "/^require.*wp-settings.php/d" -e "s/define( 'ABSPATH', __DIR__ . '\\/' );/define( 'ABSPATH', '\\/var\\/www\\/html\\/' );\\n\\tdefine( 'WP_DEFAULT_THEME', 'default' );/" /var/www/html/wp-config.php > /wordpress-phpunit/wp-tests-config.php`, + `sed -e "/^require.*wp-settings.php/d" -e "s/${ abspathDef }/define( 'ABSPATH', '\\/var\\/www\\/html\\/' );\\n\\tdefine( 'WP_DEFAULT_THEME', 'default' );/" /var/www/html/wp-config.php > /wordpress-phpunit/wp-tests-config.php`, ], { config: config.dockerComposeConfigPath,