Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F6038448
WatchedCondition.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
WatchedCondition.php
View Options
<?php
namespace
MediaWiki\RecentChanges\ChangesListQuery
;
use
MediaWiki\User\UserIdentity
;
use
MediaWiki\Utils\MWTimestamp
;
use
stdClass
;
use
Wikimedia\Rdbms\IReadableDatabase
;
use
Wikimedia\Rdbms\RawSQLExpression
;
/**
* Check if a recentchange row is watched by the current watchlist user.
* Optionally check if the change is a "new" change.
*
* @since 1.45
*/
class
WatchedCondition
extends
ChangesListConditionBase
{
private
?
int
$userId
=
null
;
private
const
ALL_VALUES
=
[
'notwatched'
,
'watchedold'
,
'watchednew'
];
public
function
__construct
(
private
bool
$enableExpiry
)
{
}
public
function
setUser
(
UserIdentity
$user
)
{
$this
->
userId
=
$user
->
getId
();
}
/**
* @param string $value
* @return string
*/
public
function
validateValue
(
$value
)
{
if
(
!
in_array
(
$value
,
self
::
ALL_VALUES
,
true
)
)
{
throw
new
\InvalidArgumentException
(
'unknown value for watched filter'
);
}
return
$value
;
}
/** @inheritDoc */
public
function
evaluate
(
stdClass
$row
,
$value
):
bool
{
if
(
!
$this
->
userId
||
(
$this
->
enableExpiry
&&
$row
->
we_expiry
!==
null
&&
MWTimestamp
::
convert
(
TS_UNIX
,
$row
->
we_expiry
)
<=
wfTimestamp
()
)
||
$row
->
wl_user
===
null
)
{
return
$value
===
'notwatched'
;
}
elseif
(
$row
->
rc_timestamp
&&
$row
->
wl_notificationtimestamp
&&
$row
->
rc_timestamp
>=
$row
->
wl_notificationtimestamp
)
{
return
$value
===
'watchednew'
;
}
else
{
return
$value
===
'watchedold'
;
}
}
/** @inheritDoc */
protected
function
prepareCapture
(
IReadableDatabase
$dbr
,
QueryBackend
$query
)
{
if
(
!
$this
->
userId
)
{
return
;
}
$query
->
joinForFields
(
'watchlist'
)->
weakLeft
();
$query
->
fields
(
[
'wl_user'
,
'wl_notificationtimestamp'
,
'rc_timestamp'
]
);
if
(
$this
->
enableExpiry
)
{
$query
->
joinForFields
(
'watchlist_expiry'
)->
left
();
$query
->
fields
(
'we_expiry'
);
}
}
/** @inheritDoc */
protected
function
prepareConds
(
IReadableDatabase
$dbr
,
QueryBackend
$query
)
{
$set
=
$this
->
getEnumValues
(
self
::
ALL_VALUES
);
if
(
$set
===
null
)
{
return
;
}
elseif
(
$set
===
[]
)
{
$query
->
forceEmptySet
();
return
;
}
$notwatched
=
in_array
(
'notwatched'
,
$set
,
true
);
$watchedold
=
in_array
(
'watchedold'
,
$set
,
true
);
$watchednew
=
in_array
(
'watchednew'
,
$set
,
true
);
if
(
!
$this
->
userId
)
{
if
(
!
$notwatched
)
{
$query
->
forceEmptySet
();
}
return
;
}
$orConds
=
[];
if
(
$notwatched
)
{
// Permit not watched: left join, allow join failure or expired
$query
->
joinForConds
(
'watchlist'
)->
left
();
$orConds
[]
=
$dbr
->
expr
(
'wl_user'
,
'='
,
null
);
if
(
$this
->
enableExpiry
)
{
$query
->
joinForConds
(
'watchlist_expiry'
)->
left
();
$orConds
[]
=
$dbr
->
expr
(
'we_expiry'
,
'<='
,
$dbr
->
timestamp
()
);
}
}
else
{
// Require watched: reorderable join, do not allow expired
$query
->
adjustDensity
(
QueryBackend
::
DENSITY_WATCHLIST
)
->
joinOrderHint
(
QueryBackend
::
JOIN_ORDER_OTHER
);
$query
->
joinForConds
(
'watchlist'
)->
reorderable
();
if
(
$this
->
enableExpiry
)
{
$query
->
joinForConds
(
'watchlist_expiry'
)->
left
();
$query
->
where
(
$dbr
->
expr
(
'we_expiry'
,
'='
,
null
)
->
or
(
'we_expiry'
,
'>'
,
$dbr
->
timestamp
()
)
);
}
}
if
(
$watchedold
xor
$watchednew
)
{
if
(
$watchedold
)
{
$oldExpr
=
(
new
RawSQLExpression
(
'rc_timestamp < wl_notificationtimestamp'
)
)
->
or
(
'wl_notificationtimestamp'
,
'='
,
null
);
}
else
{
$oldExpr
=
new
RawSQLExpression
(
'rc_timestamp >= wl_notificationtimestamp'
);
}
if
(
$notwatched
)
{
// Technically redundant since comparison with null wl_notificationtimestamp
// is always false
$oldExpr
=
$dbr
->
expr
(
'wl_user'
,
'!='
,
null
)->
andExpr
(
$oldExpr
);
}
$orConds
[]
=
$oldExpr
;
}
if
(
count
(
$orConds
)
===
1
)
{
$query
->
where
(
$orConds
[
0
]
);
}
elseif
(
count
(
$orConds
)
)
{
$query
->
where
(
$dbr
->
orExpr
(
$orConds
)
);
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Oct 4 2026, 20:00 (5 w, 5 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
33/3b/5cd08332988e108f16d3d5863049
Default Alt Text
WatchedCondition.php (3 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment