Drop PHP 7.4/8.0 support from master (forward-port from MW 1.42)

This patch was applied to release branches for MW 1.42 in April 2024, and
since ported to MW 1.43 and then MW 1.44 as well. This one-of-a-kind hot
patch will finally discontinue once this lands in the master branch as
part of MW 1.45+ releases.

A small handful of phan fixes make this pass so it can land; the rest
(including fixes rather than suppressions of events here) will happen in
later patches.

Bug: T328921
Bug: T359868
Change-Id: Ica2c11a6243795437ec652923e42ef3bd74a5fd8
This commit is contained in:
James D. Forrester 2025-03-15 16:39:09 -04:00 committed by Reedy
parent bce2f8850d
commit ac8a5b0b59
10 changed files with 30 additions and 12 deletions

View file

@ -20,10 +20,8 @@
$cfg = require __DIR__ . '/../vendor/mediawiki/mediawiki-phan-config/src/config.php';
// Whilst MediaWiki is still supporting PHP 7.4+, this lets us run phan on higher versions of PHP
// like 8.0 without phan trying to get us to make PHP 7.4-incompatible changes. This value should
// match the PHP version specified in composer.json and PHPVersionCheck.php.
$cfg['minimum_target_php_version'] = '7.4.3';
// This value should match the PHP version specified in composer.json and PHPVersionCheck.php.
$cfg['minimum_target_php_version'] = '8.1.0';
$cfg['file_list'] = array_merge(
$cfg['file_list'],

View file

@ -1344,6 +1344,7 @@ MESSAGE;
*/
public static function ensureNewline( $str ) {
$end = substr( $str, -1 );
// @phan-suppress-next-line PhanImpossibleTypeComparison
if ( $end === false || $end === '' || $end === "\n" ) {
return $str;
}

View file

@ -1293,7 +1293,6 @@ class WikiImporter {
/**
* Open the XMLReader connected to the source adapter id
* @suppress PhanStaticCallToNonStatic, UnusedSuppression -- for PHP 7.4 support
*/
private function openReader() {
// Enable the entity loader, as it is needed for loading external URLs via

View file

@ -110,6 +110,7 @@ class ConverterRule {
$flags[$validFlags[$ff]] = true;
}
}
// @phan-suppress-next-line PhanRedundantCondition
$text = strval( substr( $text, $sepPos + 1 ) );
}

View file

@ -1338,6 +1338,7 @@ class MessageCache implements LoggerAwareInterface {
// Message page exists as an override of a software messages
if ( substr( $entry, 0, 1 ) === ' ' ) {
// The message exists and is not '!TOO BIG' or '!ERROR'
// @phan-suppress-next-line PhanRedundantCondition
return (string)substr( $entry, 1 );
} elseif ( $entry === '!NONEXISTENT' ) {
// The text might be '-' or missing due to some data loss
@ -1387,6 +1388,7 @@ class MessageCache implements LoggerAwareInterface {
$this->cache->setField( $code, $title, $entry );
}
// The message exists, so make sure a string is returned
// @phan-suppress-next-line PhanRedundantCondition
return (string)substr( $entry, 1 );
}

View file

@ -239,6 +239,7 @@ class MemoryFileBackend extends FileBackendStore {
foreach ( $this->files as $path => $data ) {
if ( strpos( $path, $prefix ) === 0 ) {
$relPath = substr( $path, $prefixLen );
// @phan-suppress-next-line PhanImpossibleTypeComparisonInLoop
if ( $relPath === false ) {
continue;
} elseif ( strpos( $relPath, '/' ) === false ) {
@ -268,6 +269,7 @@ class MemoryFileBackend extends FileBackendStore {
foreach ( $this->files as $path => $data ) {
if ( strpos( $path, $prefix ) === 0 ) {
$relPath = substr( $path, $prefixLen );
// @phan-suppress-next-line PhanImpossibleTypeComparisonInLoop
if ( $relPath === false ) {
continue;
} elseif ( !empty( $params['topOnly'] ) && strpos( $relPath, '/' ) !== false ) {

View file

@ -2,9 +2,11 @@
namespace Wikimedia\Rdbms;
// Phan insists these are resources until we drop PHP 7.4
/* @phan-file-suppress PhanTypeMismatchArgumentInternal */
/**
* Result wrapper for PostgreSQL database results.
*
* @since 1.37
*/
class PostgresResultWrapper extends ResultWrapper {
/** @var DatabasePostgres */
private $db;
@ -26,18 +28,23 @@ class PostgresResultWrapper extends ResultWrapper {
}
protected function doNumRows() {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
return pg_num_rows( $this->result );
}
protected function doFetchObject() {
// pg_fetch_object may raise a warning after a seek to an invalid offset
// @phan-suppress-next-next-line PhanTypeMismatchArgumentInternal
// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
$row = @pg_fetch_object( $this->result );
// Map boolean values (T352229)
if ( is_object( $row ) ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$numFields = pg_num_fields( $this->result );
for ( $i = 0; $i < $numFields; $i++ ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
if ( pg_field_type( $this->result, $i ) === 'bool' ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$name = pg_field_name( $this->result, $i );
$row->$name = $this->convertBoolean( $row->$name );
}
@ -47,13 +54,17 @@ class PostgresResultWrapper extends ResultWrapper {
}
protected function doFetchRow() {
// @phan-suppress-next-next-line PhanTypeMismatchArgumentInternal
// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged
$row = @pg_fetch_array( $this->result );
// Map boolean values (T352229)
if ( is_array( $row ) ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$numFields = pg_num_fields( $this->result );
for ( $i = 0; $i < $numFields; $i++ ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
if ( pg_field_type( $this->result, $i ) === 'bool' ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$name = pg_field_name( $this->result, $i );
$row[$i] = $this->convertBoolean( $row[$i] );
$row[$name] = $this->convertBoolean( $row[$name] );
@ -82,17 +93,21 @@ class PostgresResultWrapper extends ResultWrapper {
}
protected function doSeek( $pos ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
pg_result_seek( $this->result, $pos );
}
protected function doFree() {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
return pg_free_result( $this->result );
}
protected function doGetFieldNames() {
$names = [];
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$n = pg_num_fields( $this->result );
for ( $i = 0; $i < $n; $i++ ) {
// @phan-suppress-next-line PhanTypeMismatchArgumentInternal
$names[] = pg_field_name( $this->result, $i );
}
return $names;

View file

@ -1129,7 +1129,7 @@ class CoreParserFunctions {
*/
public static function anchorencode( $parser, $text ) {
$text = $parser->killMarkers( $text );
$section = (string)substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
$section = substr( $parser->guessSectionNameFromWikiText( $text ), 1 );
return Sanitizer::safeEncodeAttribute( $section );
}

View file

@ -103,7 +103,7 @@ class ConvertExtensionToRegistration extends Maintenance {
foreach ( $vars as $name => $value ) {
$realName = substr( $name, 2 ); // Strip 'wg'
if ( $realName === false ) {
if ( $realName === '' ) {
continue;
}

View file

@ -11,11 +11,11 @@ use Wikimedia\Assert\Assert;
*
* PHP 8.2 has deprecated dynamic property creation for objects not explicitly annotated with #[AllowDynamicProperties].
* The recommended migration path for associating arbitrary data with objects is WeakMap, which is only available starting from PHP 8.0.
* As long as MediaWiki still supports PHP 7.4, this requires a compatibility layer for dynamic property creation on classes
* Whilst MediaWiki still supported PHP 7.4, this required a compatibility layer for dynamic property creation on classes
* that do not support it, by utilizing WeakMap when available and falling back to regular dynamic property creation
* on PHP 7.4.
*
* This class can be removed and its usages converted into direct WeakMap usage once MediaWiki only supports PHP 8.0 and above.
* This class can be removed and its usages converted into direct WeakMap usage now that MediaWiki only supports PHP 8.0 and above.
*
* @since 1.42 (also backported to 1.39.8, 1.40.4 and 1.41.2)
* @internal Only for use by core PHPUnit setup functionality.