There is currently a hard cap of badge display count.
We'll want to be able to request a different count for other purposes:
cleaning up old notifications, for example. We want to keep around a
certain amount of motifications (which is higher than the display count)
so we must be able to query a different count.
Change-Id: Id460fd7f46e397d22da49283b30fd12a6bbb0c9f
Both in the order of the cross-wiki bundles themselves, and
in the message in the notification body.
ForeignNotifications tracks timestamps per wiki per section,
and exposes these through getWikiTimestamp(). ApiEchoNotifications
adds these timestamps to the sources manifest, and also sorts
the list of wikis by timestamp (it'd be nicer to do this in
ForeignPresentationModel instead, but then we'd have to create a new
ForeignNotifications instance which causes a duplicated DB query).
NotificationsModel receives the timestamp for its wiki as its
fallback timestamp, and makes getTimestamp() return this value
during the pre-population phase. This causes its parent to
automatically sort it correctly.
Because the timestamp of a wiki depends on the section (alerts vs messages),
we can't put it in the global sources manifest at the top level
of the API response. Instead, get rid of this global sources
manifest and put all the sources data in the foreign notifications
directly. This allows us to specify different timestamps, and also
allows us to get rid of code in EchoApi that was already remapping
the API response to this format.
Bug: T130298
Change-Id: Ie083fbb1ccaf74fbe804633d87ef03c9e71b120f
This involves:
* Making this value no longer admin-configurable.
* Changing getNotificationCountForOutput to return only a single value
Since there is no + in the formatted value anymore, we can actually
use the same value for both.
This is a B/C break, but hopefully worth it to simplify the method
call.
For now, the excess parameter is just marked unused. It could be
removed at some point if the translations are updated.
This must be merged at the same time as:
* Flow - Ibfa56b1af9e8c56b4c5f900e0d487bc09688b2a2
* MobileFrontend - Ibf784b279d56773a227ff261b75f2b26125bbb63 (well, MF
can be merged first)
* translatewiki - I2a4b6938aed49e4101deb6b9351c43656a863490
Also, change 1 to One/one, per Siebrand on the task. This can easily
be dropped/undone if we don't want it.
Also, remove reference to no-longer-existent notification-page-linked-bundle
Bug: T127288
Change-Id: Iabeaae747f99980c0610d552f6b38f89d940b890
Add a 'mark as unread' to all unread notifications and allow them
to be marked unread. These notifications will no longer be automatically
marked as read when the pages they refer to are visited.
Bug: T73564
Change-Id: I677d3c0399e46fd7c35531df1cc0e61db2d4eb1b
Don't try to render if page was deleted, and fix 'extra' parameter
(was breaking message key and thus rendering)
Bug: T129641
Change-Id: I5d0fdfd3921427993211969eb5793f8e9e7667a8
The previous implementation did the following weird things:
* Stripped tags before parsing
* Stripped templates before parsing using a hacky while loop
that bails after ten attempts
* Decoded entities using htmlspecialchars_decode(), while
html_entity_decode() makes more sense
* ...which meant it had to manually convert   back
to spaces, which is not necessary if you use html_entity_decode()
* Removed any single braces ('{' and '}') from the output
* Rejected the entire output if there were any entities left,
which is fairly likely since htmlspecialchars_decode()
only decodes a few of them
Instead of all this, just parse, strip tags, decode entities
(all of them, not just a few), trim and truncate. In particular,
don't strip templates, because we use getTextSnippet() in mention
notifications, which look weird when {{ping}} templates are stripped.
Bug: T129531
Change-Id: I956b2f6badc40d2f5bf90a0458ccab8b8fc6fefb
This reverts commit e372f3ce6f.
The previous attempt was broken because
EchoTargetPageMapper::fetchByUserPageId() returns a list of
EchoTargetPage objects, not a single one.
Bug: T117531
Change-Id: Id02a025e3736a7b92d9d6fb8adf29ef674f8e2fa
Title::newFromId() can return null, and if this were the case the
instance caching would never work, so it would continually make useless
database queries.
Initialize the $title member variable as false to begin with, and use
that to check whether we've already checked Title::newFromId().
Change-Id: Id07c2c963ffcd03e212bed0a666735bcb68b92e0
We calculate how many messages and alerts are being marked as read, and
subtract them from the count since the database and caches won't be
updated until the end of the request.
For performance, we also get the event_type while doing the
EchoTargetPage lookup query to avoid having to query it individually
later on.
Bug: T117531
Change-Id: I0d9302adf1b4b07a4ff26a04b00d4498aa3fe7ee
When $adjustLength is false, truncation will only happen
when the string is longer than the limit + the length of
the ellipsis to avoid the case where the ellipsis make
the string longer than the original.
Bug: T121822
Change-Id: I731a3c38b96ede6c6510f64771be0b9662dcba43
It's terrible that in groupbysection mode, you still have to pass
messageunreadfirst and alertunreadfirst separately, but at least
this way the unreadfirst feature is available at all in the
non-grouped mode.
Change-Id: Ifb0707be484bda8e33810c888bae1d008cac2d9f
API requests with notgroupbysection disabled but notsection set
to 'alert' would return foreign notification bundles for both
alerts and messages, separately.
The frontend always pasess notgroupbysection=1 in practice because
notmessageunreadfirst=1 doesn't work without it; but regardless of
that, the API module shouldn't return a foreign notification bundle
for messages when only alerts are requested.
Change-Id: I9fa6d1411a8c121591ce6dd75ee8052bcdcb478b
Using wiki names in the header is problematic because the messages
we were using weren't designed to be used in a sentence, only in headings.
This removes the wiki names from the sentence in the header, and
instead puts a comma-separated list (with "and") of wikis in the body.
The messages keep $3 and $4 for backwards compatibility, so translations
of the form "from Commons and 2 other wikis" will keep working.
Bug: T121936
Change-Id: Ideeba794e260b3c388fa29226b53197c050162ef
It wasn't meant to be there, and flow-mention doesn't have it either.
We also don't have any other notification types with
three prioritized secondary links.
Bug: T125949
Change-Id: Icbffa185b1116b1a6beb9bb3585339fdf7e82cdd
The approach here is to use $msg->escaped() to
remove all markup and then replace new lines
with a single space.
Bug: T128062
Change-Id: I1d5a6e57fbae9b6a441671beff1c60720b9445d5
Some notifications return relative urls in their
primary or secondary links. This change makes those
urls absolute so they point to the right wiki
when viewed from another wiki (cross-wiki notifications).
Bug: T125738
Bug: T127697
Change-Id: Ib65337430eb2484f9491668a9998deef70589fb1
It used to be like this, but in order to get the messages badge to show
in the correct circumstances, I had to know if the user had ever had
foreign messages before & I also needed euw_messages_ts even if those
messages had already been read.
Now that we're unconditionally showing messages, we no longer need these
0-value rows.
Bug: T127731
Change-Id: I1fc13bf0e5133ae39224f66d1b5a59c769bfcee2
Current situation: cross-wiki can be enabled on certain wikis &
disabled on others.
Code used to check if cross-wiki was enabled before fetching the
status of unread messages on foreign wikis. However, it would then
write that result to a shared memcached key.
The cross-wiki check should not happen before data is stored to
cache: what is stored should always be for all wikis. Only when
we fetch it, should we check if cross-wiki is enabled. And if it's
not, we can't use the cross-wiki data - we have to hack around it
ourselves...
Bug: T124372
Change-Id: I3d3d54fc3cbfbf73b51e97acfd8d355dd0cea36d
when the subject line is left with the default
generated value, we take the begining of the
email content to add a preview in the
notification.
Bug: T121831
Change-Id: Ib7c646f6709c7100ef51186f84fe14807d6a211a
Objects can be different instances (and for User, they can contain
very different data) in which case they wouldn't be recognized even
if they were the same user.
Let's find by ID instead.
Bug: T124803
Change-Id: Ia166fd4190f264354cea83d98047c62c7e0714ea
This code is completely useless:
* for format=flyout, the new EchoFlyoutFormatter.php will be run
* and even that one has already been deprecated as it was replaced
by format=model (flyout html is now built in client)
Change-Id: Iea23abb66397ecc4efb575fe33fdbedc5b4e0f70
The existing "html" formatter was used for the special page & is now
superseeded by the new-style "special" formatter. Previous "html"
notifications are no longer used & could even be broken.
Instead of keeping the old "html" formatter around, we should let it
use the new formatter (and eventually just kill that redundant format
in the API)
Change-Id: Ibbd40aafa9eee718b196ad62f6edc99629b263b4
We now have 'special' in $formatters, there's no need to keep
the mapping to the legacy formatter around.
Change-Id: I66f330e8c84a50858658361caef521a3e5717d58
Right now, if certain users should be excluded, that would have
to be part of the user-locators already. This is annoying because
it's hard to write "generic" user locators when you want to exclude
just a couple of people in certain cases.
In Flow, for example, we have user-locators for users watching a
board or topic. We don't want to send the notification to people
that have also been mentioned in that post (they'll get a separate
notification). We could build that exception into those
user-locators, but then we couldn't re-use them in other places...
This basically means we couldn't use EchoUserLocator::locateUsersWatchingTitle,
we would have to roll our own that also excludes mentioned users.
Instead, this lets you add 'user-filters' (that functionality
actually exists already, but is not currently exposed), which
lists users to not send the notification to, even though they could
be in a user-locator.
Bug: T125428
Change-Id: Ifa0e2d3283f57624af4c5ec264f9f66223508e83
Split mentions into 4 cases:
- Mentioned on article talk page
- Mentioned on agent's talk page
- Mentioned on another user's talk page
- Mentioned on any other page
Adjust secondary link
icon: article or talk
text: without namespace for article and article talk
Bug: T56433
Change-Id: Ibf965dad4f9cc468fdd4321b2450d6eaec0ac1d7
Wrap the CallbackFilterIterator backport class in a conditional check
for PHP runtimes that include the class natively. This really should
only be needed for linting as the class is loaded via an autoloader
and thus should not be loaded if the runtime already has it
available.
Bug: T124828
Change-Id: I39d27385186d4693a8babdd2b818e6b4bc16255a
Only display when it's different than the pre-populated
edit summary (Undo revision 123 by User).
Bug: T121808
Change-Id: I5a00ff174fd31fdbf776a06b7b9375f63b921677
There was no point in letting it extend EchoFlyoutFormatter instead
of the base EchoEventFormatter. The only things in EchoFlyoutFormatter
are formatModel & getIconURL, both of which aren't being called.
Change-Id: I89511530a41976974f4d51d55379a617dfe503ec
WikiMap is almost useful for this purpose, but not quite
because it doesn't provide the script path, only the article path.
Change-Id: I1627d58cab5ff518be3c3e14e05a53899b083503
All extensions seem to have been updated to use the current formats,
so we can get rid of this tech debt.
Depends-On: I7503db28b0d81fb818b525ea9362e49b9b56342a
Change-Id: Idbcbbf95eab1172015bceea4e8124ba4c639efa8
Also updated description value in agent link: '' is used everywhere
else to mean "no description" (because that's exactly what '' is)
Change-Id: Ib77c0f1843593abf67e9d726a80bb4fbe1ec7d84
We already output unix timestamp both in user preference timezone as well as
utc, but we only had the user timezone version for TS_MW format.
While we could change the frontend to use the unix timestamp format, I don't see
any reason not to also include the MW format in utc. Frontend can now easily use
that.
Also fixed creation of the moment object. The timestamp was created as UTC, but
the way it got there was wrong: it expects the timezone offset (Z) to be
included in the timestamp, which is not the case (so it just ended up at +0:00,
which was fine, but confusing). I removed the 'Z' and forced it to be
interpreted as utc.
Bug: T121813
Change-Id: I09403615a1ffbde5dd69af9914afdbdd86cbfe4d
We're trying to get rid of links in notification
messages, and the link was redundant with the primary link
in both cases.
Change-Id: I69e888a355c263b5a8c5ca7a46430746895de44c
They're currently auto-converted to the new format, but ideally,
we wouldn't need that B/C code. And since this is the extension
others will likely look at for examples when implementing, we
should do it right here.
Also: there is no B/C correction for missing keys in secondary
links (description, icon).
Change-Id: If1a8b9911e81bb4c565f21a4b9e31fdc73426d93
Also removes tests for the class.
Bug: T119253
Change-Id: I4c0d7187c2b847297dd0867faecba26185cfba37
Depends-On: Iccafbbdb06711463fee0f30a11326c7771df30e2
Right now, it'll only respond a certain, fixed, amount,
not allowing you to paginate the list.
Note: haven't properly tested all possible cases yet!
Change-Id: I84761b13a1b9203cb8e3fcc80941d739cd28659f
The only difference at this point is that fetchByUser initializes
the EchoNotification object with $targetPages. It doesn't really
matter that it doesn't have the target pages, since fetchUnreadByUser
is currently only used in the flyout, where those target pages aren't
used. But regardless of what method was used to fetch the data, I
think the data should be the same.
And now, there's less code duplication...
Change-Id: I04c7b98794af5427a2217dd337108e7eea1e65c5
Added code to redirect the user and display a short message informing
them of the need to login.
Bug: T118873
Change-Id: I2145bc1502dbd19d660302d9f19e0d4a2ad5ad50
Presentation models that display the number of bundled notifications
typically group these by a property like agent or page ID. For example,
every edit someone makes to a user talk page generates an event,
so there could be 5 edit-user-talk events by only 2 distinct users;
in that case we want to display "Foo and 1 other user left a message",
not "Foo and 4 other users".
With this change, a presentation model that wants such behavior
can pass a callback to getBundleCount() that retursn the user ID, which
will cause getBundleCount() to return the number of distinct
users rather than the total number of notifications.
Change-Id: I79c8dd14277eff0d2ec27f155b1d13dca1e571a8
I'm not really sure where to stick the primary link. I could wrap the
entire notification in a <a> tag, but all the text becomes ugly (I
suppose we could hack around it with CSS?). For now I just added it
before all the secondary links.
Change-Id: I4f6add9ecfb367660d1a6346825382ad415bdb77
The implementation of this sucks as the presentation model
should not be making database queries. But the API it provides
is what we want and will be supported even if the backend
implementation is changed.
Change-Id: Ifd0d11260990fd0e00e8f32eee273f9717d3e1fb
We should probably merge this ASAP now that a lot of presentation
models still have to be implemented. There's a bit of B/C code that
will take care of the previous format, but it would be nice to be
able to remove that soon.
Meanwhile I've also changed getPrimaryLink to follow the same format.
Bug: T115421
Change-Id: Ic18a050d2ee0239f287a6d55c572df6f8aebb59a
This implements a backend layer and database storage for tracking what
wikis a user has unread notifications on. It is not yet exposed via any
API.
Whenever the notification counts on the local wiki are reset, a deferred
update is queued to also update the central database table.
Change-Id: Id1498bdeb5811d6848dc66781ffca03e726eab90
Instead of relying on the frontend to render, this enables the frontend
to do it.
The API will now accept a new format: 'model', which is basically the
presentation model's data in json format.
Some of the render code is currently only in the backend (e.g. get icon
path from icon type) so other api formats will stay available. At some
point, however, we may be able to kill those.
Bug: T115418
Change-Id: Ibc3ad54c94d6ea9bf751f3927cf69e1d062f4780
It's basically impossible for DatabaseBase::select() to return false now
that ignoreErrors() is protected. So always return an array so callers
don't have to worry about false.
And remove a test that checked the result if DatabaseBase::select() did
return false.
Change-Id: I9ca8511585403d8c0ec262898ad4e61c2b038d51
`getMessageWithAgent` is used by `getHeaderMessage` is can
be reused by other presentation models who need the
agent in their body message.
Bug: T118059
Change-Id: I0cbccaeb8b6e60d03bc75bc85c74591619b4399a
Since EchoEventPresentationModel::canRender can reject notifications,
its result should no longer be used for infinite scroll.
Current code checks if the amount of to-be-rendered data exceeds what
we need to display, but if we reject some notifications that may no
longer be the case, even though there is more data still.
Change-Id: I3e5f8c2d1fc0c63db7b277324c96af043689ddce
getTextSnippet() has a `Language` type hint that will fatal if $wgLang
is a StubUserLang object, so make sure we unstub it if nothing else
already has.
Bug: T118542
Change-Id: I847680074fbbf95bbe3b6002151d2a18c45ebe6e
Wikis can customize the 'notification-welcome-link' to a page title
(like "Project:Welcome" for example) and the "Welcome!" notification new
users receive will have a primary link to that page.
Bug: T117509
Change-Id: I29f6d69db480fa7d39573941e762c4dad8737ed0
Because 'welcome' doesn't.
Returning `false` indicates that there is no link, and the
FlyoutFormatter was updated accordingly.
Change-Id: Ifd329b396f3361fc7c08c607a6407181ffdb8bf6
This seems better for availability than stopping the world
and rolling everything back (or just throwing post-commit
errors that didn't stop the original change anyway).
Change-Id: I816b3cb5f0d26de608e620a01571a332aa832c05
The conversion of EchoEvent into a EchoEventPresentationModel is now
done by EchoFlyoutFormatter, instead of having each subclass do it. It
also does the canRender() check so subclasses don't need to worry about
it.
The subclasses no longer have access to the underlying EchoEvent object,
so the timestamp is exposed in EchoEventPresentationModel.
Change-Id: I7f0a650373eebac7aa2231b1795b51a6d031ad67