File: app/controllers/projects_controller.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  class: ProjectsController#18
includes
  CustomFieldsHelper   
  ProjectsHelper   
  QueriesHelper   
  RepositoriesHelper   
  SortHelper   
inherits from
  ApplicationController   
has properties
method: index #48
method: new #66
method: create #73
method: copy #106
method: show #142
method: settings #174
method: edit #182
method: update #185
method: modules #207
method: archive #213
method: unarchive #222
method: destroy #228
method: validate_parent_id #245

Class Hierarchy

Code

   1  # Redmine - project management software
   2  # Copyright (C) 2006-2011  Jean-Philippe Lang
   3  #
   4  # This program is free software; you can redistribute it and/or
   5  # modify it under the terms of the GNU General Public License
   6  # as published by the Free Software Foundation; either version 2
   7  # of the License, or (at your option) any later version.
   8  #
   9  # This program is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  14  # You should have received a copy of the GNU General Public License
  15  # along with this program; if not, write to the Free Software
  16  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17 
  18  class ProjectsController < ApplicationController
  19    menu_item :overview
  20    menu_item :roadmap, :only => :roadmap
  21    menu_item :settings, :only => :settings
  22 
  23    before_filter :find_project, :except => [ :index, :list, :new, :create, :copy ]
  24    before_filter :authorize, :except => [ :index, :list, :new, :create, :copy, :archive, :unarchive, :destroy]
  25    before_filter :authorize_global, :only => [:new, :create]
  26    before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
  27    accept_rss_auth :index
  28    accept_api_auth :index, :show, :create, :update, :destroy
  29 
  30    after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
  31      if controller.request.post?
  32        controller.send :expire_action, :controller => 'welcome', :action => 'robots'
  33      end
  34    end
  35 
  36    helper :sort
  37    include SortHelper
  38    helper :custom_fields
  39    include CustomFieldsHelper
  40    helper :issues
  41    helper :queries
  42    include QueriesHelper
  43    helper :repositories
  44    include RepositoriesHelper
  45    include ProjectsHelper
  46 
  47    # Lists visible projects
  48    def index
  49      respond_to do |format|
  50        format.html {
  51          @projects = Project.visible.find(:all, :order => 'lft')
  52        }
  53        format.api  {
  54          @offset, @limit = api_offset_and_limit
  55          @project_count = Project.visible.count
  56          @projects = Project.visible.all(:offset => @offset, :limit => @limit, :order => 'lft')
  57        }
  58        format.atom {
  59          projects = Project.visible.find(:all, :order => 'created_on DESC',
  60                                                :limit => Setting.feeds_limit.to_i)
  61          render_feed(projects, :title => "#{Setting.app_title}: #{l(:label_project_latest)}")
  62        }
  63      end
  64    end
  65 
  66    def new
  67      @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
  68      @trackers = Tracker.all
  69      @project = Project.new
  70      @project.safe_attributes = params[:project]
  71    end
  72 
  73    def create
  74      @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
  75      @trackers = Tracker.all
  76      @project = Project.new
  77      @project.safe_attributes = params[:project]
  78 
  79      if validate_parent_id && @project.save
  80        @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
  81        # Add current user as a project member if he is not admin
  82        unless User.current.admin?
  83          r = Role.givable.find_by_id(Setting.new_project_user_role_id.to_i) || Role.givable.first
  84          m = Member.new(:user => User.current, :roles => [r])
  85          @project.members << m
  86        end
  87        respond_to do |format|
  88          format.html {
  89            flash[:notice] = l(:notice_successful_create)
  90            redirect_to(params[:continue] ?
  91              {:controller => 'projects', :action => 'new', :project => {:parent_id => @project.parent_id}.reject {|k,v| v.nil?}} :
  92              {:controller => 'projects', :action => 'settings', :id => @project}
  93            )
  94          }
  95          format.api  { render :action => 'show', :status => :created, :location => url_for(:controller => 'projects', :action => 'show', :id => @project.id) }
  96        end
  97      else
  98        respond_to do |format|
  99          format.html { render :action => 'new' }
 100          format.api  { render_validation_errors(@project) }
 101        end
 102      end
 103 
 104    end
 105 
 106    def copy
 107      @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
 108      @trackers = Tracker.all
 109      @root_projects = Project.find(:all,
 110                                    :conditions => "parent_id IS NULL AND status = #{Project::STATUS_ACTIVE}",
 111                                    :order => 'name')
 112      @source_project = Project.find(params[:id])
 113      if request.get?
 114        @project = Project.copy_from(@source_project)
 115        if @project
 116          @project.identifier = Project.next_identifier if Setting.sequential_project_identifiers?
 117        else
 118          redirect_to :controller => 'admin', :action => 'projects'
 119        end
 120      else
 121        Mailer.with_deliveries(params[:notifications] == '1') do
 122          @project = Project.new
 123          @project.safe_attributes = params[:project]
 124          if validate_parent_id && @project.copy(@source_project, :only => params[:only])
 125            @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
 126            flash[:notice] = l(:notice_successful_create)
 127            redirect_to :controller => 'projects', :action => 'settings', :id => @project
 128          elsif !@project.new_record?
 129            # Project was created
 130            # But some objects were not copied due to validation failures
 131            # (eg. issues from disabled trackers)
 132            # TODO: inform about that
 133            redirect_to :controller => 'projects', :action => 'settings', :id => @project
 134          end
 135        end
 136      end
 137    rescue ActiveRecord::RecordNotFound
 138      redirect_to :controller => 'admin', :action => 'projects'
 139    end
 140 
 141    # Show @project
 142    def show
 143      if params[:jump]
 144        # try to redirect to the requested menu item
 145        redirect_to_project_menu_item(@project, params[:jump]) && return
 146      end
 147 
 148      @users_by_role = @project.users_by_role
 149      @subprojects = @project.children.visible.all
 150      @news = @project.news.find(:all, :limit => 5, :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC")
 151      @trackers = @project.rolled_up_trackers
 152 
 153      cond = @project.project_condition(Setting.display_subprojects_issues?)
 154 
 155      @open_issues_by_tracker = Issue.visible.count(:group => :tracker,
 156                                              :include => [:project, :status, :tracker],
 157                                              :conditions => ["(#{cond}) AND #{IssueStatus.table_name}.is_closed=?", false])
 158      @total_issues_by_tracker = Issue.visible.count(:group => :tracker,
 159                                              :include => [:project, :status, :tracker],
 160                                              :conditions => cond)
 161 
 162      if User.current.allowed_to?(:view_time_entries, @project)
 163        @total_hours = TimeEntry.visible.sum(:hours, :include => :project, :conditions => cond).to_f
 164      end
 165 
 166      @key = User.current.rss_key
 167 
 168      respond_to do |format|
 169        format.html
 170        format.api
 171      end
 172    end
 173 
 174    def settings
 175      @issue_custom_fields = IssueCustomField.find(:all, :order => "#{CustomField.table_name}.position")
 176      @issue_category ||= IssueCategory.new
 177      @member ||= @project.members.new
 178      @trackers = Tracker.all
 179      @wiki ||= @project.wiki
 180    end
 181 
 182    def edit
 183    end
 184 
 185    def update
 186      @project.safe_attributes = params[:project]
 187      if validate_parent_id && @project.save
 188        @project.set_allowed_parent!(params[:project]['parent_id']) if params[:project].has_key?('parent_id')
 189        respond_to do |format|
 190          format.html {
 191            flash[:notice] = l(:notice_successful_update)
 192            redirect_to :action => 'settings', :id => @project
 193          }
 194          format.api  { head :ok }
 195        end
 196      else
 197        respond_to do |format|
 198          format.html {
 199            settings
 200            render :action => 'settings'
 201          }
 202          format.api  { render_validation_errors(@project) }
 203        end
 204      end
 205    end
 206 
 207    def modules
 208      @project.enabled_module_names = params[:enabled_module_names]
 209      flash[:notice] = l(:notice_successful_update)
 210      redirect_to :action => 'settings', :id => @project, :tab => 'modules'
 211    end
 212 
 213    def archive
 214      if request.post?
 215        unless @project.archive
 216          flash[:error] = l(:error_can_not_archive_project)
 217        end
 218      end
 219      redirect_to(url_for(:controller => 'admin', :action => 'projects', :status => params[:status]))
 220    end
 221 
 222    def unarchive
 223      @project.unarchive if request.post? && !@project.active?
 224      redirect_to(url_for(:controller => 'admin', :action => 'projects', :status => params[:status]))
 225    end
 226 
 227    # Delete @project
 228    def destroy
 229      @project_to_destroy = @project
 230      if api_request? || params[:confirm]
 231        @project_to_destroy.destroy
 232        respond_to do |format|
 233          format.html { redirect_to :controller => 'admin', :action => 'projects' }
 234          format.api  { head :ok }
 235        end
 236      end
 237      # hide project in layout
 238      @project = nil
 239    end
 240 
 241    private
 242 
 243    # Validates parent_id param according to user's permissions
 244    # TODO: move it to Project model in a validation that depends on User.current
 245    def validate_parent_id
 246      return true if User.current.admin?
 247      parent_id = params[:project] && params[:project][:parent_id]
 248      if parent_id || @project.new_record?
 249        parent = parent_id.blank? ? nil : Project.find_by_id(parent_id.to_i)
 250        unless @project.allowed_parents.include?(parent)
 251          @project.errors.add :parent_id, :invalid
 252          return false
 253        end
 254      end
 255      true
 256    end
 257  end