2022-02-28 03:05:58 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace MediaWiki\User\TempUser;
|
|
|
|
|
|
2024-06-13 11:58:53 +00:00
|
|
|
use Stringable;
|
2023-06-10 13:05:22 +00:00
|
|
|
use UnexpectedValueException;
|
2023-12-05 21:00:02 +00:00
|
|
|
use Wikimedia\Rdbms\LikeValue;
|
2023-03-06 01:16:39 +00:00
|
|
|
use Wikimedia\Rdbms\Platform\ISQLPlatform;
|
|
|
|
|
|
2022-02-28 03:05:58 +00:00
|
|
|
/**
|
|
|
|
|
* Helper for TempUserConfig representing string patterns with "$1" indicating
|
|
|
|
|
* variable substitution.
|
|
|
|
|
*
|
|
|
|
|
* @internal
|
|
|
|
|
*/
|
2024-06-13 11:58:53 +00:00
|
|
|
class Pattern implements Stringable {
|
2022-02-28 03:05:58 +00:00
|
|
|
/** @var string */
|
|
|
|
|
private $debugName;
|
|
|
|
|
/** @var string */
|
|
|
|
|
private $pattern;
|
|
|
|
|
/** @var string */
|
|
|
|
|
private $prefix;
|
|
|
|
|
/** @var string */
|
|
|
|
|
private $suffix;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $debugName The name of the pattern, for use in error messages
|
|
|
|
|
* @param string $pattern The pattern itself
|
|
|
|
|
*/
|
|
|
|
|
public function __construct( string $debugName, string $pattern ) {
|
|
|
|
|
$this->debugName = $debugName;
|
|
|
|
|
$this->pattern = $pattern;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Does the pattern match the given name?
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function isMatch( string $name ) {
|
|
|
|
|
$this->init();
|
|
|
|
|
$match = true;
|
|
|
|
|
if ( $this->prefix !== '' ) {
|
|
|
|
|
$match = str_starts_with( $name, $this->prefix );
|
|
|
|
|
}
|
|
|
|
|
if ( $match && $this->suffix !== '' ) {
|
|
|
|
|
$match = str_ends_with( $name, $this->suffix )
|
|
|
|
|
&& strlen( $name ) >= strlen( $this->prefix ) + strlen( $this->suffix );
|
|
|
|
|
}
|
|
|
|
|
return $match;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Substitute the serial number into the pattern.
|
|
|
|
|
*
|
|
|
|
|
* @param string $mappedSerial
|
2023-12-20 11:22:13 +00:00
|
|
|
* @param ?string $year
|
2022-02-28 03:05:58 +00:00
|
|
|
* @return string
|
|
|
|
|
*/
|
2023-12-20 11:22:13 +00:00
|
|
|
public function generate( $mappedSerial, ?string $year = null ) {
|
2022-02-28 03:05:58 +00:00
|
|
|
$this->init();
|
2023-12-20 11:22:13 +00:00
|
|
|
return $this->prefix .
|
|
|
|
|
( $year ? $year . '-' : '' ) .
|
|
|
|
|
$mappedSerial .
|
|
|
|
|
$this->suffix;
|
2022-02-28 03:05:58 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-06 01:16:39 +00:00
|
|
|
/**
|
|
|
|
|
* Convert the pattern to an SQL like clause
|
|
|
|
|
*
|
2023-12-05 21:00:02 +00:00
|
|
|
* @deprecated since 1.42. Use toLikeValue() instead
|
2023-03-06 01:16:39 +00:00
|
|
|
* @param ISQLPlatform $db
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function buildLike( ISQLPlatform $db ) {
|
2023-12-05 21:00:02 +00:00
|
|
|
wfDeprecated( __METHOD__, '1.42' );
|
2023-03-06 01:16:39 +00:00
|
|
|
$this->init();
|
|
|
|
|
return $db->buildLike(
|
|
|
|
|
$this->prefix,
|
|
|
|
|
$db->anyString(),
|
|
|
|
|
$this->suffix
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-05 21:00:02 +00:00
|
|
|
/**
|
|
|
|
|
* Convert the pattern to an SQL builder "LIKE" value that matches it
|
|
|
|
|
*
|
|
|
|
|
* @param ISQLPlatform $db
|
|
|
|
|
* @return LikeValue
|
|
|
|
|
*/
|
|
|
|
|
public function toLikeValue( ISQLPlatform $db ): LikeValue {
|
|
|
|
|
$this->init();
|
|
|
|
|
return new LikeValue(
|
|
|
|
|
$this->prefix,
|
|
|
|
|
$db->anyString(),
|
|
|
|
|
$this->suffix
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-06 01:16:39 +00:00
|
|
|
/**
|
2023-12-20 11:22:13 +00:00
|
|
|
* Extract the variable part of the string (matching $1 or YYYY-$1),
|
|
|
|
|
* or null if there is no match
|
2023-03-06 01:16:39 +00:00
|
|
|
*
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @return ?string
|
|
|
|
|
*/
|
|
|
|
|
public function extract( string $name ) {
|
|
|
|
|
if ( $this->isMatch( $name ) ) {
|
|
|
|
|
return substr( $name,
|
|
|
|
|
strlen( $this->prefix ),
|
|
|
|
|
strlen( $name ) - strlen( $this->prefix ) - strlen( $this->suffix ) );
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-28 03:05:58 +00:00
|
|
|
/**
|
|
|
|
|
* Initialise the prefix and suffix
|
|
|
|
|
*/
|
|
|
|
|
private function init() {
|
|
|
|
|
if ( $this->prefix === null ) {
|
|
|
|
|
$varPos = strpos( $this->pattern, '$1' );
|
|
|
|
|
if ( $varPos === false ) {
|
2023-06-10 13:05:22 +00:00
|
|
|
throw new UnexpectedValueException( __CLASS__ .
|
2022-02-28 03:05:58 +00:00
|
|
|
"pattern {$this->debugName} must be of the form \"prefix \$1 suffix\"" );
|
|
|
|
|
}
|
|
|
|
|
$this->prefix = substr( $this->pattern, 0, $varPos );
|
|
|
|
|
$this->suffix = substr( $this->pattern, $varPos + strlen( '$1' ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-06-13 11:58:53 +00:00
|
|
|
|
|
|
|
|
public function __toString() {
|
|
|
|
|
return $this->pattern;
|
|
|
|
|
}
|
2022-02-28 03:05:58 +00:00
|
|
|
}
|