Index: trac/ticket/web_ui.py
===================================================================
--- trac/ticket/web_ui.py (revision 6697)
+++ trac/ticket/web_ui.py (working copy)
@@ -476,6 +476,8 @@
# Store a timestamp for detecting "mid air collisions"
'timestamp': str(ticket.time_changed)})
+ data['backrefs'] = self._get_backrefs(context, ticket)
+
self._insert_ticket_data(req, ticket, data,
get_reporter_id(req, 'author'), field_changes)
@@ -1000,6 +1002,39 @@
for key in field_changes:
ticket[key] = field_changes[key]['new']
+ def _get_backrefs(self, context, ticket):
+ id = ticket.id
+ cursor = context.db.cursor()
+ refs = []
+
+ cursor.execute("SELECT 'ticket', id, description "
+ "FROM ticket WHERE description LIKE '%%#%s%%' "
+ " OR description LIKE '%%ticket:%s%%' "
+ "UNION "
+ "SELECT 'ticket', t.id, newvalue "
+ "FROM ticket_change c JOIN ticket t on c.ticket = t.id "
+ "WHERE newvalue LIKE '%%#%s%%' "
+ " OR newvalue LIKE '%%ticket:%s%%' "
+ "UNION "
+ "SELECT 'changeset', rev, message "
+ "FROM revision WHERE message LIKE '%%#%s%%' "
+ " OR message LIKE '%%ticket:%s%%' "
+ "UNION "
+ "SELECT 'wiki', name, text "
+ "FROM wiki WHERE (text LIKE '%%#%s%%' "
+ " OR text LIKE '%%ticket:%s%%') "
+ "AND version = (SELECT max(version) FROM wiki w "
+ " WHERE w.name = wiki.name) "
+ "ORDER BY 1 desc, 2"
+ % ((id,) * 8))
+
+ for idx, row in enumerate(cursor):
+ rtyp, rid, text = row
+ # check whether the link is an single word
+ if re.search(r"(\W|^)#%s(\W|$)" % id, text):
+ refs.append(context(rtyp, rid))
+ return refs
+
def _prepare_fields(self, req, ticket):
context = Context.from_request(req, ticket.resource)
fields = []
Index: trac/ticket/templates/ticket.html
===================================================================
--- trac/ticket/templates/ticket.html (revision 6697)
+++ trac/ticket/templates/ticket.html (working copy)
@@ -186,6 +186,21 @@
+
+
+
Index: trac/versioncontrol/web_ui/changeset.py
===================================================================
--- trac/versioncontrol/web_ui/changeset.py (revision 6697)
+++ trac/versioncontrol/web_ui/changeset.py (working copy)
@@ -611,6 +611,8 @@
info = None
changes.append(info) # the sequence should be immutable
+ data['backrefs'] = self._get_backrefs(context, rev)
+
data.update({'has_diffs': has_diffs, 'changes': changes, 'xhr': xhr,
'filestats': filestats, 'annotated': annotated,
'files': files, 'location': self._get_location(files),
@@ -931,6 +933,42 @@
old=data['old_rev']) + query
return tag.a(label, class_="changeset", title=title, href=href)
+ def _get_backrefs(self, context, rev):
+ cursor = context.db.cursor()
+ refs = []
+
+ cursor.execute("SELECT 'ticket', id, description "
+ "FROM ticket WHERE description LIKE '%%[%s]%%' "
+ " OR description LIKE '%%r%s%%' "
+ " OR description LIKE '%%changeset:%s%%' "
+ "UNION "
+ "SELECT 'ticket', t.id, newvalue "
+ "FROM ticket_change c JOIN ticket t on c.ticket = t.id "
+ "WHERE newvalue LIKE '%%[%s%%' "
+ " OR newvalue LIKE '%%r:%s%%' "
+ " OR newvalue LIKE '%%changeset:%s%%' "
+ "UNION "
+ "SELECT 'changeset', rev, message "
+ "FROM revision WHERE message LIKE '%%[%s]%%' "
+ " OR message LIKE '%%r:%s%%' "
+ " OR message LIKE '%%changeset:%s%%' "
+ "UNION "
+ "SELECT 'wiki', name, text "
+ "FROM wiki WHERE (text LIKE '%%[%s]%%' "
+ " OR text LIKE '%%r:%s%%' "
+ " OR text LIKE '%%changeset:%s%%' ) "
+ " AND version = (SELECT max(version) FROM wiki w "
+ " WHERE w.name = wiki.name) "
+ "ORDER BY 1 desc, 2"
+ % ((rev,) * 12))
+
+ for idx, row in enumerate(cursor):
+ rtyp, rid, text = row
+ # check whether the link is an single word
+ if re.search(r"(\W|^)(\[|r:|changeset:)%s\]?(\W|$)" % id, text) or 1:
+ refs.append(context(rtyp, rid))
+ return refs
+
# ISearchSource methods
def get_search_filters(self, req):
Index: trac/versioncontrol/templates/changeset.html
===================================================================
--- trac/versioncontrol/templates/changeset.html (revision 6697)
+++ trac/versioncontrol/templates/changeset.html (working copy)
@@ -116,6 +116,19 @@
${changeset.message}
+
+
+ Referenced by:
+
+
+ ${ref.shortname()}
+
+
+
+
Location:
Index: trac/wiki/web_ui.py
===================================================================
--- trac/wiki/web_ui.py (revision 6697)
+++ trac/wiki/web_ui.py (working copy)
@@ -491,6 +491,8 @@
WikiSystem(self.env).get_pages(prefix) if
'WIKI_VIEW' in req.perm('wiki', template)]
+ data['backrefs'] = self._get_backrefs(context, page)
+
# -- prev/up/next links
if prev_version:
add_link(req, 'prev',
@@ -532,6 +534,35 @@
action='diff',
version=page.version))
+ def _get_backrefs(self, context, page):
+ id = page.id
+ cursor = context.db.cursor()
+ refs = []
+
+ cursor.execute("SELECT 'ticket', id, description "
+ "FROM ticket WHERE description LIKE '%%%s%%' "
+ "UNION "
+ "SELECT 'ticket', t.id, newvalue "
+ "FROM ticket_change c JOIN ticket t on c.ticket = t.id "
+ "WHERE newvalue LIKE '%%%s%%' "
+ "UNION "
+ "SELECT 'changeset', rev, message "
+ "FROM revision WHERE message LIKE '%%%s%%' "
+ "UNION "
+ "SELECT 'wiki', name, text "
+ "FROM wiki WHERE text LIKE '%%%s%%' "
+ "AND version = (SELECT max(version) FROM wiki w "
+ " WHERE w.name = wiki.name) "
+ "ORDER BY 1 desc, 2"
+ % ((id,) * 4))
+
+ for idx, row in enumerate(cursor):
+ rtyp, rid, text = row
+ # check whether the link is an single word
+ if re.search(r"(\W|^)(wiki:)?%s(\W|$)" % id, text):
+ refs.append(context(rtyp, rid))
+ return refs
+
# ITimelineEventProvider methods
def get_timeline_filters(self, req):
Index: trac/wiki/templates/wiki_view.html
===================================================================
--- trac/wiki/templates/wiki_view.html (revision 6697)
+++ trac/wiki/templates/wiki_view.html (working copy)
@@ -43,6 +43,16 @@
${list_of_attachments(attachments, compact=True)}
+
+ Referenced by:
+
+ ${ref.shortname()}
+
+
+