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
20 private ?UserIdentity $user = null;
21
22 public function __construct(
23 private WatchedItemStoreInterface $watchedItemStore
24 ) {
25 }
26
27 public function setUser( UserIdentity $user ) {
28 if ( $user->getId() ) {
29 $this->user = $user;
30 } else {
31 $this->user = null;
32 }
33 }
34
36 public function evaluate( stdClass $row, $value ): bool {
37 if ( !$this->user ) {
38 $seen = false;
39 } else {
40 $firstUnseen = $this->getLatestNotificationTimestamp( $row, $this->user );
41 $seen = $firstUnseen === null
42 || $firstUnseen > ConvertibleTimestamp::convert( TS::MW, $row->rc_timestamp );
43 }
44 return $seen === $value;
45 }
46
50 private function getLatestNotificationTimestamp( stdClass $row, UserIdentity $user ) {
51 if ( $row->rc_title === '' ) {
52 return null;
53 }
54 return $this->watchedItemStore->getLatestNotificationTimestamp(
55 $row->wl_notificationtimestamp,
56 $user,
57 new PageReferenceValue( (int)$row->rc_namespace, $row->rc_title, PageReferenceValue::LOCAL )
58 );
59 }
60
65 public function validateValue( $value ) {
66 if ( !is_bool( $value ) ) {
67 throw new \InvalidArgumentException(
68 'filter "seen" requires a boolean value' );
69 }
70 return $value;
71 }
72
74 protected function prepareCapture( IReadableDatabase $dbr, QueryBackend $query ) {
75 if ( $this->user ) {
76 $query->joinForFields( 'watchlist' )->weakLeft();
77 $query->fields( [ 'rc_timestamp', 'rc_namespace', 'rc_title', 'wl_notificationtimestamp' ] );
78 }
79 }
80
82 protected function prepareConds( IReadableDatabase $dbr, QueryBackend $query ) {
83 $values = $this->getEnumValues( [ true, false ] );
84 if ( $values === [] ) {
85 $query->forceEmptySet();
86 } elseif ( $values === [ true ] ) {
87 // Require seen
88 if ( $this->user ) {
89 $query->joinForConds( 'watchlist' )->weakLeft();
90 $query->where( $dbr->expr( 'wl_notificationtimestamp', '=', null )
91 ->orExpr( new RawSQLExpression( 'rc_timestamp < wl_notificationtimestamp' ) ) );
92 } else {
93 $query->forceEmptySet();
94 }
95 } elseif ( $values === [ false ] ) {
96 // Require unseen
97 if ( $this->user ) {
98 $query->joinForConds( 'watchlist' )->weakLeft();
99 $query->where( $dbr->expr( 'wl_notificationtimestamp', '!=', null )
100 ->andExpr( new RawSQLExpression( 'rc_timestamp >= wl_notificationtimestamp' ) ) );
101 }
102 }
103 }
104}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:69
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()