diff --git a/app/controllers/open_source_projects_controller.rb b/app/controllers/open_source_projects_controller.rb index 41df7c409..f7f32a43b 100644 --- a/app/controllers/open_source_projects_controller.rb +++ b/app/controllers/open_source_projects_controller.rb @@ -1,4 +1,7 @@ class OpenSourceProjectsController < ApplicationController + + helper :sort + include SortHelper # GET /open_source_projects # GET /open_source_projects.json def index @@ -21,6 +24,33 @@ class OpenSourceProjectsController < ApplicationController # GET /open_source_projects/1.json def show @open_source_project = OpenSourceProject.find(params[:id]) + + sort_init 'updated_at', 'desc' + sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", + 'replies' => "#{RelativeMemo.table_name}.replies_count", + 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" + + @memo = RelativeMemo.new(:open_source_project => @open_source_project) + @topic_count = @open_source_project.topics.count + @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + @memos = @open_source_project.topics. + reorder("#{RelativeMemo.table_name}.sticky DESC"). + includes(:last_reply). + limit(@topic_pages.per_page). + offset(@topic_pages.offset). + order(sort_clause). + all + + + + # @offset, @limit = api_offset_and_limit({:limit => 10}) + # @forum = Forum.find(params[:id]) + # @memos_all = @forum.topics + # @topic_count = @memos_all.count + # @topic_pages = Paginator.new @topic_count, @limit, params['page'] + + # @offset ||= @topic_pages.offset + # @memos = @memos_all.offset(@offset).limit(@limit).all respond_to do |format| format.html { diff --git a/app/controllers/relative_memos_controller.rb b/app/controllers/relative_memos_controller.rb new file mode 100644 index 000000000..98ca8cd52 --- /dev/null +++ b/app/controllers/relative_memos_controller.rb @@ -0,0 +1,123 @@ +class RelativeMemosController < ApplicationController + + helper :sort + include SortHelper + # GET /open_source_projects + # GET /open_source_projects.json + def index + # per_page_option = 10 +# + # @open_source_projects = OpenSourceProject.all +# + # @os_project_count = @open_source_projects.count + # @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page'] +# + # @open_source_projects = OpenSourceProject.all +# + # respond_to do |format| + # format.html # index.html.erb + # format.json { render json: @open_source_projects } + # end + end + + # GET /open_source_projects/1 + # GET /open_source_projects/1.json + def show + # @open_source_project = OpenSourceProject.find(params[:id]) +# + # sort_init 'updated_at', 'desc' + # sort_update 'created_at' => "#{RelativeMemo.table_name}.created_at", + # 'replies' => "#{RelativeMemo.table_name}.replies_count", + # 'updated_at' => "COALESCE (last_replies_relative_memos.created_at, #{RelativeMemo.table_name}.created_at)" +# + # @memo = RelativeMemo.new(:open_source_project => @open_source_project) + # @topic_count = @open_source_project.topics.count + # @topic_pages = Paginator.new @topic_count, per_page_option, params['page'] + # @memos = @open_source_project.topics. + # reorder("#{RelativeMemo.table_name}.sticky DESC"). + # includes(:last_reply). + # limit(@topic_pages.per_page). + # offset(@topic_pages.offset). + # order(sort_clause). + # all + + + + # @offset, @limit = api_offset_and_limit({:limit => 10}) + # @forum = Forum.find(params[:id]) + # @memos_all = @forum.topics + # @topic_count = @memos_all.count + # @topic_pages = Paginator.new @topic_count, @limit, params['page'] + + # @offset ||= @topic_pages.offset + # @memos = @memos_all.offset(@offset).limit(@limit).all + + # respond_to do |format| + # format.html { + # render :layout => "base_opensource_p" + # } + # format.json { render json: @open_source_project } + # end + end + + + # GET /open_source_projects/new + # GET /open_source_projects/new.json + def new + @open_source_project = OpenSourceProject.new + + respond_to do |format| + format.html # new.html.erb + format.json { render json: @open_source_project } + end + end + + # GET /open_source_projects/1/edit + def edit + @open_source_project = OpenSourceProject.find(params[:id]) + end + + # POST /open_source_projects + # POST /open_source_projects.json + def create + @open_source_project = OpenSourceProject.new(params[:open_source_project]) + + respond_to do |format| + if @open_source_project.save + format.html { redirect_to @open_source_project, notice: 'Open source project was successfully created.'} + format.json { render json: @open_source_project, status: :created, location: @open_source_project } + else + format.html { render action: "new" } + format.json { render json: @open_source_project.errors, status: :unprocessable_entity } + end + end + end + + # PUT /open_source_projects/1 + # PUT /open_source_projects/1.json + def update + @open_source_project = OpenSourceProject.find(params[:id]) + + respond_to do |format| + if @open_source_project.update_attributes(params[:open_source_project]) + format.html { redirect_to @open_source_project, notice: 'Open source project was successfully updated.' } + format.json { head :no_content } + else + format.html { render action: "edit" } + format.json { render json: @open_source_project.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /open_source_projects/1 + # DELETE /open_source_projects/1.json + def destroy + @open_source_project = OpenSourceProject.find(params[:id]) + @open_source_project.destroy + + respond_to do |format| + format.html { redirect_to open_source_projects_url } + format.json { head :no_content } + end + end +end diff --git a/app/models/open_source_project.rb b/app/models/open_source_project.rb index 39ab5fc46..f6ec5a8ce 100644 --- a/app/models/open_source_project.rb +++ b/app/models/open_source_project.rb @@ -1,10 +1,25 @@ class OpenSourceProject < ActiveRecord::Base attr_accessible :String + include Redmine::SafeAttributes + has_many :topics, :class_name => 'RelativeMemo', :foreign_key => 'osp_id', :conditions => "#{RelativeMemo.table_name}.parent_id IS NULL", :order => "#{RelativeMemo.table_name}.created_at DESC", :dependent => :destroy + has_many :relative_memos, :dependent => :destroy has_many :tags, :through => :project_tags, :class_name => 'Tag' has_many :project_tags, :class_name => 'ProjectTags' acts_as_taggable def short_description(length = 255) description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description end + + def reset_counters! + self.class.reset_counters!(id) + end + + def self.reset_counters!(id) + osp_id = id.to_i + update_all("topic_count = (SELECT COUNT(*) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id} AND parent_id IS NULL)," + + " memo_count = (SELECT COUNT(*) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id} AND parent_id IS NOT NULL)," + + " last_memo_id = (SELECT MAX(id) FROM #{RelativeMemo.table_name} WHERE osp_id=#{osp_id})", + ["id = ?", osp_id]) + end end diff --git a/app/models/relative_memo.rb b/app/models/relative_memo.rb index a8b745f66..060312f86 100644 --- a/app/models/relative_memo.rb +++ b/app/models/relative_memo.rb @@ -1,3 +1,152 @@ class RelativeMemo < ActiveRecord::Base # attr_accessible :title, :body + include Redmine::SafeAttributes + belongs_to :open_source_project, :class_name => "OpenSourceProject", :foreign_key => 'osp_id' + belongs_to :author, :class_name => "User", :foreign_key => 'author_id' + + has_many :tags, :through => :project_tags, :class_name => 'Tag' + has_many :project_tags, :class_name => 'ProjectTags' + acts_as_taggable + + validates_presence_of :osp_id, :subject + #validates :content, presence: true + # validates_length_of :subject, maximum: 50 + #validates_length_of :content, maximum: 3072 + validate :cannot_reply_to_locked_topic, :on => :create + + acts_as_tree :counter_cache => :replies_count, :order => "#{RelativeMemo.table_name}.created_at ASC" + acts_as_attachable + belongs_to :last_reply, :class_name => 'RelativeMemo', :foreign_key => 'last_reply_id' + # acts_as_searchable :column => ['subject', 'content'], + # #:include => { :forum => :p} + # #:project_key => "#{Forum.table_name}.project_id" + # :date_column => "#{table_name}.created_at" + + # acts_as_event :title => Proc.new {|o| "#{o.forum.name}: #{o.subject}"}, + # :datetime => :updated_at, + # # :datetime => :created_at, + # :description => :content, + # :author => :author, + # :type => Proc.new {|o| o.parent_id.nil? ? 'Memo' : 'Reply'}, + # :url => Proc.new {|o| {:controller => 'memos', :action => 'show', :forum_id => o.forum_id}.merge(o.parent_id.nil? ? {:id => o.id} : {:id => o.parent_id, :r => o.id, :anchor => "reply-#{o.id}"})} + # acts_as_activity_provider :author_key => :author_id, + # :func => 'memos', + # :timestamp => 'created_at' + + # :find_options => {:type => 'memos'} + # acts_as_watchable + + safe_attributes "author_id", + "subject", + "content", + "osp_id", + "last_memo_id", + "lock", + "sticky", + "parent_id", + "replies_count", + "is_quote" + + after_create :add_author_as_watcher, :reset_counters! + # after_update :update_memos_forum + after_destroy :reset_counters! + # after_create :send_notification + # after_save :plusParentAndForum + # after_destroy :minusParentAndForum + + # scope :visible, lambda { |*args| + # includes(:forum => ).where() + # } + + def cannot_reply_to_locked_topic + errors.add :base, l(:label_memo_locked) if root.locked? && self != root + end + + # def update_memos_forum + # if forum_id_changed? + # Message.update_all({:board_id => board_id}, ["id = ? OR parent_id = ?", root.id, root.id ]) + # Forum.reset_counters!(forum_id_was) + # Forum.reset_counters!(forum_id) + # end + # end + + def reset_counters! + if parent && parent.id + RelativeMemo.update_all({:last_reply_id => parent.children.maximum(:id)}, {:id => parent.id}) + parent.update_attribute(:updated_at, Time.now) + end + forum.reset_counters! + end + + def sticky? + sticky == 1 + end + + def replies + RelativeMemo.where("parent_id = ?", id) + end + + def locked? + self.lock + end + + def editable_by? user + # user && user.logged? || (self.author == usr && usr.allowed_to?(:edit_own_messages, project)) + user.admin? + end + + # def destroyable_by? user + # (user && user.logged? && (Forum.find(self.forum_id).creator_id == user.id) ) || user.admin? + # #self.author == user || user.admin? + # end + + def deleted_attach_able_by? user + (user && user.logged? && (self.author == user) ) || user.admin? + end + + private + + def add_author_as_watcher + Watcher.create(:watchable => self.root, :user => author) + end + + def send_notification + if Setting.notified_events.include?('message_posted') + Mailer.message_posted(self).deliver + end + end + + # def plusParentAndForum + # @forum = Forum.find(self.forum_id) + # @forum.memo_count = @forum.memo_count.to_int + 1 + # @forum.last_memo_id = self.id + # if self.parent_id + # @parent_memo = Memo.find_by_id(self.parent_id) + # @parent_memo.last_reply_id = self + # @parent_memo.replies_count = @parent_memo.replies_count.to_int + 1 + # @parent_memo.save + # else + # @forum.topic_count = @forum.topic_count.to_int + 1 + # end + # @forum.save + # end + + # def minusParentAndForum + # @forum = Forum.find(self.forum_id) + # @forum.memo_count = @forum.memo_count.to_int - 1 + # @forum.memo_count = 0 if @forum.memo_count.to_int < 0 + # # @forum.last_memo_id = Memo.reorder('created_at ASC').find_all_by_forum_id(self.forum_id).last.id + # if self.parent_id + # @parent_memo = Memo.find_by_id(self.parent_id) + # # @parent_memo.last_reply_id = Memo.reorder('created_at ASC').find_all_by_parent_id(self.parent_id).last.id + # @parent_memo.replies_count = @parent_memo.replies_count.to_int - 1 + # @parent_memo.replies_count = 0 if @parent_memo.replies_count.to_int < 0 + # @parent_memo.save + # else + # @forum.topic_count = @forum.topic_count.to_int - 1 + # @forum.topic_count = 0 if @forum.topic_count.to_int < 0 + # end + # @forum.save + # end end + diff --git a/app/views/forums/_show_topics.html.erb b/app/views/forums/_show_topics.html.erb index 3e7d4947b..0531f9625 100644 --- a/app/views/forums/_show_topics.html.erb +++ b/app/views/forums/_show_topics.html.erb @@ -5,7 +5,7 @@ <% if memos.any? %> <% memos.each do |topic| %>
<%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) %> | +||
<%= link_to image_tag(url_to_avatar(topic.author), :class => "avatar"), user_path(topic.author) if topic.author%> |
|