PageRenderTime 121ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/app/Controller/SearchController.php

https://github.com/suzuki/candycane
PHP | 204 lines | 83 code | 20 blank | 101 comment | 11 complexity | 507f9fcbc74aa02fd3af593fe9c22bad MD5 | raw file
  1. <?php
  2. /**
  3. * Search Controller
  4. *
  5. * @package candycane
  6. * @subpackage candycane.controllers
  7. */
  8. class SearchController extends AppController {
  9. /**
  10. * Models to use
  11. *
  12. * @var array
  13. */
  14. public $uses = array('Issue');
  15. # before_filter :find_optional_project
  16. /**
  17. * Helpers
  18. *
  19. * @var array
  20. */
  21. public $helpers = array('Search', 'Text');
  22. # helper :messages
  23. # include MessagesHelper
  24. /**
  25. * Index action
  26. *
  27. * @return void
  28. */
  29. function index() {
  30. $question = isset($this->request->query['q']) ? trim($this->request->query['q']) : '';
  31. # @all_words = params[:all_words] || (params[:submit] ? false : true)
  32. $all_words = isset($this->request->query['all_words']) && $this->request->query['all_words'];
  33. $titles_only = isset($this->request->query['titles_only']) && $this->request->query['titles_only'];
  34. $scope = isset($this->request->query['scope']) ? trim($this->request->query['scope']) : '';
  35. $projects_to_search = null;
  36. # projects_to_search =
  37. # case params[:scope]
  38. # when 'all'
  39. # nil
  40. # when 'my_projects'
  41. # User.current.memberships.collect(&:project)
  42. # when 'subprojects'
  43. # @project ? ([ @project ] + @project.active_children) : nil
  44. # else
  45. # @project
  46. # end
  47. $offset = null;
  48. # offset = nil
  49. # begin; offset = params[:offset].to_time if params[:offset]; rescue; end
  50. #
  51. # # quick jump to an issue
  52. // Quick jump to an issue by matching #1234 style issue id
  53. if (preg_match('/^#?(\d+)$/', $question, $match)) {
  54. $conditions = $this->Project->get_visible_by_condition($this->current_user);
  55. $conditions['Issue.id'] = $question;
  56. $ret = $this->Issue->find('first',array(
  57. 'fields' => array('Issue.id'),
  58. 'conditions' => $conditions
  59. ));
  60. if (!empty($ret)) {
  61. $this->redirect(array(
  62. 'controller' => 'issues',
  63. 'action' => 'show',
  64. 'id' => $question
  65. ));
  66. }
  67. }
  68. #
  69. # @object_types = %w(issues news documents changesets wiki_pages messages projects)
  70. $object_types = array('issues', 'news', 'wiki_pages', 'projects');
  71. # if projects_to_search.is_a? Project
  72. # # don't search projects
  73. # @object_types.delete('projects')
  74. # # only show what the user is allowed to view
  75. # @object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
  76. # end
  77. #
  78. # @scope = @object_types.select {|t| params[t]}
  79. # @scope = @object_types if @scope.empty?
  80. $scope_types = array_intersect($object_types, array_keys($this->request->query));
  81. if (empty($scope_types)) {
  82. $scope_types = $object_types;
  83. }
  84. #
  85. # # extract tokens from the question
  86. # # eg. hello "bye bye" => ["hello", "bye bye"]
  87. # @tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
  88. # # tokens must be at least 3 character long
  89. # @tokens = @tokens.uniq.select {|w| w.length > 2 }
  90. #
  91. # if !@tokens.empty?
  92. $results = array();
  93. $results_by_type = array();
  94. if (!empty($question)) {
  95. # # no more than 5 tokens to search for
  96. # @tokens.slice! 5..-1 if @tokens.size > 5
  97. # # strings used in sql like statement
  98. # like_tokens = @tokens.collect {|w| "%#{w.downcase}%"}
  99. $limit = 10;
  100. foreach ($scope_types as $s) {
  101. $model = ClassRegistry::init(Inflector::classify($s));
  102. $fields = Set::classicExtract($model->filterArgs, '{n}.name');
  103. $conditions = $this->Project->get_visible_by_condition($this->current_user);
  104. if ($titles_only) {
  105. $fields = array_intersect(array('title', 'subject', 'name'), $fields);
  106. }
  107. $or_conditions = $model->parseCriteria(array_fill_keys($fields, $question));
  108. // @todo Refactor this Wiki specific code into the model.
  109. if ($s === 'wiki_pages') {
  110. $projectConditions = $conditions;
  111. $Wiki = ClassRegistry::init('Wiki');
  112. $wiki_ids = $Wiki->find('all', array(
  113. 'conditions' => $projectConditions,
  114. 'fields' => array($Wiki->primaryKey),
  115. 'recursive' => 0,
  116. ));
  117. $wiki_ids = Set::extract('/Wiki/id', $wiki_ids);
  118. $conditions = array(
  119. 'Wiki.id' => $wiki_ids,
  120. 'OR' => $or_conditions
  121. );
  122. } else {
  123. $conditions['OR'] = $or_conditions;
  124. }
  125. $r = $model->find('all', array(
  126. 'conditions' => $conditions,
  127. 'recursive' => 2
  128. ));
  129. foreach ($r as $k => $v) {
  130. //wiki_page doesn't relay to Project directory.
  131. if (isset($v['Wiki']['Project'])) {
  132. $v['Project'] = $v['Wiki']['Project'];
  133. }
  134. $r[$k] = $v + $model->create_event_data($v);
  135. }
  136. if (count($r)) {
  137. $results = array_merge($results, $r);
  138. }
  139. $results_by_type[$s] = $r;
  140. # r, c = s.singularize.camelcase.constantize.search(like_tokens, projects_to_search,
  141. # :all_words => @all_words,
  142. # :titles_only => @titles_only,
  143. # :limit => (limit+1),
  144. # :offset => offset,
  145. # :before => params[:previous].nil?)
  146. # @results += r
  147. # @results_by_type[s] += c
  148. }
  149. # @results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
  150. # if params[:previous].nil?
  151. # @pagination_previous_date = @results[0].event_datetime if offset && @results[0]
  152. # if @results.size > limit
  153. # @pagination_next_date = @results[limit-1].event_datetime
  154. # @results = @results[0, limit]
  155. # end
  156. # else
  157. # @pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
  158. # if @results.size > limit
  159. # @pagination_previous_date = @results[-(limit)].event_datetime
  160. # @results = @results[-(limit), limit]
  161. # end
  162. # end
  163. # else
  164. # @question = ""
  165. }
  166. # render :layout => false if request.xhr?
  167. $this->set('question', $question);
  168. $this->set('scope', $scope);
  169. $this->set('object_types', $object_types);
  170. $this->set('scope_types', $scope_types);
  171. $this->set('results', $results);
  172. $this->set('results_by_type', $results_by_type);
  173. }
  174. #
  175. #private
  176. # def find_optional_project
  177. # return true unless params[:id]
  178. # @project = Project.find(params[:id])
  179. # check_project_privacy
  180. # rescue ActiveRecord::RecordNotFound
  181. # render_404
  182. # end
  183. #end
  184. }