mirror of
				https://github.com/NodeBB/NodeBB.git
				synced 2025-10-31 11:05:54 +01:00 
			
		
		
		
	closes #1803
This commit is contained in:
		| @@ -1,3 +1,3 @@ | |||||||
| { | { | ||||||
| 	"results_matching": "%1 result(s) matching \"%2\"" | 	"results_matching": "%1 result(s) matching \"%2\", (%3 seconds)" | ||||||
| } | } | ||||||
| @@ -2,22 +2,21 @@ define('forum/search', function() { | |||||||
| 	var	Search = {}; | 	var	Search = {}; | ||||||
|  |  | ||||||
| 	Search.init = function() { | 	Search.init = function() { | ||||||
| 		var searchQuery = $('#topic-results').attr('data-search-query'); | 		var searchQuery = $('#post-results').attr('data-search-query'); | ||||||
|  |  | ||||||
| 		$('.search-result-text').each(function() { | 		$('.search-result-text').each(function() { | ||||||
| 			var result = $(this); | 			var result = $(this); | ||||||
| 			var text = result.html(); | 			var text = result.html(); | ||||||
| 			var regex = new RegExp(searchQuery, 'gi'); | 			var regex = new RegExp(searchQuery, 'gi'); | ||||||
| 			text = text.replace(regex, '<span class="label label-success">' + searchQuery + '</span>'); | 			text = text.replace(regex, '<strong>' + searchQuery + '</strong>'); | ||||||
| 			result.html(text); | 			result.html(text).find('img').addClass('img-responsive'); | ||||||
| 			result.find('img').addClass('img-responsive'); |  | ||||||
| 		}); | 		}); | ||||||
|  |  | ||||||
| 		$('#search-form input').val(searchQuery); | 		$('#search-form input').val(searchQuery); | ||||||
|  |  | ||||||
| 		$('#mobile-search-form').off('submit').on('submit', function() { | 		$('#mobile-search-form').off('submit').on('submit', function() { | ||||||
| 			var input = $(this).find('input'); | 			var input = $(this).find('input'); | ||||||
| 			ajaxify.go("search/" + input.val(), null, "search"); | 			ajaxify.go('search/' + input.val(), null, 'search'); | ||||||
| 			input.val(''); | 			input.val(''); | ||||||
| 			return false; | 			return false; | ||||||
| 		}); | 		}); | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ module.exports = function(Categories) { | |||||||
| 				return callback(err, []); | 				return callback(err, []); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			posts.getPostSummaryByPids(pids, true, callback); | 			posts.getPostSummaryByPids(pids, {stripTags: true}, callback); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -12,11 +12,13 @@ var topicsController = require('./topics'), | |||||||
|  |  | ||||||
| 	async = require('async'), | 	async = require('async'), | ||||||
| 	nconf = require('nconf'), | 	nconf = require('nconf'), | ||||||
|  | 	winston = require('winston'), | ||||||
| 	auth = require('../routes/authentication'), | 	auth = require('../routes/authentication'), | ||||||
| 	meta = require('../meta'), | 	meta = require('../meta'), | ||||||
| 	user = require('../user'), | 	user = require('../user'), | ||||||
| 	posts = require('../posts'), | 	posts = require('../posts'), | ||||||
| 	topics = require('../topics'), | 	topics = require('../topics'), | ||||||
|  | 	search = require('../search'), | ||||||
| 	plugins = require('../plugins'), | 	plugins = require('../plugins'), | ||||||
| 	categories = require('../categories'), | 	categories = require('../categories'), | ||||||
| 	privileges = require('../privileges'); | 	privileges = require('../privileges'); | ||||||
| @@ -83,69 +85,35 @@ Controllers.home = function(req, res, next) { | |||||||
| 			}); | 			}); | ||||||
| 		} | 		} | ||||||
| 	}, function (err, data) { | 	}, function (err, data) { | ||||||
|  | 		if (err) { | ||||||
|  | 			return next(err); | ||||||
|  | 		} | ||||||
| 		res.render('home', data); | 		res.render('home', data); | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| Controllers.search = function(req, res, next) { | Controllers.search = function(req, res, next) { | ||||||
| 	var start = process.hrtime(); |  | ||||||
|  |  | ||||||
| 	if (!req.params.term) { | 	if (!req.params.term) { | ||||||
| 		return res.render('search', { | 		return res.render('search', { | ||||||
|  | 			time: 0, | ||||||
| 			search_query: '', | 			search_query: '', | ||||||
| 			posts: [], | 			posts: [], | ||||||
| 			topics: [] | 			topics: [] | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	var uid = req.user ? req.user.uid : 0; | ||||||
|  |  | ||||||
| 	if (!plugins.hasListeners('filter:search.query')) { | 	if (!plugins.hasListeners('filter:search.query')) { | ||||||
| 		return res.redirect('/404'); | 		return res.redirect('/404'); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	function search(index, callback) { | 	search.search(req.params.term, uid, function(err, results) { | ||||||
| 		plugins.fireHook('filter:search.query', { |  | ||||||
| 			index: index, |  | ||||||
| 			query: req.params.term |  | ||||||
| 		}, callback); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	async.parallel({ |  | ||||||
| 		pids: function(next) { |  | ||||||
| 			search('post', next); |  | ||||||
| 		}, |  | ||||||
| 		tids: function(next) { |  | ||||||
| 			search('topic', next); |  | ||||||
| 		} |  | ||||||
| 	}, function (err, results) { |  | ||||||
| 		if (err) { | 		if (err) { | ||||||
| 			return next(err); | 			return next(err); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if(!results) { | 		return res.render('search', results); | ||||||
| 			results = {pids:[], tids: []}; |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		async.parallel({ |  | ||||||
| 			posts: function(next) { |  | ||||||
| 				posts.getPostSummaryByPids(results.pids, false, next); |  | ||||||
| 			}, |  | ||||||
| 			topics: function(next) { |  | ||||||
| 				topics.getTopicsByTids(results.tids, 0, next); |  | ||||||
| 			} |  | ||||||
| 		}, function(err, results) { |  | ||||||
| 			if (err) { |  | ||||||
| 				return next(err); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			return res.render('search', { |  | ||||||
| 				time: process.elapsedTimeSince(start), |  | ||||||
| 				search_query: req.params.term, |  | ||||||
| 				posts: results.posts, |  | ||||||
| 				topics: results.topics, |  | ||||||
| 				post_matches : results.posts.length, |  | ||||||
| 				topic_matches : results.topics.length |  | ||||||
| 			}); |  | ||||||
| 		}); |  | ||||||
| 	}); | 	}); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -203,7 +203,7 @@ topicsController.teaser = function(req, res, next) { | |||||||
| 			return res.json(404, 'not-found'); | 			return res.json(404, 'not-found'); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		posts.getPostSummaryByPids([pid], false, function(err, posts) { | 		posts.getPostSummaryByPids([pid], {stripTags: false}, function(err, posts) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return next(err); | 				return next(err); | ||||||
| 			} | 			} | ||||||
|   | |||||||
| @@ -325,7 +325,7 @@ | |||||||
| 					return callback(err); | 					return callback(err); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				posts.getPostSummaryByPids(pids, false, callback); | 				posts.getPostSummaryByPids(pids, {stripTags: false}, callback); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								src/posts.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/posts.js
									
									
									
									
									
								
							| @@ -183,7 +183,7 @@ var async = require('async'), | |||||||
| 					next(!err && canRead); | 					next(!err && canRead); | ||||||
| 				}); | 				}); | ||||||
| 			}, function(pids) { | 			}, function(pids) { | ||||||
| 				Posts.getPostSummaryByPids(pids, true, callback); | 				Posts.getPostSummaryByPids(pids, {stripTags: true}, callback); | ||||||
| 			}); | 			}); | ||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
| @@ -231,7 +231,9 @@ var async = require('async'), | |||||||
| 		}); | 		}); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	Posts.getPostSummaryByPids = function(pids, stripTags, callback) { | 	Posts.getPostSummaryByPids = function(pids, options, callback) { | ||||||
|  | 		options.stripTags = options.hasOwnProperty('stripTags') ? options.stripTags : false; | ||||||
|  | 		options.parse = options.hasOwnProperty('parse') ? options.parse : true; | ||||||
|  |  | ||||||
| 		function getPostSummary(post, callback) { | 		function getPostSummary(post, callback) { | ||||||
|  |  | ||||||
| @@ -261,7 +263,7 @@ var async = require('async'), | |||||||
| 					}); | 					}); | ||||||
| 				}, | 				}, | ||||||
| 				content: function(next) { | 				content: function(next) { | ||||||
| 					if (!post.content) { | 					if (!post.content || !options.parse) { | ||||||
| 						return next(null, post.content); | 						return next(null, post.content); | ||||||
| 					} | 					} | ||||||
|  |  | ||||||
| @@ -280,7 +282,7 @@ var async = require('async'), | |||||||
| 				post.category = results.topicCategory.category; | 				post.category = results.topicCategory.category; | ||||||
| 				post.index = results.index; | 				post.index = results.index; | ||||||
|  |  | ||||||
| 				if (stripTags) { | 				if (options.stripTags) { | ||||||
| 					var s = S(results.content); | 					var s = S(results.content); | ||||||
| 					post.content = s.stripTags.apply(s, utils.stripTags).s; | 					post.content = s.stripTags.apply(s, utils.stripTags).s; | ||||||
| 				} else { | 				} else { | ||||||
| @@ -443,7 +445,7 @@ var async = require('async'), | |||||||
| 			return callback(null, {posts: [], nextStart: 0}); | 			return callback(null, {posts: [], nextStart: 0}); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		Posts.getPostSummaryByPids(pids, false, function(err, posts) { | 		Posts.getPostSummaryByPids(pids, {stripTags: false}, function(err, posts) { | ||||||
| 			if (err) { | 			if (err) { | ||||||
| 				return callback(err); | 				return callback(err); | ||||||
| 			} | 			} | ||||||
|   | |||||||
							
								
								
									
										89
									
								
								src/search.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								src/search.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | 'use strict'; | ||||||
|  |  | ||||||
|  | var async = require('async'), | ||||||
|  | 	posts = require('./posts'), | ||||||
|  | 	topics = require('./topics'), | ||||||
|  | 	plugins = require('./plugins'), | ||||||
|  | 	privileges = require('./privileges'); | ||||||
|  |  | ||||||
|  | var search = {}; | ||||||
|  |  | ||||||
|  | module.exports = search; | ||||||
|  |  | ||||||
|  | search.search = function(term, uid, callback) { | ||||||
|  | 	var start = process.hrtime(); | ||||||
|  |  | ||||||
|  | 	async.parallel({ | ||||||
|  | 		pids: function(next) { | ||||||
|  | 			searchTerm('post', term, next); | ||||||
|  | 		}, | ||||||
|  | 		tids: function(next) { | ||||||
|  | 			searchTerm('topic', term, next); | ||||||
|  | 		} | ||||||
|  | 	}, function (err, results) { | ||||||
|  | 		if (err) { | ||||||
|  | 			return callback(err); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (!results || (!results.pids.length && !results.tids.length)) { | ||||||
|  | 			return callback(null, { | ||||||
|  | 				time: (process.elapsedTimeSince(start) / 1000).toFixed(2), | ||||||
|  | 				search_query: term, | ||||||
|  | 				results: [], | ||||||
|  | 				matchCount: 0 | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		getMainPids(results.tids, function(err, mainPids) { | ||||||
|  | 			if (err) { | ||||||
|  | 				return callback(err); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			results.pids.forEach(function(pid) { | ||||||
|  | 				if (mainPids.indexOf(pid) === -1) { | ||||||
|  | 					mainPids.push(pid); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
|  |  | ||||||
|  | 			async.filter(mainPids, function(pid, next) { | ||||||
|  | 				privileges.posts.can('read', pid, uid, function(err, canRead) { | ||||||
|  | 					next(!err && canRead); | ||||||
|  | 				}); | ||||||
|  | 			}, function(pids) { | ||||||
|  | 				posts.getPostSummaryByPids(pids, {stripTags: false, parse: false}, function(err, posts) { | ||||||
|  | 					if (err) { | ||||||
|  | 						return callback(err); | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					callback(null, { | ||||||
|  | 						time: (process.elapsedTimeSince(start) / 1000).toFixed(2), | ||||||
|  | 						search_query: term, | ||||||
|  | 						results: posts, | ||||||
|  | 						matchCount: posts.length | ||||||
|  | 					}); | ||||||
|  | 				}); | ||||||
|  | 			}); | ||||||
|  | 		}); | ||||||
|  | 	}); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | function getMainPids(tids, callback) { | ||||||
|  | 	topics.getTopicsFields(tids, ['mainPid'], function(err, topics) { | ||||||
|  | 		if (err) { | ||||||
|  | 			return callback(err); | ||||||
|  | 		} | ||||||
|  | 		topics = topics.map(function(topics) { | ||||||
|  | 			return topics.mainPid; | ||||||
|  | 		}); | ||||||
|  | 		callback(null, topics); | ||||||
|  | 	}); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function searchTerm(index, term, callback) { | ||||||
|  | 	plugins.fireHook('filter:search.query', { | ||||||
|  | 		index: index, | ||||||
|  | 		query: term | ||||||
|  | 	}, callback); | ||||||
|  | } | ||||||
|  |  | ||||||
		Reference in New Issue
	
	Block a user