summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CheckUser/src/ChangeService.php')
-rw-r--r--CheckUser/src/ChangeService.php142
1 files changed, 142 insertions, 0 deletions
diff --git a/CheckUser/src/ChangeService.php b/CheckUser/src/ChangeService.php
new file mode 100644
index 00000000..19b904e2
--- /dev/null
+++ b/CheckUser/src/ChangeService.php
@@ -0,0 +1,142 @@
+<?php
+
+namespace MediaWiki\CheckUser;
+
+use Wikimedia\IPUtils;
+use Wikimedia\Rdbms\IDatabase;
+use Wikimedia\Rdbms\ILoadBalancer;
+
+abstract class ChangeService {
+ /** @var ILoadBalancer */
+ protected $loadBalancer;
+
+ /** @var UserManager */
+ protected $userManager;
+
+ /**
+ * @param ILoadBalancer $loadBalancer
+ * @param UserManager $userManager
+ */
+ public function __construct(
+ ILoadBalancer $loadBalancer,
+ UserManager $userManager
+ ) {
+ $this->loadBalancer = $loadBalancer;
+ $this->userManager = $userManager;
+ }
+
+ /**
+ * Builds a query predicate depending on what type of
+ * target is passed in
+ *
+ * @param string[] $targets
+ * @return string[]
+ */
+ protected function buildTargetCondsMultiple( array $targets ) : array {
+ $db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
+
+ $condSet = array_map( function ( $target ) {
+ return $this->buildTargetConds( $target );
+ }, $targets );
+
+ if ( !$condSet ) {
+ return [
+ $db->addQuotes( false )
+ ];
+ }
+
+ $conds = array_merge_recursive( ...$condSet );
+
+ if ( !$conds ) {
+ return [
+ $db->addQuotes( false )
+ ];
+ }
+
+ return [
+ $db->makeList( $conds, IDatabase::LIST_OR ),
+ ];
+ }
+
+ /**
+ * Builds a query predicate depending on what type of
+ * target is passed in
+ *
+ * @param string $target
+ * @return string[]
+ */
+ protected function buildTargetConds( $target ) : array {
+ $db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
+ $conds = [];
+
+ if ( IPUtils::isIpAddress( $target ) ) {
+ if ( IPUtils::isValid( $target ) ) {
+ $conds['cuc_ip_hex'] = IPUtils::toHex( $target );
+ } elseif ( IPUtils::isValidRange( $target ) ) {
+ $range = IPUtils::parseRange( $target );
+ $conds[] = $db->makeList( [
+ 'cuc_ip_hex >= ' . $db->addQuotes( $range[0] ),
+ 'cuc_ip_hex <= ' . $db->addQuotes( $range[1] )
+ ], IDatabase::LIST_AND );
+ }
+ } else {
+ // TODO: This may filter out invalid values, changing the number of
+ // targets. The per-target limit should change too (T246393).
+ $userId = $this->userManager->idFromName( $target );
+ if ( $userId ) {
+ $conds['cuc_user'] = $userId;
+ }
+ }
+
+ return $conds;
+ }
+
+ /**
+ * @param string[] $targets
+ * @return array
+ */
+ protected function buildExcludeTargetsConds( array $targets ) : array {
+ $conds = [];
+ $db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
+
+ $ipTargets = [];
+ $userTargets = [];
+
+ foreach ( $targets as $target ) {
+ if ( IPUtils::isIpAddress( $target ) ) {
+ $ipTargets[] = IPUtils::toHex( $target );
+ } else {
+ $userId = $this->userManager->idFromName( $target );
+ if ( $userId ) {
+ $userTargets[] = $userId;
+ }
+ }
+ }
+
+ if ( count( $ipTargets ) > 0 ) {
+ $conds[] = 'cuc_ip_hex NOT IN (' . $db->makeList( $ipTargets ) . ')';
+ }
+ if ( count( $userTargets ) > 0 ) {
+ $conds[] = 'cuc_user NOT IN (' . $db->makeList( $userTargets ) . ')';
+ }
+
+ return $conds;
+ }
+
+ /**
+ * Build conditions for the start timeestamp.
+ *
+ * @param string $start timestamp
+ * @return array conditions
+ */
+ protected function buildStartConds( string $start ) : array {
+ if ( $start === '' ) {
+ return [];
+ }
+
+ $db = $this->loadBalancer->getConnectionRef( DB_REPLICA );
+ return [
+ 'cuc_timestamp >= ' . $db->addQuotes( $start ),
+ ];
+ }
+}