MediaWiki master
SeenCondition.php
Go to the documentation of this file.
1<?php
2
4
8use stdClass;
11use Wikimedia\Timestamp\ConvertibleTimestamp;
12use Wikimedia\Timestamp\TimestampFormat as TS;
13
22 private ?UserIdentity $user = null;
23
24 public function __construct(
25 private WatchedItemStoreInterface $watchedItemStore
26 ) {
27 }
28
29 public function setUser( UserIdentity $user ) {
30 if ( $user->getId() ) {
31 $this->user = $user;
32 } else {
33 $this->user = null;
34 }
35 }
36
38 public function evaluate( stdClass $row, $value ): bool {
39 if ( !$this->user ) {
40 $seen = false;
41 } else {
42 $firstUnseen = $this->getLatestNotificationTimestamp( $row, $this->user );
43 $seen = $firstUnseen === null
44 || $firstUnseen > ConvertibleTimestamp::convert( TS::MW, $row->rc_timestamp );
45 }
46 return $seen === $value;
47 }
48
52 private function getLatestNotificationTimestamp( stdClass $row, UserIdentity $user ) {
53 if ( $row->rc_title === '' ) {
54 return null;
55 }
56 return $this->watchedItemStore->getLatestNotificationTimestamp(
57 $row->wl_notificationtimestamp,
58 $user,
59 new PageReferenceValue( (int)$row->rc_namespace, $row->rc_title, PageReferenceValue::LOCAL )
60 );
61 }
62
67 public function validateValue( $value ) {
68 if ( !is_bool( $value ) ) {
69 throw new \InvalidArgumentException(
70 'filter "seen" requires a boolean value' );
71 }
72 return $value;
73 }
74
76 protected function prepareCapture( IReadableDatabase $dbr, QueryBackend $query ) {
77 if ( $this->user ) {
78 $query->joinForFields( 'watchlist' )->weakLeft();
79 $query->fields( [ 'rc_timestamp', 'rc_namespace', 'rc_title', 'wl_notificationtimestamp' ] );
80 }
81 }
82
84 protected function prepareConds( IReadableDatabase $dbr, QueryBackend $query ) {
85 $values = $this->getEnumValues( [ true, false ] );
86 if ( $values === [] ) {
87 $query->forceEmptySet();
88 } elseif ( $values === [ true ] ) {
89 // Require seen
90 if ( $this->user ) {
91 $query->joinForConds( 'watchlist' )->weakLeft();
92 $query->where( $dbr->expr( 'wl_notificationtimestamp', '=', null )
93 ->orExpr( new RawSQLExpression( 'rc_timestamp < wl_notificationtimestamp' ) ) );
94 } else {
95 $query->forceEmptySet();
96 }
97 } elseif ( $values === [ false ] ) {
98 // Require unseen
99 if ( $this->user ) {
100 $query->joinForConds( 'watchlist' )->weakLeft();
101 $query->where( $dbr->expr( 'wl_notificationtimestamp', '!=', null )
102 ->andExpr( new RawSQLExpression( 'rc_timestamp >= wl_notificationtimestamp' ) ) );
103 }
104 }
105 }
106}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:71
Immutable value object representing a page reference.
Check if the recentchange row has been seen by the current watchlist user.
prepareConds(IReadableDatabase $dbr, QueryBackend $query)
Add conditions to the query according to the values passed to require() and exclude()....
__construct(private WatchedItemStoreInterface $watchedItemStore)
prepareCapture(IReadableDatabase $dbr, QueryBackend $query)
evaluate(stdClass $row, $value)
Evaluate the filter condition against a row, determining whether it is true or false....
Raw SQL expression to be used in query builders.
The narrow interface passed to filter modules.
forceEmptySet()
Set a flag forcing the query to return no rows when it is executed.
fields( $fields)
Add fields to the query.
where(IExpression $expr)
Add a condition to the query.
joinForFields(string $table)
Join on the specified table and declare that it will be used to provide fields for the SELECT clause.
joinForConds(string $table)
Join on the specified table and declare that it will be used to provide fields for the WHERE clause.
Interface for objects representing user identity.
getId( $wikiId=self::LOCAL)
A database connection without write operations.
expr(string $field, string $op, $value)
See Expression::__construct()