92 $options += [
'namespaceIds' => [] ];
95 !isset( $options[
'sort'] ) || in_array( $options[
'sort'], [ self::SORT_ASC, self::SORT_DESC ] ),
97 'must be SORT_ASC or SORT_DESC'
100 !isset( $options[
'filter'] ) || in_array(
101 $options[
'filter'], [ self::FILTER_CHANGED, self::FILTER_NOT_CHANGED ]
103 '$options[\'filter\']',
104 'must be FILTER_CHANGED or FILTER_NOT_CHANGED'
107 ( !isset( $options[
'from'] ) && !isset( $options[
'until'] ) && !isset( $options[
'startFrom'] ) )
108 || isset( $options[
'sort'] ),
109 '$options[\'sort\']',
110 'must be provided if any of "from", "until", "startFrom" options is provided'
113 $db = $this->dbProvider->getReplicaDatabase();
115 $queryBuilder = $db->newSelectQueryBuilder()
116 ->select( [
'wl_namespace',
'wl_title',
'wl_notificationtimestamp' ] )
117 ->from(
'watchlist' )
118 ->caller( __METHOD__ );
119 $this->addQueryCondsForWatchedItemsForUser( $db, $user, $options, $queryBuilder );
120 $this->addQueryDbOptionsForWatchedItemsForUser( $options, $queryBuilder );
122 if ( $this->expiryEnabled ) {
124 $queryBuilder->leftJoin(
'watchlist_expiry',
null,
'wl_id = we_item' )
125 ->andWhere( $db->expr(
'we_expiry',
'>', $db->timestamp() )->or(
'we_expiry',
'=',
null ) );
127 $res = $queryBuilder->fetchResultSet();
130 foreach ( $res as $row ) {
131 $target = PageReferenceValue::localReference( (
int)$row->wl_namespace, $row->wl_title );
136 $this->watchedItemStore->getLatestNotificationTimestamp(
137 $row->wl_notificationtimestamp, $user, $target
139 $row->we_expiry ??
null
143 return $watchedItems;