Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
05b96c4
german locale
cforce Jan 25, 2012
cfc5434
Updated QuestionMailer templates to work with Redmine >= 1.3.0
sleavitt Jun 10, 2012
0ca798f
Renamed QuestionMailer templates to work with >= Redmine 1.3.0
sleavitt Jun 10, 2012
ef654f0
Updated plugin to work with Redmine 2.0
sleavitt Jun 10, 2012
c5a171e
@journal.render_detail is not present in Redmine, probably a hold-ove…
sleavitt Jun 11, 2012
ccc828c
Refactored ActiveRecord::Relation patches to avoid issues relating sc…
sleavitt Jun 22, 2012
b41980f
Updated QuestionMailer patch to not use deprecated syntax.
sleavitt Jul 10, 2012
c61a146
Merge branch 'master' of https://github.com/edavis10/question_plugin
cforce Jul 25, 2012
fb1135f
Merge branch 'redmine_2.0' of https://github.com/sleavitt/question_pl…
cforce Jul 25, 2012
2d517af
added redmine 1.4 and 2.0 comatible routes
cforce Jul 25, 2012
ce4323a
Compatibility with redmine 2.1
ares Oct 18, 2012
461d304
Fixed question filtering/ordering and locales encoding
thorin Oct 24, 2012
9ceae32
Merge pull request #1 from thorin/master
ares Oct 25, 2012
a1dec3e
Disabled gravatar of the inquired user: bronken since we don't have a…
thorin Nov 5, 2012
0775f5e
Czech translation
ares Nov 14, 2012
41074b5
Added missing czech translation
ares Nov 14, 2012
776485f
Limit autocomplete users only to members of a given project
ares Nov 14, 2012
a1f3b49
Merge pull request #1 from igloonet/master
cforce Nov 20, 2012
93e5892
Russian translation added
salashnik Dec 18, 2012
f292b31
More elegant look
salashnik Dec 18, 2012
e827720
Display answered questions in history as question but with another style
salashnik Dec 18, 2012
8bd06fa
Configurable option for autocomplete
salashnik Dec 18, 2012
5064f19
Possibility choose questions for answer (configurable option)
salashnik Dec 19, 2012
b99b2a8
Changed subject & sender in mailer
salashnik Dec 19, 2012
60bcdf7
Small fix for russian translation
salashnik Dec 20, 2012
8e36a14
Some fixes for compatibility with latest redmine trunk
salashnik Dec 20, 2012
3a4fb33
Merge pull request #3 from NEXSTEP/master
cforce Dec 20, 2012
f9968ba
Merge branch 'master' of https://github.com/igloonet/question_plugin
thorin Jan 5, 2013
67bd45e
Minor spacing change for readability
Jan 13, 2013
09f126e
Fix to ensure proper color coding of open questions on an issue
Jan 13, 2013
567c92e
Fixed to work with the latest redmine version
thorin May 10, 2013
5af1156
Question assigned to filter not working when assigned to none or any
thorin May 10, 2013
5b3665a
Changed from Query to IssueQuery
thorin May 16, 2013
d5daec4
Merge from sleavitt
thorin May 16, 2013
794d264
Fixed truncate on question_issue_patch
thorin Jul 2, 2013
c51f084
fixed plugin incompatibility
cforce Jul 17, 2013
a4028fb
updated locale
cforce Jul 17, 2013
1db5709
Merge pull request #2 from cforce/master
thorin Jul 28, 2013
61fde4f
After merge fixes
Aug 9, 2013
6545eb5
works and fixed for redmine 2.3.2
cforce Aug 16, 2013
26d4a5f
fix settings
cforce Aug 16, 2013
5dbbaf8
New feature: Can obfuscate name/address of asker/answerer and/or ques…
Aug 27, 2013
930533b
Imitation of previous behavior
Sep 10, 2013
01ff189
duno
cforce Sep 27, 2013
bc34396
fixed javascript ref bug
cforce Sep 29, 2013
38ee6c8
Merge branch 'master' of https://github.com/cforce/question_plugin
cforce Sep 29, 2013
e8d354a
Merge branch 'master' of https://github.com/igloonet/question_plugin
cforce Sep 29, 2013
55ffe3a
mefrged all in and fixed bugs
cforce Sep 30, 2013
82ae2dd
Merge branch 'feat-obfuscate' of https://github.com/C-Duv/question_pl…
cforce Sep 30, 2013
271548b
added locale
cforce Sep 30, 2013
4538a34
Replaced windows \r\n to linux \n
salashnik Feb 11, 2014
1403776
Refactor & last redmine trunk compatibility
salashnik Feb 13, 2014
bddb420
"Questions for me" on *every* page
salashnik Feb 13, 2014
a955e3f
settings for questions banner on/off
salashnik Feb 13, 2014
b7015ac
More nice looking banner
salashnik Feb 13, 2014
965f266
Double sending removed
salashnik Feb 13, 2014
096c22f
Possibility remove question from banner (hide)
salashnik Feb 20, 2014
80caa6c
Fix internal error when "questions" column visible in issue list (in …
salashnik Feb 20, 2014
e8ae612
Fix question mailing crash in redmine > 2.3
salashnik Feb 20, 2014
86981c4
Fix answering questions
tamtamchik Mar 25, 2014
b0f5ed4
Merge pull request #1 from tamtamchik/patch-1
salashnik Mar 25, 2014
0e155d6
When counting questions use display_subproject_issues setting
salashnik Apr 14, 2014
e01d025
Preload questions for all journal entries for faster display
salashnik May 19, 2014
9e60850
add 'flash' class to banner
salashnik May 28, 2014
da5953f
fix css for banner
salashnik May 29, 2014
c087034
append 'via' parameter to match method
ichizok Mar 3, 2015
9e52ff9
update requires_redmine version
ichizok Mar 3, 2015
6a987ec
fix finder-method to be compatible with Redmine 3.0
ichizok Mar 3, 2015
c721c1e
fix an error while saving question
ichizok Mar 4, 2015
f50c9f9
More expressive notification mail
michalgritzbach Jan 26, 2015
73761be
User#full_name does not exist
michalgritzbach Jan 26, 2015
e0a1759
Odstraneni webratu z gemfile - dela problemy pri deployi
kepi Feb 19, 2015
1f4e6a4
Journal Observer patch moved to Journal patch
michalgritzbach Feb 23, 2015
fbff470
Added users array in mails (for RM core issue mail partial)
michalgritzbach Mar 13, 2015
10baa73
turkish translation
giraypultar Jul 25, 2015
a4ab515
Updated and improved Czech translation
kepi Mar 13, 2019
4913a14
Reimplemented new question e-mail title
kepi Mar 27, 2019
67a3645
Fix forgotten localization symbols for previous commit
kepi Mar 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +0,0 @@
group :test do
gem 'webrat'
end
Empty file modified Rakefile
100755 → 100644
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
class QuestionsController < ApplicationController
class IssuequestionsController < ApplicationController
unloadable
layout 'base'

Expand All @@ -12,18 +12,31 @@ def user_issue_filter
new_filter_for_questions_assigned_to(params[:user_id])
redirect_to :controller => 'issues', :action => 'index', :project_id => params[:project]
end

def hide
@question = Question.find(params[:id])
@question.hidden = true
if @question.save
redirect_to :back
end

end

def autocomplete_for_user_login
if params[:user]
@users = User.active.all(:conditions => ["LOWER(login) LIKE :user OR LOWER(firstname) LIKE :user OR LOWER(lastname) LIKE :user", {:user => params[:user]+"%" }],
:limit => 10,
:order => 'login ASC')
if params[:issue_id] && Setting.plugin_question_plugin[:only_members] == 1
@issue = Issue.find(params[:issue_id])
base = @issue.project.users
else
base = User
end
q = (params[:q] || params[:term] || params[:user]).to_s.strip.downcase
if q.present?
@users = base.active.where(["LOWER(login) LIKE :user OR LOWER(firstname) LIKE :user OR LOWER(lastname) LIKE :user", {:user => q + "%" }]).
limit(10).
order('login ASC')
end
@users ||=[]

if params[:issue_id]
@issue = Issue.find_by_id(params[:issue_id])
end
render :layout => false
end

Expand All @@ -32,7 +45,7 @@ def autocomplete_for_user_login
def new_filter_for_questions_assigned_to(user_id)
@project = Project.find(params[:project]) unless params[:project].nil?

@query = Query.new(:name => "_",
@query = (ActiveSupport::Dependencies::search_for_file('issue_query') ? IssueQuery : Query).new(:name => "_",
:filters => {'status_id' => {:operator => '*', :values => [""]}}
)
@query.project = @project unless params[:project].nil?
Expand Down
30 changes: 16 additions & 14 deletions app/models/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@ class Question < ActiveRecord::Base
belongs_to :assigned_to, :class_name => "User", :foreign_key => "assigned_to_id"
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
belongs_to :issue
belongs_to :journal
belongs_to :journal, :class_name => "Journal", :foreign_key => "journal_id"

validates_presence_of :author
validates_presence_of :issue
validates_presence_of :journal

attr_protected :journal

scope :opened, lambda { where(:opened => true) }
scope :not_hidden, lambda { where(:hidden => false) }

named_scope :opened, :conditions => {:opened => true}
named_scope :for_user, lambda {|user|
{ :conditions => {:assigned_to_id => user.id }}
scope :for_user, lambda {|user|
where(:assigned_to_id => user.id)
}
named_scope :by_user, lambda {|user|
{ :conditions => {:author_id => user.id }}
scope :by_user, lambda {|user|
where(:author_id => user.id)
}

delegate :notes, :to => :journal, :allow_nil => true
Expand All @@ -29,22 +33,20 @@ def close!(closing_journal=nil)
if self.opened
self.opened = false
if self.save && closing_journal
QuestionMailer.deliver_answered_question(self, closing_journal)
QuestionMailer.answered_question(self, closing_journal).deliver
end
end
end

# TODO: refactor to named_scope
def self.count_of_open_for_user(user)
Question.count(:conditions => {:assigned_to_id => user.id, :opened => true})
Question.where(:assigned_to_id => user.id, :opened => true).count
end

# TODO: refactor to named_scope
def self.count_of_open_for_user_on_project(user, project)
Question.count(:conditions => ["#{Question.table_name}.assigned_to_id = ? AND #{Project.table_name}.id = ? AND #{Question.table_name}.opened = ?",
user.id,
project.id,
true],
:include => [:issue => [:project]])
Question.where(["(#{Question.table_name}.assigned_to_id = ?) AND #{project.project_condition(Setting.display_subprojects_issues?)} AND (#{Question.table_name}.opened = ?)",
user.id, true]).
joins(:issue => :project).preload(:project).count
end
end
91 changes: 56 additions & 35 deletions app/models/question_mailer.rb
Original file line number Diff line number Diff line change
@@ -1,69 +1,90 @@
# encoding: utf-8
class QuestionMailer < Mailer
unloadable

def asked_question(journal)
question = journal.question
subject "[Question #{question.issue.project.name} ##{question.issue.id}] #{question.issue.subject}"
recipients question.assigned_to.mail unless question.assigned_to.nil?
@from = "#{question.author.name} (Redmine) <#{Setting.mail_from}>" unless question.author.nil?

if Setting.plugin_question_plugin[:obfuscate_author] == "1"
# Obfuscate author infos
from = "#{Setting.app_title} <#{Setting.mail_from}>"
else
# Clear author infos
from = question.author ? "#{question.author.name} (#{l(:field_system_name)} - #{I18n.t(:text_question)}) <#{Setting.mail_from}>" : nil
end
to = question.assigned_to ? question.assigned_to.mail : nil
subject = "[#{question.issue.project.name} ##{question.issue.id}] #{question.issue.subject}"

@from = from
@question = question
@issue = question.issue
@journal = journal
@users = [question.assigned_to]
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => question.issue)
@users = [question.assigned_to]

redmine_headers 'Issue-Id' => question.issue.id
redmine_headers 'Question-Asked' => question.author.login if question.author.present?
redmine_headers 'Question-Assigned-To' => question.assigned_to.login if question.assigned_to.present?

body({
:question => question,
:issue => question.issue,
:journal => journal,
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => question.issue)
})

RAILS_DEFAULT_LOGGER.debug 'Sending QuestionMailer#asked_question'
render_multipart('asked_question', body)
Rails.logger.debug 'Sending QuestionMailer#asked_question'
mail(:from => from, :to => to, :subject => subject)
end

def answered_question(question, closing_journal)
subject "[Answered #{question.issue.project.name} ##{question.issue.id}] #{question.issue.subject}"
if Setting.plugin_question_plugin[:obfuscate_author] == "1"
# Obfuscate author infos
from = "#{Setting.app_title} <#{Setting.mail_from}>"
@from = from
else
# Clear author infos
from = question.assigned_to ? "#{question.assigned_to.name} (#{l(:field_system_name)} - #{I18n.t(:text_answer)}) <#{Setting.mail_from}>" : nil
@from = "#{question.assigned_to.name} (#{l(:field_system_name)} - #{I18n.t(:text_answer)}) <#{Setting.mail_from}>" unless question.assigned_to.nil?
end
to = question.author ? question.author.mail : nil
subject = "[#{question.issue.project.name} ##{question.issue.id}] #{question.issue.subject}"

@question = question
@issue = question.issue
@journal = closing_journal
@users = [question.author]
@issue_url = url_for(:controller => 'issues', :action => 'show', :id => question.issue)
@users = [question.author]

recipients question.author.mail unless question.author.nil?
@from = "#{question.assigned_to.name} (Redmine) <#{Setting.mail_from}>" unless question.assigned_to.nil?
redmine_headers 'Issue-Id' => question.issue.id
redmine_headers 'Question-Answer' => "#{question.issue.id}-#{closing_journal.id}"

body({
:question => question,
:issue => question.issue,
:journal => closing_journal,
:issue_url => url_for(:controller => 'issues', :action => 'show', :id => question.issue)
})

RAILS_DEFAULT_LOGGER.debug 'Sending QuestionMailer#answered_question'
render_multipart('answered_question', body)
Rails.logger.debug 'Sending QuestionMailer#answered_question'
mail(:from => from, :to => to, :subject => subject)
end

# Creates an email with a list of issues that have open questions
# assigned to the user
def question_reminder(user, issues)
redmine_headers 'Type' => "Question"
set_language_if_valid user.language
recipients user.mail
subject l(:question_reminder_subject, :count => issues.size)
body :issues => issues,
:issues_url => url_for(:controller => 'questions', :action => 'my_issue_filter')
render_multipart('question_reminder', body)

to = user.mail
subject = l(:question_reminder_subject, :count => issues.size)

@issues = issues
@issues_url = url_for(:controller => 'issuequestions', :action => 'my_issue_filter')

redmine_headers 'Type' => 'Question'

mail(:to => to, :subject => subject)
end

# Send email reminders to users who have open questions.
def self.question_reminders

open_questions_by_assignee = Question.opened.all(:order => 'id desc').group_by(&:assigned_to)
open_questions_by_assignee = Question.opened.order('id desc').all.group_by(&:assigned_to)

open_questions_by_assignee.each do |assignee, questions|
next unless assignee.present?
next unless assignee.present? and not assignee.locked?

issues = questions.collect {|q| q.issue.visible?(assignee) ? q.issue : nil }.compact.uniq
issues = questions.reject {|q| not q.issue.visible?(assignee) }.collect {|q| q.issue }.uniq
next if issues.count == 0

deliver_question_reminder(assignee, issues)
question_reminder(assignee, issues).deliver
end
end
end
7 changes: 7 additions & 0 deletions app/views/issuequestions/autocomplete_for_user_login.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<%= raw @users.map {|user| {
'id' => user.login,
'label' => "#{user.login}: #{user.name(:lastname_coma_firstname)}",
'value' => user.login
}
}.to_json
%>
7 changes: 7 additions & 0 deletions app/views/issuequestions/autocomplete_for_user_login.json.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<%= raw @users.map {|user| {
'id' => user.login,
'label' => "#{user.login}: #{user.name(:lastname_coma_firstname)}",
'value' => user.login
}
}.to_json
%>
18 changes: 18 additions & 0 deletions app/views/layouts/_questions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<% questions = Question.opened.not_hidden.for_user(User.current) %>
<% if questions && questions.any? %>
<div class="flash question">
<h3><%= l(:text_questions_for_me)%> (<%= h(questions.length) %>)</h3>
<ol>
<% questions.each do |question| %>
<li>
<%= link_to_issue(question.issue, :project => true, :subject => false) %>:
<%= truncate(question.notes, :length => 120) %>
<%= link_to l(:label_question_plugin_hide), hide_path(question) %>
</li>
<% end %>
</ol>
</div>
<% end %>



20 changes: 20 additions & 0 deletions app/views/question_mailer/answered_question.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<% if Setting.plugin_question_plugin[:obfuscate_content] == "1" %>
<%= textilizable(l(:mail_body_answer_link)) %>
<% else %>
<h1><%= l(:text_answer) %></h1>
<%= textilizable(@journal, :notes, :only_path => false) %>
<% end %>

<h1><%= l(:text_question_for) %> <%= @question.assigned_to %></h1>
<%= textilizable(@question.journal, :notes, :only_path => false) %>

<% if Setting.plugin_question_plugin[:obfuscate_content] == "0" %>
<ul>
<% for detail in @journal.details %>
<li><%= show_detail(detail, true) %></li>
<% end %>
</ul>

<hr />
<% end %>
<%= render :partial => "mailer/issue", :locals => { :issue => @issue, :issue_url => @issue_url, :users => @users } %>
20 changes: 20 additions & 0 deletions app/views/question_mailer/answered_question.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<% if Setting.plugin_question_plugin[:obfuscate_content] == "1" %>
<%= l(:mail_body_answer_link) %>
<% else %>
<h1><%= l(:text_answer) %></h1>
<%= textilizable(@journal, :notes, :only_path => false) %>
<% end %>

<h1><%= l(:text_question_for) %> <%= @question.assigned_to %></h1>
<%= textilizable(@question.journal, :notes, :only_path => false) %>

<% if Setting.plugin_question_plugin[:obfuscate_content] == "0" %>
<ul>
<% for detail in @journal.details %>
<li><%= show_detail(detail, true) %></li>
<% end %>
</ul>

<hr />
<% end %>
<%= render :partial => "mailer/issue", :locals => { :issue => @issue, :issue_url => @issue_url, :users => @users } %>
14 changes: 0 additions & 14 deletions app/views/question_mailer/answered_question.text.html.rhtml

This file was deleted.

14 changes: 0 additions & 14 deletions app/views/question_mailer/answered_question.text.plain.rhtml

This file was deleted.

16 changes: 16 additions & 0 deletions app/views/question_mailer/asked_question.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<h1><%= l(:mail_body_title, name: @question.assigned_to, issue: "##{@issue.id}", author: @question.author) %></h1>

<% if Setting.plugin_question_plugin[:obfuscate_content] == "1" %>
<%= textilizable(l(:mail_body_question_link)) %>
<% else %>
<%= textilizable(@journal, :notes, :only_path => false) %>

<ul>
<% for detail in @journal.details %>
<li><%= show_detail(detail, true) %></li>
<% end %>
</ul>

<hr />
<% end %>
<%= render :partial => "mailer/issue", :locals => { :issue => @issue, :issue_url => @issue_url, :users => @users } %>
14 changes: 14 additions & 0 deletions app/views/question_mailer/asked_question.text.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<%= l(:mail_body_title, name: @question.assigned_to, issue: "##{@issue.id}", author: @question.author) %>

<% if Setting.plugin_question_plugin[:obfuscate_content] == "1" %>
<%= l(:mail_body_question_link) %>
<% else %>
<%= @journal.notes if @journal.notes? %>

<% for detail in @journal.details -%>
<%= show_detail(detail, true) %>
<% end -%>

----------------------------------------
<% end %>
<%= render :partial => "mailer/issue", :locals => { :issue => @issue, :issue_url => @issue_url, :users => @users } %>
12 changes: 0 additions & 12 deletions app/views/question_mailer/asked_question.text.html.rhtml

This file was deleted.

Loading