2018-01-21 20:52:43 +00:00
|
|
|
<?php
|
|
|
|
|
2022-11-13 06:43:40 +00:00
|
|
|
namespace MediaWiki\Extension\Notifications;
|
|
|
|
|
|
|
|
use BadMethodCallException;
|
2021-06-24 19:21:49 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2018-07-09 22:45:54 +00:00
|
|
|
use MediaWiki\Preferences\MultiUsernameFilter;
|
2023-12-11 15:33:08 +00:00
|
|
|
use MediaWiki\User\User;
|
2022-11-13 06:43:40 +00:00
|
|
|
use WANObjectCache;
|
2018-07-09 22:45:54 +00:00
|
|
|
|
2018-01-21 20:52:43 +00:00
|
|
|
/**
|
2022-11-13 06:43:40 +00:00
|
|
|
* Utilizes ContainmentList interface to provide a fluent interface to whitelist/blacklist
|
2018-01-21 20:52:43 +00:00
|
|
|
* from multiple sources like global variables, wiki pages, etc.
|
|
|
|
*
|
|
|
|
* Initialize:
|
2024-06-26 09:17:13 +00:00
|
|
|
* $cache = ObjectCacheFactory::getLocalClusterInstance();
|
2022-11-13 06:43:40 +00:00
|
|
|
* $set = new ContainmentSet;
|
2018-01-21 20:52:43 +00:00
|
|
|
* $set->addArray( $wgSomeGlobalParameter );
|
|
|
|
* $set->addOnWiki( NS_USER, 'Foo/bar-baz', $cache, 'some_user_specific_cache_key' );
|
|
|
|
*
|
|
|
|
* Usage:
|
|
|
|
* if ( $set->contains( 'SomeUser' ) ) {
|
|
|
|
* ...
|
|
|
|
* }
|
|
|
|
*/
|
2022-11-13 06:43:40 +00:00
|
|
|
class ContainmentSet {
|
2018-01-21 20:52:43 +00:00
|
|
|
/**
|
2022-11-13 06:43:40 +00:00
|
|
|
* @var ContainmentList[]
|
2018-01-21 20:52:43 +00:00
|
|
|
*/
|
|
|
|
protected $lists = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var User
|
|
|
|
*/
|
|
|
|
protected $recipient;
|
|
|
|
|
2021-12-01 18:29:00 +00:00
|
|
|
/**
|
|
|
|
* @param User $recipient
|
|
|
|
*/
|
2018-01-21 20:52:43 +00:00
|
|
|
public function __construct( User $recipient ) {
|
|
|
|
$this->recipient = $recipient;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-11-13 06:43:40 +00:00
|
|
|
* Add an ContainmentList to the set of lists checked by self::contains()
|
2018-01-21 20:52:43 +00:00
|
|
|
*
|
2022-11-13 06:43:40 +00:00
|
|
|
* @param ContainmentList $list
|
2018-01-21 20:52:43 +00:00
|
|
|
*/
|
2022-11-13 06:43:40 +00:00
|
|
|
public function add( ContainmentList $list ) {
|
2018-01-21 20:52:43 +00:00
|
|
|
$this->lists[] = $list;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a php array to the set of lists checked by self::contains()
|
|
|
|
*
|
|
|
|
* @param array $list
|
|
|
|
*/
|
|
|
|
public function addArray( array $list ) {
|
2022-11-13 06:43:40 +00:00
|
|
|
$this->add( new ArrayList( $list ) );
|
2018-01-21 20:52:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a list from a user preference to the set of lists checked by self::contains().
|
|
|
|
*
|
|
|
|
* @param string $preferenceName
|
|
|
|
*/
|
2021-12-01 18:29:00 +00:00
|
|
|
public function addFromUserOption( string $preferenceName ) {
|
|
|
|
$userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
|
|
|
|
$preference = $userOptionsLookup->getOption( $this->recipient, $preferenceName, [] );
|
2018-01-21 20:52:43 +00:00
|
|
|
if ( $preference ) {
|
2018-07-09 22:45:54 +00:00
|
|
|
$ids = MultiUsernameFilter::splitIds( $preference );
|
2021-06-24 19:21:49 +00:00
|
|
|
$names = MediaWikiServices::getInstance()
|
|
|
|
->getCentralIdLookup()
|
|
|
|
->namesFromCentralIds( $ids, $this->recipient );
|
2018-01-21 20:52:43 +00:00
|
|
|
$this->addArray( $names );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-20 19:40:07 +00:00
|
|
|
/**
|
|
|
|
* Add a list of title IDs from a user preference to the set of lists
|
|
|
|
* checked by self::contains().
|
|
|
|
*
|
|
|
|
* @param string $preferenceName
|
|
|
|
*/
|
2021-07-23 21:23:16 +00:00
|
|
|
public function addTitleIDsFromUserOption( string $preferenceName ): void {
|
2021-12-01 18:29:00 +00:00
|
|
|
$userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
|
|
|
|
$preference = $userOptionsLookup->getOption( $this->recipient, $preferenceName, [] );
|
2020-04-20 19:40:07 +00:00
|
|
|
if ( !is_string( $preference ) ) {
|
|
|
|
// We expect the preference data to be saved as a string via the
|
|
|
|
// preferences form; if the user modified their data so it's no
|
|
|
|
// longer a string, ignore it.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
$titleIDs = preg_split( '/\n/', $preference, -1, PREG_SPLIT_NO_EMPTY );
|
|
|
|
$this->addArray( $titleIDs );
|
|
|
|
}
|
|
|
|
|
2018-01-21 20:52:43 +00:00
|
|
|
/**
|
|
|
|
* Add a list from a wiki page to the set of lists checked by self::contains(). Data
|
|
|
|
* from wiki pages is cached via the BagOStuff. Caching is disabled when passing a null
|
|
|
|
* $cache object.
|
|
|
|
*
|
|
|
|
* @param int $namespace An NS_* constant representing the mediawiki namespace of the page containing the list.
|
|
|
|
* @param string $title The title of the page containing the list.
|
2019-02-28 21:17:15 +00:00
|
|
|
* @param WANObjectCache|null $cache An object to cache the page with or null for no cache.
|
2018-01-21 20:52:43 +00:00
|
|
|
* @param string $cacheKeyPrefix A prefix to be combined with the pages latest revision id and used as a cache key.
|
|
|
|
*/
|
2019-02-28 21:17:15 +00:00
|
|
|
public function addOnWiki(
|
|
|
|
$namespace, $title, WANObjectCache $cache = null, $cacheKeyPrefix = ''
|
|
|
|
) {
|
2022-11-13 06:43:40 +00:00
|
|
|
$list = new OnWikiList( $namespace, $title );
|
2018-01-21 20:52:43 +00:00
|
|
|
if ( $cache ) {
|
|
|
|
if ( $cacheKeyPrefix === '' ) {
|
2023-06-07 17:46:16 +00:00
|
|
|
throw new BadMethodCallException( 'Cache requires providing a cache key prefix.' );
|
2018-01-21 20:52:43 +00:00
|
|
|
}
|
2022-11-13 06:43:40 +00:00
|
|
|
$list = new CachedList( $cache, $cacheKeyPrefix, $list );
|
2018-01-21 20:52:43 +00:00
|
|
|
}
|
|
|
|
$this->add( $list );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Test the wrapped lists for existence of $value
|
|
|
|
*
|
|
|
|
* @param mixed $value The value to look for
|
|
|
|
* @return bool True when the set contains the provided value
|
|
|
|
*/
|
|
|
|
public function contains( $value ) {
|
|
|
|
foreach ( $this->lists as $list ) {
|
|
|
|
// Use strict comparison to prevent the number 0 from matching all strings (T177825)
|
2022-06-23 09:17:10 +00:00
|
|
|
if ( in_array( $value, $list->getValues(), true ) ) {
|
2018-01-21 20:52:43 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|