Merge branch 'szzh' of http://repository.trustie.net/xianbo/trustie2 into szzh
Conflicts: app/views/welcome/contest.html.erb app/views/welcome/index.html.erb public/javascripts/attachments.js
This commit is contained in:
commit
3d860af48b
268
Gemfile
268
Gemfile
|
@ -1,134 +1,134 @@
|
|||
source 'http://ruby.taobao.org'
|
||||
#source 'http://ruby.sdutlinux.org/'
|
||||
|
||||
unless RUBY_PLATFORM =~ /w32/
|
||||
# unix-like only
|
||||
gem 'iconv'
|
||||
gem 'rubyzip'
|
||||
gem 'zip-zip'
|
||||
end
|
||||
|
||||
gem 'seems_rateable', path: 'lib/seems_rateable'
|
||||
gem "rails", "3.2.13"
|
||||
gem "jquery-rails", "~> 2.0.2"
|
||||
gem "i18n", "~> 0.6.0"
|
||||
gem "coderay", "~> 1.0.6"
|
||||
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
|
||||
gem "builder", "3.0.0"
|
||||
gem 'acts-as-taggable-on', '2.4.1'
|
||||
|
||||
group :development do
|
||||
gem 'better_errors', path: 'lib/better_errors'
|
||||
gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "shoulda", "~> 3.5.0"
|
||||
gem "mocha", "~> 1.1.0"
|
||||
gem 'capybara', '~> 2.4.1'
|
||||
gem 'nokogiri', '~> 1.6.3'
|
||||
gem 'factory_girl', '~> 4.4.0'
|
||||
gem 'selenium-webdriver', '~> 2.42.0'
|
||||
|
||||
|
||||
platforms :mri, :mingw do
|
||||
group :rmagick do
|
||||
# RMagick 2 supports ruby 1.9
|
||||
# RMagick 1 would be fine for ruby 1.8 but Bundler does not support
|
||||
# different requirements for the same gem on different platforms
|
||||
gem "rmagick", ">= 2.0.0"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem "guard-rails", '~> 0.5.3'
|
||||
gem 'spork-testunit', '~> 0.0.8'
|
||||
gem 'guard-spork', '~> 1.5.1'
|
||||
gem 'guard-test', '~> 1.0.0'
|
||||
gem 'ruby-prof', '~> 0.15.1' unless RUBY_PLATFORM =~ /w32/
|
||||
gem 'pry'
|
||||
gem 'pry-nav'
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.3'
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
end
|
||||
|
||||
# Optional gem for LDAP authentication
|
||||
group :ldap do
|
||||
gem "net-ldap", "~> 0.3.1"
|
||||
end
|
||||
|
||||
|
||||
# Optional gem for OpenID authentication
|
||||
group :openid do
|
||||
gem "ruby-openid", "~> 2.1.4", :require => "openid"
|
||||
gem "rack-openid"
|
||||
end
|
||||
|
||||
# Optional gem for exporting the gantt to a PNG file, not supported with jruby
|
||||
platforms :jruby do
|
||||
# jruby-openssl is bundled with JRuby 1.7.0
|
||||
gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
|
||||
gem "activerecord-jdbc-adapter", "1.2.5"
|
||||
end
|
||||
|
||||
# Include database gems for the adapters found in the database
|
||||
# configuration file
|
||||
require 'erb'
|
||||
require 'yaml'
|
||||
database_file = File.join(File.dirname(__FILE__), "config/database.yml")
|
||||
if File.exist?(database_file)
|
||||
database_config = YAML::load(ERB.new(IO.read(database_file)).result)
|
||||
adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
|
||||
if adapters.any?
|
||||
adapters.each do |adapter|
|
||||
case adapter
|
||||
when 'mysql2'
|
||||
gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
||||
when 'mysql'
|
||||
gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
||||
when /postgresql/
|
||||
gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
||||
when /sqlite3/
|
||||
gem "sqlite3", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
||||
when /sqlserver/
|
||||
gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
||||
else
|
||||
warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
|
||||
end
|
||||
end
|
||||
else
|
||||
warn("No adapter found in config/database.yml, please configure it first")
|
||||
end
|
||||
else
|
||||
warn("Please configure your config/database.yml first")
|
||||
end
|
||||
|
||||
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
|
||||
if File.exists?(local_gemfile)
|
||||
puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
instance_eval File.read(local_gemfile)
|
||||
end
|
||||
|
||||
# Load plugins' Gemfiles
|
||||
Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file|
|
||||
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
instance_eval File.read(file)
|
||||
end
|
||||
source 'http://ruby.taobao.org'
|
||||
#source 'http://ruby.sdutlinux.org/'
|
||||
|
||||
unless RUBY_PLATFORM =~ /w32/
|
||||
# unix-like only
|
||||
gem 'iconv'
|
||||
gem 'rubyzip'
|
||||
gem 'zip-zip'
|
||||
end
|
||||
|
||||
gem 'seems_rateable', path: 'lib/seems_rateable'
|
||||
gem "rails", "3.2.13"
|
||||
gem "jquery-rails", "~> 2.0.2"
|
||||
gem "i18n", "~> 0.6.0"
|
||||
gem "coderay", "~> 1.0.6"
|
||||
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
|
||||
gem "builder", "3.0.0"
|
||||
gem 'acts-as-taggable-on', '2.4.1'
|
||||
|
||||
group :development do
|
||||
gem 'better_errors', path: 'lib/better_errors'
|
||||
gem 'rack-mini-profiler', path: 'lib/rack-mini-profiler'
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "shoulda", "~> 3.5.0"
|
||||
gem "mocha", "~> 1.1.0"
|
||||
gem 'capybara', '~> 2.4.1'
|
||||
gem 'nokogiri', '~> 1.6.3'
|
||||
gem 'factory_girl', '~> 4.4.0'
|
||||
gem 'selenium-webdriver', '~> 2.42.0'
|
||||
|
||||
|
||||
platforms :mri, :mingw do
|
||||
group :rmagick do
|
||||
# RMagick 2 supports ruby 1.9
|
||||
# RMagick 1 would be fine for ruby 1.8 but Bundler does not support
|
||||
# different requirements for the same gem on different platforms
|
||||
gem "rmagick", ">= 2.0.0"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
gem "guard-rails", '~> 0.5.3'
|
||||
gem 'spork-testunit', '~> 0.0.8'
|
||||
gem 'guard-spork', '~> 1.5.1'
|
||||
gem 'guard-test', '~> 1.0.0'
|
||||
gem 'ruby-prof', '~> 0.15.1' unless RUBY_PLATFORM =~ /w32/
|
||||
gem 'pry'
|
||||
gem 'pry-nav'
|
||||
|
||||
end
|
||||
|
||||
|
||||
# Gems used only for assets and not required
|
||||
# in production environments by default.
|
||||
group :assets do
|
||||
gem 'sass-rails', '~> 3.2.3'
|
||||
gem 'coffee-rails', '~> 3.2.1'
|
||||
|
||||
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
||||
gem 'therubyracer', :platforms => :ruby
|
||||
|
||||
gem 'uglifier', '>= 1.0.3'
|
||||
end
|
||||
|
||||
# Optional gem for LDAP authentication
|
||||
group :ldap do
|
||||
gem "net-ldap", "~> 0.3.1"
|
||||
end
|
||||
|
||||
|
||||
# Optional gem for OpenID authentication
|
||||
group :openid do
|
||||
gem "ruby-openid", "~> 2.1.4", :require => "openid"
|
||||
gem "rack-openid"
|
||||
end
|
||||
|
||||
# Optional gem for exporting the gantt to a PNG file, not supported with jruby
|
||||
platforms :jruby do
|
||||
# jruby-openssl is bundled with JRuby 1.7.0
|
||||
gem "jruby-openssl" if Object.const_defined?(:JRUBY_VERSION) && JRUBY_VERSION < '1.7.0'
|
||||
gem "activerecord-jdbc-adapter", "1.2.5"
|
||||
end
|
||||
|
||||
# Include database gems for the adapters found in the database
|
||||
# configuration file
|
||||
require 'erb'
|
||||
require 'yaml'
|
||||
database_file = File.join(File.dirname(__FILE__), "config/database.yml")
|
||||
if File.exist?(database_file)
|
||||
database_config = YAML::load(ERB.new(IO.read(database_file)).result)
|
||||
adapters = database_config.values.map {|c| c['adapter']}.compact.uniq
|
||||
if adapters.any?
|
||||
adapters.each do |adapter|
|
||||
case adapter
|
||||
when 'mysql2'
|
||||
gem "mysql2", "= 0.3.11", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
||||
when 'mysql'
|
||||
gem "mysql", "~> 2.8.1", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
||||
when /postgresql/
|
||||
gem "pg", ">= 0.11.0", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
||||
when /sqlite3/
|
||||
gem "sqlite3", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
||||
when /sqlserver/
|
||||
gem "tiny_tds", "~> 0.5.1", :platforms => [:mri, :mingw]
|
||||
gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
||||
else
|
||||
warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems")
|
||||
end
|
||||
end
|
||||
else
|
||||
warn("No adapter found in config/database.yml, please configure it first")
|
||||
end
|
||||
else
|
||||
warn("Please configure your config/database.yml first")
|
||||
end
|
||||
|
||||
local_gemfile = File.join(File.dirname(__FILE__), "Gemfile.local")
|
||||
if File.exists?(local_gemfile)
|
||||
puts "Loading Gemfile.local ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
instance_eval File.read(local_gemfile)
|
||||
end
|
||||
|
||||
# Load plugins' Gemfiles
|
||||
Dir.glob File.expand_path("../plugins/*/Gemfile", __FILE__) do |file|
|
||||
puts "Loading #{file} ..." if $DEBUG # `ruby -d` or `bundle -v`
|
||||
instance_eval File.read(file)
|
||||
end
|
||||
|
|
562
Gemfile.lock
562
Gemfile.lock
|
@ -1,281 +1,281 @@
|
|||
PATH
|
||||
remote: lib/better_errors
|
||||
specs:
|
||||
better_errors (1.1.0)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
|
||||
PATH
|
||||
remote: lib/rack-mini-profiler
|
||||
specs:
|
||||
rack-mini-profiler (0.9.1)
|
||||
rack (>= 1.1.3)
|
||||
|
||||
PATH
|
||||
remote: lib/seems_rateable
|
||||
specs:
|
||||
seems_rateable (1.0.13)
|
||||
jquery-rails
|
||||
rails
|
||||
|
||||
GEM
|
||||
remote: http://ruby.taobao.org/
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
mail (~> 2.5.3)
|
||||
actionpack (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
activesupport (3.2.13)
|
||||
i18n (= 0.6.1)
|
||||
multi_json (~> 1.0)
|
||||
acts-as-taggable-on (2.4.1)
|
||||
rails (>= 3, < 5)
|
||||
arel (3.0.3)
|
||||
builder (3.0.0)
|
||||
capybara (2.4.1)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
childprocess (0.5.3)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cocaine (0.5.4)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
coffee-script (2.3.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.7.1)
|
||||
erubis (2.7.0)
|
||||
execjs (2.2.1)
|
||||
factory_girl (4.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
fastercsv (1.5.5)
|
||||
ffi (1.9.3)
|
||||
ffi (1.9.3-x86-mingw32)
|
||||
formatador (0.2.5)
|
||||
guard (2.6.1)
|
||||
formatador (>= 0.2.4)
|
||||
listen (~> 2.7)
|
||||
lumberjack (~> 1.0)
|
||||
pry (>= 0.9.12)
|
||||
thor (>= 0.18.1)
|
||||
guard-rails (0.5.3)
|
||||
guard (~> 2.0)
|
||||
guard-spork (1.5.1)
|
||||
childprocess (>= 0.2.3)
|
||||
guard (>= 1.1)
|
||||
spork (>= 0.8.4)
|
||||
guard-test (1.0.0)
|
||||
guard (>= 1.8)
|
||||
test-unit (~> 2.2)
|
||||
hike (1.2.3)
|
||||
htmlentities (4.3.2)
|
||||
i18n (0.6.1)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.0.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.8.1)
|
||||
kaminari (0.16.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
libv8 (3.16.14.3)
|
||||
listen (2.7.9)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
lumberjack (1.0.9)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.4)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.6.0)
|
||||
mocha (1.1.0)
|
||||
metaclass (~> 0.0.1)
|
||||
multi_json (1.10.1)
|
||||
mysql2 (0.3.11-x86-mingw32)
|
||||
net-ldap (0.3.1)
|
||||
nokogiri (1.6.3)
|
||||
mini_portile (= 0.6.0)
|
||||
nokogiri (1.6.3-x86-mingw32)
|
||||
mini_portile (= 0.6.0)
|
||||
paperclip (3.5.4)
|
||||
activemodel (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
polyglot (0.3.5)
|
||||
pry (0.9.12.6)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry (0.9.12.6-x86-mingw32)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
win32console (~> 1.3)
|
||||
pry-nav (0.2.3)
|
||||
pry (~> 0.9.10)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-openid (1.4.2)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-raw-upload (1.1.1)
|
||||
multi_json
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.13)
|
||||
actionmailer (= 3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activerecord (= 3.2.13)
|
||||
activeresource (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.13)
|
||||
railties (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (10.3.2)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.5)
|
||||
ffi (>= 0.5.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
ref (1.0.5)
|
||||
rich (1.4.6)
|
||||
jquery-rails
|
||||
kaminari
|
||||
mime-types
|
||||
paperclip
|
||||
rack-raw-upload
|
||||
rails (>= 3.2.0)
|
||||
sass-rails
|
||||
rmagick (2.13.2)
|
||||
ruby-openid (2.1.8)
|
||||
rubyzip (1.1.6)
|
||||
sass (3.3.10)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
selenium-webdriver (2.42.0)
|
||||
childprocess (>= 0.5.0)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0.4)
|
||||
shoulda (3.5.0)
|
||||
shoulda-context (~> 1.0, >= 1.0.1)
|
||||
shoulda-matchers (>= 1.4.1, < 3.0)
|
||||
shoulda-context (1.2.1)
|
||||
shoulda-matchers (2.6.1)
|
||||
activesupport (>= 3.0.0)
|
||||
slop (3.5.0)
|
||||
spork (0.9.2)
|
||||
spork-testunit (0.0.8)
|
||||
spork (>= 0.6.0)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
test-unit (2.5.5)
|
||||
therubyracer (0.12.1)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
tilt (1.4.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.40)
|
||||
uglifier (2.5.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
websocket (1.0.7)
|
||||
win32console (1.3.2-x86-mingw32)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x86-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord-jdbc-adapter (= 1.2.5)
|
||||
activerecord-jdbcmysql-adapter
|
||||
acts-as-taggable-on (= 2.4.1)
|
||||
better_errors!
|
||||
builder (= 3.0.0)
|
||||
capybara (~> 2.4.1)
|
||||
coderay (~> 1.0.6)
|
||||
coffee-rails (~> 3.2.1)
|
||||
factory_girl (~> 4.4.0)
|
||||
fastercsv (~> 1.5.0)
|
||||
guard-rails (~> 0.5.3)
|
||||
guard-spork (~> 1.5.1)
|
||||
guard-test (~> 1.0.0)
|
||||
htmlentities
|
||||
i18n (~> 0.6.0)
|
||||
jquery-rails (~> 2.0.2)
|
||||
kaminari
|
||||
mocha (~> 1.1.0)
|
||||
mysql2 (= 0.3.11)
|
||||
net-ldap (~> 0.3.1)
|
||||
nokogiri (~> 1.6.3)
|
||||
paperclip (~> 3.5.4)
|
||||
pry
|
||||
pry-nav
|
||||
rack-mini-profiler!
|
||||
rack-openid
|
||||
rails (= 3.2.13)
|
||||
rich (= 1.4.6)
|
||||
rmagick (>= 2.0.0)
|
||||
ruby-openid (~> 2.1.4)
|
||||
sass-rails (~> 3.2.3)
|
||||
seems_rateable!
|
||||
selenium-webdriver (~> 2.42.0)
|
||||
shoulda (~> 3.5.0)
|
||||
spork-testunit (~> 0.0.8)
|
||||
therubyracer
|
||||
uglifier (>= 1.0.3)
|
||||
PATH
|
||||
remote: lib/better_errors
|
||||
specs:
|
||||
better_errors (1.1.0)
|
||||
coderay (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
|
||||
PATH
|
||||
remote: lib/rack-mini-profiler
|
||||
specs:
|
||||
rack-mini-profiler (0.9.1)
|
||||
rack (>= 1.1.3)
|
||||
|
||||
PATH
|
||||
remote: lib/seems_rateable
|
||||
specs:
|
||||
seems_rateable (1.0.13)
|
||||
jquery-rails
|
||||
rails
|
||||
|
||||
GEM
|
||||
remote: http://ruby.taobao.org/
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
mail (~> 2.5.3)
|
||||
actionpack (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
erubis (~> 2.7.0)
|
||||
journey (~> 1.0.4)
|
||||
rack (~> 1.4.5)
|
||||
rack-cache (~> 1.2)
|
||||
rack-test (~> 0.6.1)
|
||||
sprockets (~> 2.2.1)
|
||||
activemodel (3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
builder (~> 3.0.0)
|
||||
activerecord (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
arel (~> 3.0.2)
|
||||
tzinfo (~> 0.3.29)
|
||||
activeresource (3.2.13)
|
||||
activemodel (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
activesupport (3.2.13)
|
||||
i18n (= 0.6.1)
|
||||
multi_json (~> 1.0)
|
||||
acts-as-taggable-on (2.4.1)
|
||||
rails (>= 3, < 5)
|
||||
arel (3.0.3)
|
||||
builder (3.0.0)
|
||||
capybara (2.4.1)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
celluloid (0.15.2)
|
||||
timers (~> 1.1.0)
|
||||
childprocess (0.5.3)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
climate_control (0.0.3)
|
||||
activesupport (>= 3.0)
|
||||
cocaine (0.5.4)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.0.9)
|
||||
coffee-rails (3.2.2)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (~> 3.2.0)
|
||||
coffee-script (2.3.0)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.7.1)
|
||||
erubis (2.7.0)
|
||||
execjs (2.2.1)
|
||||
factory_girl (4.4.0)
|
||||
activesupport (>= 3.0.0)
|
||||
fastercsv (1.5.5)
|
||||
ffi (1.9.3)
|
||||
ffi (1.9.3-x86-mingw32)
|
||||
formatador (0.2.5)
|
||||
guard (2.6.1)
|
||||
formatador (>= 0.2.4)
|
||||
listen (~> 2.7)
|
||||
lumberjack (~> 1.0)
|
||||
pry (>= 0.9.12)
|
||||
thor (>= 0.18.1)
|
||||
guard-rails (0.5.3)
|
||||
guard (~> 2.0)
|
||||
guard-spork (1.5.1)
|
||||
childprocess (>= 0.2.3)
|
||||
guard (>= 1.1)
|
||||
spork (>= 0.8.4)
|
||||
guard-test (1.0.0)
|
||||
guard (>= 1.8)
|
||||
test-unit (~> 2.2)
|
||||
hike (1.2.3)
|
||||
htmlentities (4.3.2)
|
||||
i18n (0.6.1)
|
||||
journey (1.0.4)
|
||||
jquery-rails (2.0.3)
|
||||
railties (>= 3.1.0, < 5.0)
|
||||
thor (~> 0.14)
|
||||
json (1.8.1)
|
||||
kaminari (0.16.1)
|
||||
actionpack (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
libv8 (3.16.14.3)
|
||||
listen (2.7.9)
|
||||
celluloid (>= 0.15.2)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
lumberjack (1.0.9)
|
||||
mail (2.5.4)
|
||||
mime-types (~> 1.16)
|
||||
treetop (~> 1.4.8)
|
||||
metaclass (0.0.4)
|
||||
method_source (0.8.2)
|
||||
mime-types (1.25.1)
|
||||
mini_portile (0.6.0)
|
||||
mocha (1.1.0)
|
||||
metaclass (~> 0.0.1)
|
||||
multi_json (1.10.1)
|
||||
mysql2 (0.3.11-x86-mingw32)
|
||||
net-ldap (0.3.1)
|
||||
nokogiri (1.6.3)
|
||||
mini_portile (= 0.6.0)
|
||||
nokogiri (1.6.3-x86-mingw32)
|
||||
mini_portile (= 0.6.0)
|
||||
paperclip (3.5.4)
|
||||
activemodel (>= 3.0.0)
|
||||
activesupport (>= 3.0.0)
|
||||
cocaine (~> 0.5.3)
|
||||
mime-types
|
||||
polyglot (0.3.5)
|
||||
pry (0.9.12.6)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
pry (0.9.12.6-x86-mingw32)
|
||||
coderay (~> 1.0)
|
||||
method_source (~> 0.8)
|
||||
slop (~> 3.4)
|
||||
win32console (~> 1.3)
|
||||
pry-nav (0.2.3)
|
||||
pry (~> 0.9.10)
|
||||
rack (1.4.5)
|
||||
rack-cache (1.2)
|
||||
rack (>= 0.4)
|
||||
rack-openid (1.4.2)
|
||||
rack (>= 1.1.0)
|
||||
ruby-openid (>= 2.1.8)
|
||||
rack-raw-upload (1.1.1)
|
||||
multi_json
|
||||
rack-ssl (1.3.4)
|
||||
rack
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
rails (3.2.13)
|
||||
actionmailer (= 3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activerecord (= 3.2.13)
|
||||
activeresource (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.13)
|
||||
railties (3.2.13)
|
||||
actionpack (= 3.2.13)
|
||||
activesupport (= 3.2.13)
|
||||
rack-ssl (~> 1.3.2)
|
||||
rake (>= 0.8.7)
|
||||
rdoc (~> 3.4)
|
||||
thor (>= 0.14.6, < 2.0)
|
||||
rake (10.3.2)
|
||||
rb-fsevent (0.9.4)
|
||||
rb-inotify (0.9.5)
|
||||
ffi (>= 0.5.0)
|
||||
rdoc (3.12.2)
|
||||
json (~> 1.4)
|
||||
ref (1.0.5)
|
||||
rich (1.4.6)
|
||||
jquery-rails
|
||||
kaminari
|
||||
mime-types
|
||||
paperclip
|
||||
rack-raw-upload
|
||||
rails (>= 3.2.0)
|
||||
sass-rails
|
||||
rmagick (2.13.2)
|
||||
ruby-openid (2.1.8)
|
||||
rubyzip (1.1.6)
|
||||
sass (3.3.10)
|
||||
sass-rails (3.2.6)
|
||||
railties (~> 3.2.0)
|
||||
sass (>= 3.1.10)
|
||||
tilt (~> 1.3)
|
||||
selenium-webdriver (2.42.0)
|
||||
childprocess (>= 0.5.0)
|
||||
multi_json (~> 1.0)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0.4)
|
||||
shoulda (3.5.0)
|
||||
shoulda-context (~> 1.0, >= 1.0.1)
|
||||
shoulda-matchers (>= 1.4.1, < 3.0)
|
||||
shoulda-context (1.2.1)
|
||||
shoulda-matchers (2.6.1)
|
||||
activesupport (>= 3.0.0)
|
||||
slop (3.5.0)
|
||||
spork (0.9.2)
|
||||
spork-testunit (0.0.8)
|
||||
spork (>= 0.6.0)
|
||||
sprockets (2.2.2)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
tilt (~> 1.1, != 1.3.0)
|
||||
test-unit (2.5.5)
|
||||
therubyracer (0.12.1)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.1)
|
||||
tilt (1.4.1)
|
||||
timers (1.1.0)
|
||||
treetop (1.4.15)
|
||||
polyglot
|
||||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.40)
|
||||
uglifier (2.5.1)
|
||||
execjs (>= 0.3.0)
|
||||
json (>= 1.8.0)
|
||||
websocket (1.0.7)
|
||||
win32console (1.3.2-x86-mingw32)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
x86-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
activerecord-jdbc-adapter (= 1.2.5)
|
||||
activerecord-jdbcmysql-adapter
|
||||
acts-as-taggable-on (= 2.4.1)
|
||||
better_errors!
|
||||
builder (= 3.0.0)
|
||||
capybara (~> 2.4.1)
|
||||
coderay (~> 1.0.6)
|
||||
coffee-rails (~> 3.2.1)
|
||||
factory_girl (~> 4.4.0)
|
||||
fastercsv (~> 1.5.0)
|
||||
guard-rails (~> 0.5.3)
|
||||
guard-spork (~> 1.5.1)
|
||||
guard-test (~> 1.0.0)
|
||||
htmlentities
|
||||
i18n (~> 0.6.0)
|
||||
jquery-rails (~> 2.0.2)
|
||||
kaminari
|
||||
mocha (~> 1.1.0)
|
||||
mysql2 (= 0.3.11)
|
||||
net-ldap (~> 0.3.1)
|
||||
nokogiri (~> 1.6.3)
|
||||
paperclip (~> 3.5.4)
|
||||
pry
|
||||
pry-nav
|
||||
rack-mini-profiler!
|
||||
rack-openid
|
||||
rails (= 3.2.13)
|
||||
rich (= 1.4.6)
|
||||
rmagick (>= 2.0.0)
|
||||
ruby-openid (~> 2.1.4)
|
||||
sass-rails (~> 3.2.3)
|
||||
seems_rateable!
|
||||
selenium-webdriver (~> 2.42.0)
|
||||
shoulda (~> 3.5.0)
|
||||
spork-testunit (~> 0.0.8)
|
||||
therubyracer
|
||||
uglifier (>= 1.0.3)
|
||||
|
|
|
@ -1,407 +1,407 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AccountController < ApplicationController
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
|
||||
# prevents login action to be filtered by check_if_login_required application scope filter
|
||||
skip_before_filter :check_if_login_required
|
||||
|
||||
# Login request and validation
|
||||
def login
|
||||
if request.get?
|
||||
if User.current.logged?
|
||||
redirect_to home_url
|
||||
end
|
||||
else
|
||||
authenticate_user
|
||||
end
|
||||
rescue AuthSourceException => e
|
||||
logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
|
||||
render_error :message => e.message
|
||||
end
|
||||
|
||||
# Log out current user and redirect to welcome page
|
||||
def logout
|
||||
if User.current.anonymous?
|
||||
redirect_to home_url
|
||||
elsif request.post?
|
||||
logout_user
|
||||
redirect_to home_url
|
||||
end
|
||||
# display the logout form
|
||||
end
|
||||
|
||||
# Lets user choose a new password
|
||||
def lost_password
|
||||
(redirect_to(home_url); return) unless Setting.lost_password?
|
||||
if params[:token]
|
||||
@token = Token.find_token("recovery", params[:token].to_s)
|
||||
if @token.nil? || @token.expired?
|
||||
redirect_to home_url
|
||||
return
|
||||
end
|
||||
@user = @token.user
|
||||
unless @user && @user.active?
|
||||
redirect_to home_url
|
||||
return
|
||||
end
|
||||
if request.post?
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if @user.save
|
||||
@token.destroy
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
redirect_to signin_url
|
||||
return
|
||||
end
|
||||
end
|
||||
render :template => "account/password_recovery"
|
||||
return
|
||||
else
|
||||
if request.post?
|
||||
user = User.find_by_mail(params[:mail].to_s)
|
||||
# user not found or not active
|
||||
unless user && user.active?
|
||||
flash.now[:error] = l(:notice_account_unknown_email)
|
||||
return
|
||||
end
|
||||
# user cannot change its password
|
||||
unless user.change_password_allowed?
|
||||
flash.now[:error] = l(:notice_can_t_change_password)
|
||||
return
|
||||
end
|
||||
# create a new token for password recovery
|
||||
token = Token.new(:user => user, :action => "recovery")
|
||||
if token.save
|
||||
Thread.new do
|
||||
Mailer.lost_password(token).deliver
|
||||
end
|
||||
flash[:notice] = l(:notice_account_lost_email_sent)
|
||||
redirect_to signin_url
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# User self-registration
|
||||
def register
|
||||
# @root_path="/home/pdl/redmine-2.3.2-0/apache2/"
|
||||
#
|
||||
@cache_identityy = params[:identity]||"" #身份
|
||||
@cache_no = params[:no]||"" #学号
|
||||
@cache_technical_title = params[:technical_title]||"" #教师职称
|
||||
@cache_province = params[:province]||"" #省份
|
||||
@cache_city = params[:city]||"" #城市
|
||||
@cache_enterprise_name = params[:enterprise_name]||"" #企业
|
||||
|
||||
firstname_code = ""
|
||||
lastname_code = ""
|
||||
(redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
|
||||
if request.get?
|
||||
session[:auth_source_registration] = nil
|
||||
@user = User.new(:language => current_language.to_s)
|
||||
else
|
||||
user_params = params[:user] || {}
|
||||
@user = User.new
|
||||
@user.safe_attributes = user_params
|
||||
if params[:identity] == "2" # 2 企业
|
||||
firstname_code = @user.firstname
|
||||
lastname_code = @user.lastname
|
||||
@user.firstname = params[:enterprise_name]
|
||||
@user.lastname = l(:field_enterprise)
|
||||
end
|
||||
@user.admin = false
|
||||
@user.register
|
||||
if session[:auth_source_registration]
|
||||
@user.activate
|
||||
@user.login = session[:auth_source_registration][:login]
|
||||
@user.auth_source_id = session[:auth_source_registration][:auth_source_id]
|
||||
if @user.save
|
||||
session[:auth_source_registration] = nil
|
||||
self.logged_user = @user
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
redirect_to my_account_url
|
||||
end
|
||||
else
|
||||
@user.login = params[:user][:login]
|
||||
unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
|
||||
@user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
|
||||
end
|
||||
|
||||
if(@cache_identityy == "")
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
flash.now[:error]= l(:label_identity)+l(:'activerecord.errors.messages.empty')
|
||||
return
|
||||
end
|
||||
if(@cache_city == "")
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
flash.now[:error]= l(:label_location)+l(:'activerecord.errors.messages.empty')
|
||||
return
|
||||
end
|
||||
|
||||
case Setting.self_registration
|
||||
when '1'
|
||||
register_by_email_activation(@user)
|
||||
when '3'
|
||||
register_automatically(@user)
|
||||
else
|
||||
register_manually_by_administrator(@user)
|
||||
end
|
||||
|
||||
#added by bai
|
||||
if @user.id != nil
|
||||
ue = @user.user_extensions ||= UserExtensions.new
|
||||
#ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => )
|
||||
ue.identity = params[:identity].to_i
|
||||
ue.technical_title = params[:technical_title]
|
||||
ue.gender = params[:gender].to_i
|
||||
ue.user_id = @user.id
|
||||
ue.student_id = params[:no]
|
||||
ue.location = params[:province] if params[:province] != nil
|
||||
ue.location_city = params[:city] if params[:city] != nil
|
||||
ue.save
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
end
|
||||
|
||||
# Token based account activation
|
||||
def activate
|
||||
(redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
|
||||
token = Token.find_token('register', params[:token].to_s)
|
||||
(redirect_to(home_url); return) unless token and !token.expired?
|
||||
user = token.user
|
||||
(redirect_to(home_url); return) unless user.registered?
|
||||
user.activate
|
||||
if user.save
|
||||
token.destroy
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
end
|
||||
redirect_to signin_url
|
||||
end
|
||||
|
||||
def valid_ajax
|
||||
req = Hash.new(false)
|
||||
req[:message] = ''
|
||||
|
||||
valid_attr = params[:valid]
|
||||
valid_value = params[:value]
|
||||
|
||||
faker = User.new
|
||||
|
||||
if valid_attr.eql?('login')
|
||||
faker.login = valid_value
|
||||
faker.valid?
|
||||
req[:valid] = faker.errors[:login].blank?
|
||||
req[:message] = faker.errors[:login]
|
||||
end
|
||||
|
||||
if valid_attr.eql?('mail')
|
||||
faker.mail = valid_value
|
||||
faker.valid?
|
||||
req[:valid] = faker.errors[:mail].blank?
|
||||
req[:message] = faker.errors[:mail]
|
||||
end
|
||||
|
||||
req[:message] = l(:modal_valid_passing) if req[:message].blank?
|
||||
render :json => req
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_user
|
||||
if Setting.openid? && using_open_id?
|
||||
open_id_authenticate(params[:openid_url])
|
||||
else
|
||||
password_authentication
|
||||
end
|
||||
end
|
||||
|
||||
def password_authentication
|
||||
user = User.try_to_login(params[:username], params[:password])
|
||||
|
||||
if user.nil?
|
||||
invalid_credentials
|
||||
elsif user.status == 2
|
||||
invalid_credentials_new
|
||||
elsif user.new_record?
|
||||
onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
|
||||
else
|
||||
# Valid user
|
||||
successful_authentication(user)
|
||||
end
|
||||
end
|
||||
|
||||
def open_id_authenticate(openid_url)
|
||||
back_url = signin_url(:autologin => params[:autologin])
|
||||
|
||||
authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration|
|
||||
if result.successful?
|
||||
user = User.find_or_initialize_by_identity_url(identity_url)
|
||||
if user.new_record?
|
||||
# Self-registration off
|
||||
(redirect_to(home_url); return) unless Setting.self_registration?
|
||||
|
||||
# Create on the fly
|
||||
user.login = registration['nickname'] unless registration['nickname'].nil?
|
||||
user.mail = registration['email'] unless registration['email'].nil?
|
||||
user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
|
||||
user.random_password
|
||||
user.register
|
||||
|
||||
case Setting.self_registration
|
||||
when '1'
|
||||
register_by_email_activation(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
when '3'
|
||||
register_automatically(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
else
|
||||
register_manually_by_administrator(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
end
|
||||
else
|
||||
# Existing record
|
||||
if user.active?
|
||||
successful_authentication(user)
|
||||
else
|
||||
account_pending
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
# generate a key and set cookie if autologin
|
||||
if params[:autologin] && Setting.autologin?
|
||||
set_autologin_cookie(user)
|
||||
end
|
||||
call_hook(:controller_account_success_authentication_after, {:user => user })
|
||||
|
||||
code = /\d*/
|
||||
#根据home_url生产正则表达式
|
||||
eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/")
|
||||
if code=~params[:back_url]
|
||||
redirect_to user_activities_path(user)
|
||||
else
|
||||
#by young
|
||||
#redirect_back_or_default my_page_path
|
||||
redirect_back_or_default User.current
|
||||
#redirect_to User.current
|
||||
end
|
||||
end
|
||||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.create(:user => user, :action => 'autologin')
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
:expires => 1.year.from_now,
|
||||
:path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
|
||||
:secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
|
||||
:httponly => true
|
||||
}
|
||||
cookies[autologin_cookie_name] = cookie_options
|
||||
end
|
||||
|
||||
# Onthefly creation failed, display the registration form to fill/fix attributes
|
||||
def onthefly_creation_failed(user, auth_source_options = { })
|
||||
@user = user
|
||||
session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
|
||||
render :action => 'register'
|
||||
end
|
||||
|
||||
def invalid_credentials
|
||||
logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
flash.now[:error] = l(:notice_account_invalid_creditentials)
|
||||
end
|
||||
|
||||
def invalid_credentials_new
|
||||
logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
flash.now[:error] = l(:notice_account_invalid_creditentials_new)
|
||||
end
|
||||
|
||||
# Register a user for email activation.
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_by_email_activation(user, &block)
|
||||
token = Token.new(:user => user, :action => "register")
|
||||
if user.save and token.save
|
||||
UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
|
||||
Mailer.register(token).deliver
|
||||
flash[:notice] = l(:notice_account_register_done)
|
||||
redirect_to signin_url
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
# Automatically register a user
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_automatically(user, &block)
|
||||
# Automatic activation
|
||||
user.activate
|
||||
user.last_login_on = Time.now
|
||||
if user.save
|
||||
UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
|
||||
self.logged_user = user
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
redirect_to my_account_url
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
# Manual activation by the administrator
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_manually_by_administrator(user, &block)
|
||||
if user.save
|
||||
UserStatus.create(:user_id => user.id ,:changsets_count => 0, :watchers_count => 0)
|
||||
# Sends an email to the administrators
|
||||
Mailer.account_activation_request(user).deliver
|
||||
account_pending
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
def account_pending
|
||||
flash[:notice] = l(:notice_account_pending)
|
||||
redirect_to signin_url
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AccountController < ApplicationController
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
|
||||
# prevents login action to be filtered by check_if_login_required application scope filter
|
||||
skip_before_filter :check_if_login_required
|
||||
|
||||
# Login request and validation
|
||||
def login
|
||||
if request.get?
|
||||
if User.current.logged?
|
||||
redirect_to home_url
|
||||
end
|
||||
else
|
||||
authenticate_user
|
||||
end
|
||||
rescue AuthSourceException => e
|
||||
logger.error "An error occured when authenticating #{params[:username]}: #{e.message}"
|
||||
render_error :message => e.message
|
||||
end
|
||||
|
||||
# Log out current user and redirect to welcome page
|
||||
def logout
|
||||
if User.current.anonymous?
|
||||
redirect_to home_url
|
||||
elsif request.post?
|
||||
logout_user
|
||||
redirect_to home_url
|
||||
end
|
||||
# display the logout form
|
||||
end
|
||||
|
||||
# Lets user choose a new password
|
||||
def lost_password
|
||||
(redirect_to(home_url); return) unless Setting.lost_password?
|
||||
if params[:token]
|
||||
@token = Token.find_token("recovery", params[:token].to_s)
|
||||
if @token.nil? || @token.expired?
|
||||
redirect_to home_url
|
||||
return
|
||||
end
|
||||
@user = @token.user
|
||||
unless @user && @user.active?
|
||||
redirect_to home_url
|
||||
return
|
||||
end
|
||||
if request.post?
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
if @user.save
|
||||
@token.destroy
|
||||
flash[:notice] = l(:notice_account_password_updated)
|
||||
redirect_to signin_url
|
||||
return
|
||||
end
|
||||
end
|
||||
render :template => "account/password_recovery"
|
||||
return
|
||||
else
|
||||
if request.post?
|
||||
user = User.find_by_mail(params[:mail].to_s)
|
||||
# user not found or not active
|
||||
unless user && user.active?
|
||||
flash.now[:error] = l(:notice_account_unknown_email)
|
||||
return
|
||||
end
|
||||
# user cannot change its password
|
||||
unless user.change_password_allowed?
|
||||
flash.now[:error] = l(:notice_can_t_change_password)
|
||||
return
|
||||
end
|
||||
# create a new token for password recovery
|
||||
token = Token.new(:user => user, :action => "recovery")
|
||||
if token.save
|
||||
Thread.new do
|
||||
Mailer.lost_password(token).deliver
|
||||
end
|
||||
flash[:notice] = l(:notice_account_lost_email_sent)
|
||||
redirect_to signin_url
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# User self-registration
|
||||
def register
|
||||
# @root_path="/home/pdl/redmine-2.3.2-0/apache2/"
|
||||
#
|
||||
@cache_identityy = params[:identity]||"" #身份
|
||||
@cache_no = params[:no]||"" #学号
|
||||
@cache_technical_title = params[:technical_title]||"" #教师职称
|
||||
@cache_province = params[:province]||"" #省份
|
||||
@cache_city = params[:city]||"" #城市
|
||||
@cache_enterprise_name = params[:enterprise_name]||"" #企业
|
||||
|
||||
firstname_code = ""
|
||||
lastname_code = ""
|
||||
(redirect_to(home_url); return) unless Setting.self_registration? || session[:auth_source_registration]
|
||||
if request.get?
|
||||
session[:auth_source_registration] = nil
|
||||
@user = User.new(:language => current_language.to_s)
|
||||
else
|
||||
user_params = params[:user] || {}
|
||||
@user = User.new
|
||||
@user.safe_attributes = user_params
|
||||
if params[:identity] == "2" # 2 企业
|
||||
firstname_code = @user.firstname
|
||||
lastname_code = @user.lastname
|
||||
@user.firstname = params[:enterprise_name]
|
||||
@user.lastname = l(:field_enterprise)
|
||||
end
|
||||
@user.admin = false
|
||||
@user.register
|
||||
if session[:auth_source_registration]
|
||||
@user.activate
|
||||
@user.login = session[:auth_source_registration][:login]
|
||||
@user.auth_source_id = session[:auth_source_registration][:auth_source_id]
|
||||
if @user.save
|
||||
session[:auth_source_registration] = nil
|
||||
self.logged_user = @user
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
redirect_to my_account_url
|
||||
end
|
||||
else
|
||||
@user.login = params[:user][:login]
|
||||
unless user_params[:identity_url].present? && user_params[:password].blank? && user_params[:password_confirmation].blank?
|
||||
@user.password, @user.password_confirmation = user_params[:password], user_params[:password_confirmation]
|
||||
end
|
||||
|
||||
if(@cache_identityy == "")
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
flash.now[:error]= l(:label_identity)+l(:'activerecord.errors.messages.empty')
|
||||
return
|
||||
end
|
||||
if(@cache_city == "")
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
flash.now[:error]= l(:label_location)+l(:'activerecord.errors.messages.empty')
|
||||
return
|
||||
end
|
||||
|
||||
case Setting.self_registration
|
||||
when '1'
|
||||
register_by_email_activation(@user)
|
||||
when '3'
|
||||
register_automatically(@user)
|
||||
else
|
||||
register_manually_by_administrator(@user)
|
||||
end
|
||||
|
||||
#added by bai
|
||||
if @user.id != nil
|
||||
ue = @user.user_extensions ||= UserExtensions.new
|
||||
#ue = UserExtensions.create(:identity => params[:identity].to_i,:technical_title => params[:technical_title], :gender => params[:gender].to_i, :user_id => @user.id, :student_id => )
|
||||
ue.identity = params[:identity].to_i
|
||||
ue.technical_title = params[:technical_title]
|
||||
ue.gender = params[:gender].to_i
|
||||
ue.user_id = @user.id
|
||||
ue.student_id = params[:no]
|
||||
ue.location = params[:province] if params[:province] != nil
|
||||
ue.location_city = params[:city] if params[:city] != nil
|
||||
ue.save
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
if params[:identity] == "2"
|
||||
@user.firstname = firstname_code
|
||||
@user.lastname = lastname_code
|
||||
end
|
||||
end
|
||||
|
||||
# Token based account activation
|
||||
def activate
|
||||
(redirect_to(home_url); return) unless Setting.self_registration? && params[:token].present?
|
||||
token = Token.find_token('register', params[:token].to_s)
|
||||
(redirect_to(home_url); return) unless token and !token.expired?
|
||||
user = token.user
|
||||
(redirect_to(home_url); return) unless user.registered?
|
||||
user.activate
|
||||
if user.save
|
||||
token.destroy
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
end
|
||||
redirect_to signin_url
|
||||
end
|
||||
|
||||
def valid_ajax
|
||||
req = Hash.new(false)
|
||||
req[:message] = ''
|
||||
|
||||
valid_attr = params[:valid]
|
||||
valid_value = params[:value]
|
||||
|
||||
faker = User.new
|
||||
|
||||
if valid_attr.eql?('login')
|
||||
faker.login = valid_value
|
||||
faker.valid?
|
||||
req[:valid] = faker.errors[:login].blank?
|
||||
req[:message] = faker.errors[:login]
|
||||
end
|
||||
|
||||
if valid_attr.eql?('mail')
|
||||
faker.mail = valid_value
|
||||
faker.valid?
|
||||
req[:valid] = faker.errors[:mail].blank?
|
||||
req[:message] = faker.errors[:mail]
|
||||
end
|
||||
|
||||
req[:message] = l(:modal_valid_passing) if req[:message].blank?
|
||||
render :json => req
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def authenticate_user
|
||||
if Setting.openid? && using_open_id?
|
||||
open_id_authenticate(params[:openid_url])
|
||||
else
|
||||
password_authentication
|
||||
end
|
||||
end
|
||||
|
||||
def password_authentication
|
||||
user = User.try_to_login(params[:username], params[:password])
|
||||
|
||||
if user.nil?
|
||||
invalid_credentials
|
||||
elsif user.status == 2
|
||||
invalid_credentials_new
|
||||
elsif user.new_record?
|
||||
onthefly_creation_failed(user, {:login => user.login, :auth_source_id => user.auth_source_id })
|
||||
else
|
||||
# Valid user
|
||||
successful_authentication(user)
|
||||
end
|
||||
end
|
||||
|
||||
def open_id_authenticate(openid_url)
|
||||
back_url = signin_url(:autologin => params[:autologin])
|
||||
|
||||
authenticate_with_open_id(openid_url, :required => [:nickname, :fullname, :email], :return_to => back_url, :method => :post) do |result, identity_url, registration|
|
||||
if result.successful?
|
||||
user = User.find_or_initialize_by_identity_url(identity_url)
|
||||
if user.new_record?
|
||||
# Self-registration off
|
||||
(redirect_to(home_url); return) unless Setting.self_registration?
|
||||
|
||||
# Create on the fly
|
||||
user.login = registration['nickname'] unless registration['nickname'].nil?
|
||||
user.mail = registration['email'] unless registration['email'].nil?
|
||||
user.firstname, user.lastname = registration['fullname'].split(' ') unless registration['fullname'].nil?
|
||||
user.random_password
|
||||
user.register
|
||||
|
||||
case Setting.self_registration
|
||||
when '1'
|
||||
register_by_email_activation(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
when '3'
|
||||
register_automatically(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
else
|
||||
register_manually_by_administrator(user) do
|
||||
onthefly_creation_failed(user)
|
||||
end
|
||||
end
|
||||
else
|
||||
# Existing record
|
||||
if user.active?
|
||||
successful_authentication(user)
|
||||
else
|
||||
account_pending
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def successful_authentication(user)
|
||||
logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
# Valid user
|
||||
self.logged_user = user
|
||||
# generate a key and set cookie if autologin
|
||||
if params[:autologin] && Setting.autologin?
|
||||
set_autologin_cookie(user)
|
||||
end
|
||||
call_hook(:controller_account_success_authentication_after, {:user => user })
|
||||
|
||||
code = /\d*/
|
||||
#根据home_url生产正则表达式
|
||||
eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/")
|
||||
if code=~params[:back_url]
|
||||
redirect_to user_activities_path(user)
|
||||
else
|
||||
#by young
|
||||
#redirect_back_or_default my_page_path
|
||||
redirect_back_or_default User.current
|
||||
#redirect_to User.current
|
||||
end
|
||||
end
|
||||
|
||||
def set_autologin_cookie(user)
|
||||
token = Token.create(:user => user, :action => 'autologin')
|
||||
cookie_options = {
|
||||
:value => token.value,
|
||||
:expires => 1.year.from_now,
|
||||
:path => (Redmine::Configuration['autologin_cookie_path'] || '/'),
|
||||
:secure => (Redmine::Configuration['autologin_cookie_secure'] ? true : false),
|
||||
:httponly => true
|
||||
}
|
||||
cookies[autologin_cookie_name] = cookie_options
|
||||
end
|
||||
|
||||
# Onthefly creation failed, display the registration form to fill/fix attributes
|
||||
def onthefly_creation_failed(user, auth_source_options = { })
|
||||
@user = user
|
||||
session[:auth_source_registration] = auth_source_options unless auth_source_options.empty?
|
||||
render :action => 'register'
|
||||
end
|
||||
|
||||
def invalid_credentials
|
||||
logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
flash.now[:error] = l(:notice_account_invalid_creditentials)
|
||||
end
|
||||
|
||||
def invalid_credentials_new
|
||||
logger.warn "Failed login for '#{params[:username]}' from #{request.remote_ip} at #{Time.now.utc}"
|
||||
flash.now[:error] = l(:notice_account_invalid_creditentials_new)
|
||||
end
|
||||
|
||||
# Register a user for email activation.
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_by_email_activation(user, &block)
|
||||
token = Token.new(:user => user, :action => "register")
|
||||
if user.save and token.save
|
||||
UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
|
||||
Mailer.register(token).deliver
|
||||
flash[:notice] = l(:notice_account_register_done)
|
||||
redirect_to signin_url
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
# Automatically register a user
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_automatically(user, &block)
|
||||
# Automatic activation
|
||||
user.activate
|
||||
user.last_login_on = Time.now
|
||||
if user.save
|
||||
UserStatus.create(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
|
||||
self.logged_user = user
|
||||
flash[:notice] = l(:notice_account_activated)
|
||||
redirect_to my_account_url
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
# Manual activation by the administrator
|
||||
#
|
||||
# Pass a block for behavior when a user fails to save
|
||||
def register_manually_by_administrator(user, &block)
|
||||
if user.save
|
||||
UserStatus.create(:user_id => user.id ,:changsets_count => 0, :watchers_count => 0)
|
||||
# Sends an email to the administrators
|
||||
Mailer.account_activation_request(user).deliver
|
||||
account_pending
|
||||
else
|
||||
yield if block_given?
|
||||
end
|
||||
end
|
||||
|
||||
def account_pending
|
||||
flash[:notice] = l(:notice_account_pending)
|
||||
redirect_to signin_url
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,286 +1,286 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AdminController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :projects, :only => :projects
|
||||
menu_item :plugins, :only => :plugins
|
||||
menu_item :info, :only => :info
|
||||
|
||||
before_filter :require_admin
|
||||
helper :sort
|
||||
helper :Users
|
||||
helper :Settings
|
||||
include SortHelper
|
||||
|
||||
def index
|
||||
@no_configuration_data = Redmine::DefaultData::Loader::no_data?
|
||||
end
|
||||
|
||||
def projects
|
||||
@status = params[:status] || 1
|
||||
|
||||
scope = Project.status(@status).order('lft')
|
||||
scope = scope.like(params[:name]) if params[:name].present?
|
||||
@projects = scope.where(project_type: Project::ProjectType_project).all
|
||||
|
||||
render :action => "projects", :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def users
|
||||
sort_init 'login', 'asc'
|
||||
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 15})
|
||||
else
|
||||
@limit = 15#per_page_option
|
||||
end
|
||||
|
||||
@status = params[:status] || 1
|
||||
scope = User.logged.status(@status)
|
||||
scope = User.like(params[:name]) if params[:name].present?
|
||||
scope = scope.in_group(params[:group_id]) if params[:group_id].present?
|
||||
|
||||
@user_count = scope.count
|
||||
@user_pages = Paginator.new @user_count, @limit, params['page']
|
||||
@offset ||= @user_pages.offset
|
||||
@users = scope.order(sort_clause).limit(@limit).offset(@offset).all
|
||||
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@groups = Group.all.sort
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def plugins
|
||||
@plugins = Redmine::Plugin.all
|
||||
end
|
||||
|
||||
# Loads the default configuration
|
||||
# (roles, trackers, statuses, workflow, enumerations)
|
||||
def default_configuration
|
||||
if request.post?
|
||||
begin
|
||||
Redmine::DefaultData::Loader::load(params[:lang])
|
||||
flash[:notice] = l(:notice_default_data_loaded)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:error_can_t_load_default_data, e.message)
|
||||
end
|
||||
end
|
||||
redirect_to admin_url
|
||||
end
|
||||
|
||||
def test_email
|
||||
raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
|
||||
# Force ActionMailer to raise delivery errors so we can catch it
|
||||
ActionMailer::Base.raise_delivery_errors = true
|
||||
begin
|
||||
@test = Mailer.test_email(User.current).deliver
|
||||
flash[:notice] = l(:notice_email_sent, User.current.mail)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:notice_email_error, e.message)
|
||||
end
|
||||
ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
|
||||
redirect_to settings_url(:tab => 'notifications')
|
||||
end
|
||||
|
||||
def info
|
||||
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||
@checklist = [
|
||||
[:text_default_administrator_account_changed, User.default_admin_account_changed?],
|
||||
[:text_file_repository_writable, File.writable?(Attachment.storage_path)],
|
||||
[:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
|
||||
[:text_rmagick_available, Object.const_defined?(:Magick)]
|
||||
]
|
||||
end
|
||||
#管理功能用户列表的搜索
|
||||
def search
|
||||
sort_init 'login', 'asc'
|
||||
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 15})
|
||||
else
|
||||
@limit = 15#per_page_option
|
||||
end
|
||||
|
||||
@status = params[:status] || 1
|
||||
scope = User.logged.status(@status)
|
||||
scope = scope.like(params[:name]) if params[:name].present?
|
||||
@user_count = scope.count
|
||||
@user_pages = Paginator.new @user_count, @limit, params['page']
|
||||
@user_base_tag = params[:id] ? 'base_users':'base'
|
||||
|
||||
@users = scope.offset(@user_pages.offset).limit(@user_pages.per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@groups = Group.all.sort
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
#首页定制
|
||||
def first_page_made
|
||||
if request.get?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@first_page.description = params[:first_page][:description]
|
||||
#@first_page.title = params[:title]
|
||||
@first_page.image_width = params[:image_width]
|
||||
@first_page.image_height = params[:image_height]
|
||||
@first_page.sort_type = params[:sort_type]
|
||||
@first_page.show_course = params[:show_course]
|
||||
@first_page.show_contest = params[:show_contest]
|
||||
if @first_page.save
|
||||
respond_to do |format|
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
format.html {
|
||||
redirect_to first_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
#format.json { render json: @first_page, status: :created, location: @first_page }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}"
|
||||
format.html {
|
||||
render :action => 'first_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
#format.json { render json: @first_page.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def course_page_made
|
||||
if request.get?
|
||||
@course_page = FirstPage.find_by_page_type('course')
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@course_page = FirstPage.find_by_page_type('course')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@course_page.web_title = params[:web_title]
|
||||
@course_page.title = params[:course_title]
|
||||
@course_page.image_width = params[:image_width]
|
||||
@course_page.image_height = params[:image_height]
|
||||
@course_page.description = params[:course_description]
|
||||
if @first_page.save && @course_page.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to course_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@course_page.errors.full_messages[0]}"
|
||||
#flash.now[:error] = "#{l :label_first_page_create_fail}: #{@course_page.errors.full_messages[0]}"
|
||||
format.html {
|
||||
|
||||
render :action => 'course_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@course_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def contest_page_made
|
||||
if request.get?
|
||||
@contest_page = FirstPage.find_by_page_type('contest')
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@contest_page = FirstPage.find_by_page_type('contest')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@contest_page.web_title = params[:web_title]
|
||||
@contest_page.title = params[:contest_title]
|
||||
@contest_page.image_width = params[:image_width]
|
||||
@contest_page.image_height = params[:image_height]
|
||||
@contest_page.description = params[:contest_description]
|
||||
|
||||
if @first_page.save && @contest_page.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to contest_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@contest_page.errors.full_messages[0]}\n\t#{@notification.errors.full_messages[0]}"
|
||||
format.html {
|
||||
render :action => 'contest_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@contest_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def web_footer_made
|
||||
if request.get?
|
||||
@organizer = WebFooterOranizer.first
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
#@notification = ContestNotification.all.first;
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@organizer = WebFooterOranizer.first
|
||||
if @organizer.nil?
|
||||
@organizer = WebFooterOranizer.new
|
||||
end
|
||||
@organizer.name = params[:organizer_name]
|
||||
@organizer.description = params[:web_footer_oranizer][:description]
|
||||
if @first_page.save && @organizer.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to web_footer_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@organizer.errors.full_messages[0]}}"
|
||||
format.html {
|
||||
render :action => 'web_footer_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@contest_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AdminController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :projects, :only => :projects
|
||||
menu_item :plugins, :only => :plugins
|
||||
menu_item :info, :only => :info
|
||||
|
||||
before_filter :require_admin
|
||||
helper :sort
|
||||
helper :Users
|
||||
helper :Settings
|
||||
include SortHelper
|
||||
|
||||
def index
|
||||
@no_configuration_data = Redmine::DefaultData::Loader::no_data?
|
||||
end
|
||||
|
||||
def projects
|
||||
@status = params[:status] || 1
|
||||
|
||||
scope = Project.status(@status).order('lft')
|
||||
scope = scope.like(params[:name]) if params[:name].present?
|
||||
@projects = scope.where(project_type: Project::ProjectType_project).all
|
||||
|
||||
render :action => "projects", :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def users
|
||||
sort_init 'login', 'asc'
|
||||
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 15})
|
||||
else
|
||||
@limit = 15#per_page_option
|
||||
end
|
||||
|
||||
@status = params[:status] || 1
|
||||
scope = User.logged.status(@status)
|
||||
scope = User.like(params[:name]) if params[:name].present?
|
||||
scope = scope.in_group(params[:group_id]) if params[:group_id].present?
|
||||
|
||||
@user_count = scope.count
|
||||
@user_pages = Paginator.new @user_count, @limit, params['page']
|
||||
@offset ||= @user_pages.offset
|
||||
@users = scope.order(sort_clause).limit(@limit).offset(@offset).all
|
||||
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@groups = Group.all.sort
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def plugins
|
||||
@plugins = Redmine::Plugin.all
|
||||
end
|
||||
|
||||
# Loads the default configuration
|
||||
# (roles, trackers, statuses, workflow, enumerations)
|
||||
def default_configuration
|
||||
if request.post?
|
||||
begin
|
||||
Redmine::DefaultData::Loader::load(params[:lang])
|
||||
flash[:notice] = l(:notice_default_data_loaded)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:error_can_t_load_default_data, e.message)
|
||||
end
|
||||
end
|
||||
redirect_to admin_url
|
||||
end
|
||||
|
||||
def test_email
|
||||
raise_delivery_errors = ActionMailer::Base.raise_delivery_errors
|
||||
# Force ActionMailer to raise delivery errors so we can catch it
|
||||
ActionMailer::Base.raise_delivery_errors = true
|
||||
begin
|
||||
@test = Mailer.test_email(User.current).deliver
|
||||
flash[:notice] = l(:notice_email_sent, User.current.mail)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:notice_email_error, e.message)
|
||||
end
|
||||
ActionMailer::Base.raise_delivery_errors = raise_delivery_errors
|
||||
redirect_to settings_url(:tab => 'notifications')
|
||||
end
|
||||
|
||||
def info
|
||||
@db_adapter_name = ActiveRecord::Base.connection.adapter_name
|
||||
@checklist = [
|
||||
[:text_default_administrator_account_changed, User.default_admin_account_changed?],
|
||||
[:text_file_repository_writable, File.writable?(Attachment.storage_path)],
|
||||
[:text_plugin_assets_writable, File.writable?(Redmine::Plugin.public_directory)],
|
||||
[:text_rmagick_available, Object.const_defined?(:Magick)]
|
||||
]
|
||||
end
|
||||
#管理功能用户列表的搜索
|
||||
def search
|
||||
sort_init 'login', 'asc'
|
||||
sort_update %w(login firstname lastname mail admin created_on last_login_on)
|
||||
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 15})
|
||||
else
|
||||
@limit = 15#per_page_option
|
||||
end
|
||||
|
||||
@status = params[:status] || 1
|
||||
scope = User.logged.status(@status)
|
||||
scope = scope.like(params[:name]) if params[:name].present?
|
||||
@user_count = scope.count
|
||||
@user_pages = Paginator.new @user_count, @limit, params['page']
|
||||
@user_base_tag = params[:id] ? 'base_users':'base'
|
||||
|
||||
@users = scope.offset(@user_pages.offset).limit(@user_pages.per_page)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@groups = Group.all.sort
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
#首页定制
|
||||
def first_page_made
|
||||
if request.get?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@first_page.description = params[:first_page][:description]
|
||||
#@first_page.title = params[:title]
|
||||
@first_page.image_width = params[:image_width]
|
||||
@first_page.image_height = params[:image_height]
|
||||
@first_page.sort_type = params[:sort_type]
|
||||
@first_page.show_course = params[:show_course]
|
||||
@first_page.show_contest = params[:show_contest]
|
||||
if @first_page.save
|
||||
respond_to do |format|
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
format.html {
|
||||
redirect_to first_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
#format.json { render json: @first_page, status: :created, location: @first_page }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}"
|
||||
format.html {
|
||||
render :action => 'first_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
#format.json { render json: @first_page.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def course_page_made
|
||||
if request.get?
|
||||
@course_page = FirstPage.find_by_page_type('course')
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@course_page = FirstPage.find_by_page_type('course')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@course_page.web_title = params[:web_title]
|
||||
@course_page.title = params[:course_title]
|
||||
@course_page.image_width = params[:image_width]
|
||||
@course_page.image_height = params[:image_height]
|
||||
@course_page.description = params[:course_description]
|
||||
if @first_page.save && @course_page.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to course_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@course_page.errors.full_messages[0]}"
|
||||
#flash.now[:error] = "#{l :label_first_page_create_fail}: #{@course_page.errors.full_messages[0]}"
|
||||
format.html {
|
||||
|
||||
render :action => 'course_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@course_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def contest_page_made
|
||||
if request.get?
|
||||
@contest_page = FirstPage.find_by_page_type('contest')
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@contest_page = FirstPage.find_by_page_type('contest')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@contest_page.web_title = params[:web_title]
|
||||
@contest_page.title = params[:contest_title]
|
||||
@contest_page.image_width = params[:image_width]
|
||||
@contest_page.image_height = params[:image_height]
|
||||
@contest_page.description = params[:contest_description]
|
||||
|
||||
if @first_page.save && @contest_page.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to contest_page_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@contest_page.errors.full_messages[0]}\n\t#{@notification.errors.full_messages[0]}"
|
||||
format.html {
|
||||
render :action => 'contest_page_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@contest_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def web_footer_made
|
||||
if request.get?
|
||||
@organizer = WebFooterOranizer.first
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
#@notification = ContestNotification.all.first;
|
||||
elsif request.post?
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
@first_page.web_title = params[:web_title]
|
||||
@organizer = WebFooterOranizer.first
|
||||
if @organizer.nil?
|
||||
@organizer = WebFooterOranizer.new
|
||||
end
|
||||
@organizer.name = params[:organizer_name]
|
||||
@organizer.description = params[:web_footer_oranizer][:description]
|
||||
if @first_page.save && @organizer.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to web_footer_made_url
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@organizer.errors.full_messages[0]}}"
|
||||
format.html {
|
||||
render :action => 'web_footer_made'
|
||||
}
|
||||
format.api { render_validation_errors(@first_page) }
|
||||
format.api { render_validation_errors(@contest_page) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,96 +1,96 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AuthSourcesController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :ldap_authentication
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
|
||||
|
||||
def index
|
||||
@auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
|
||||
end
|
||||
|
||||
def new
|
||||
klass_name = params[:type] || 'AuthSourceLdap'
|
||||
@auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source])
|
||||
render_404 unless @auth_source
|
||||
end
|
||||
|
||||
def create
|
||||
@auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source])
|
||||
if @auth_source.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to auth_sources_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @auth_source.update_attributes(params[:auth_source])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to auth_sources_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def test_connection
|
||||
begin
|
||||
@auth_source.test_connection
|
||||
flash[:notice] = l(:notice_successful_connection)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:error_unable_to_connect, e.message)
|
||||
end
|
||||
redirect_to auth_sources_url
|
||||
end
|
||||
|
||||
def destroy
|
||||
unless @auth_source.users.exists?
|
||||
@auth_source.destroy
|
||||
flash[:notice] = l(:notice_successful_delete)
|
||||
end
|
||||
redirect_to auth_sources_url
|
||||
end
|
||||
|
||||
def autocomplete_for_new_user
|
||||
results = AuthSource.search(params[:term])
|
||||
|
||||
render :json => results.map {|result| {
|
||||
'value' => result[:login],
|
||||
'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
|
||||
'login' => result[:login].to_s,
|
||||
'firstname' => result[:firstname].to_s,
|
||||
'lastname' => result[:lastname].to_s,
|
||||
'mail' => result[:mail].to_s,
|
||||
'auth_source_id' => result[:auth_source_id].to_s
|
||||
}}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_auth_source
|
||||
@auth_source = AuthSource.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class AuthSourcesController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :ldap_authentication
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
|
||||
|
||||
def index
|
||||
@auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
|
||||
end
|
||||
|
||||
def new
|
||||
klass_name = params[:type] || 'AuthSourceLdap'
|
||||
@auth_source = AuthSource.new_subclass_instance(klass_name, params[:auth_source])
|
||||
render_404 unless @auth_source
|
||||
end
|
||||
|
||||
def create
|
||||
@auth_source = AuthSource.new_subclass_instance(params[:type], params[:auth_source])
|
||||
if @auth_source.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to auth_sources_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @auth_source.update_attributes(params[:auth_source])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to auth_sources_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def test_connection
|
||||
begin
|
||||
@auth_source.test_connection
|
||||
flash[:notice] = l(:notice_successful_connection)
|
||||
rescue Exception => e
|
||||
flash[:error] = l(:error_unable_to_connect, e.message)
|
||||
end
|
||||
redirect_to auth_sources_url
|
||||
end
|
||||
|
||||
def destroy
|
||||
unless @auth_source.users.exists?
|
||||
@auth_source.destroy
|
||||
flash[:notice] = l(:notice_successful_delete)
|
||||
end
|
||||
redirect_to auth_sources_url
|
||||
end
|
||||
|
||||
def autocomplete_for_new_user
|
||||
results = AuthSource.search(params[:term])
|
||||
|
||||
render :json => results.map {|result| {
|
||||
'value' => result[:login],
|
||||
'label' => "#{result[:login]} (#{result[:firstname]} #{result[:lastname]})",
|
||||
'login' => result[:login].to_s,
|
||||
'firstname' => result[:firstname].to_s,
|
||||
'lastname' => result[:lastname].to_s,
|
||||
'mail' => result[:mail].to_s,
|
||||
'auth_source_id' => result[:auth_source_id].to_s
|
||||
}}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_auth_source
|
||||
@auth_source = AuthSource.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,152 +1,152 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class BoardsController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :messages
|
||||
before_filter :find_project_by_project_id, :find_board_if_available
|
||||
before_filter :authorize, :except => [:new, :show, :create, :index]
|
||||
accept_rss_auth :index, :show
|
||||
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :watchers
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
#modify by nwb
|
||||
if @project
|
||||
@boards = @project.boards.includes(:last_message => :author).all
|
||||
@boards = [] << @boards[0] if @boards.any?
|
||||
if @boards.size == 1
|
||||
@board = @boards.first
|
||||
show and return
|
||||
end
|
||||
render :layout => false if request.xhr?
|
||||
elsif @course
|
||||
@boards = @course.boards.includes(:last_message => :author).all
|
||||
@boards = [] << @boards[0] if @boards.any?
|
||||
if @boards.size == 1
|
||||
@board = @boards.first
|
||||
show and return
|
||||
end
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
sort_init 'updated_on', 'desc'
|
||||
sort_update 'created_on' => "#{Message.table_name}.created_on",
|
||||
'replies' => "#{Message.table_name}.replies_count",
|
||||
'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
|
||||
|
||||
@topic_count = @board.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@topics = @board.topics.
|
||||
reorder("#{Message.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
all
|
||||
@message = Message.new(:board => @board)
|
||||
#modify by nwb
|
||||
if @project
|
||||
render :action => 'show', :layout => 'base_projects'
|
||||
elsif @course
|
||||
render :action => 'show', :layout => 'base_courses'
|
||||
end
|
||||
}
|
||||
format.atom {
|
||||
@messages = @board.messages.
|
||||
reorder('created_on DESC').
|
||||
includes(:author, :board).
|
||||
limit(Setting.feeds_limit.to_i).
|
||||
all
|
||||
if @project
|
||||
render_feed(@messages, :title => "#{@project}: #{@board}")
|
||||
elsif @course
|
||||
render_feed(@messages, :title => "#{@course}: #{@board}")
|
||||
end
|
||||
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@board = @project.boards.build
|
||||
@board.safe_attributes = params[:board]
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@board = @project.boards.build
|
||||
@board.safe_attributes = params[:board]
|
||||
|
||||
if @board.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
#Modified by young
|
||||
#redirect_to_settings_in_projects
|
||||
redirect_to project_board_url(@project, @board)
|
||||
#Ended by young
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@board.safe_attributes = params[:board]
|
||||
if @board.save
|
||||
redirect_to_settings_in_projects
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@board.destroy
|
||||
redirect_to_settings_in_projects
|
||||
end
|
||||
|
||||
private
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'boards')
|
||||
end
|
||||
|
||||
def find_board_if_available
|
||||
if @project
|
||||
@board = @project.boards.find(params[:id]) if params[:id]
|
||||
elsif @course
|
||||
@board = @course.boards.find(params[:id]) if params[:id]
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class BoardsController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :messages
|
||||
before_filter :find_project_by_project_id, :find_board_if_available
|
||||
before_filter :authorize, :except => [:new, :show, :create, :index]
|
||||
accept_rss_auth :index, :show
|
||||
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :watchers
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
#modify by nwb
|
||||
if @project
|
||||
@boards = @project.boards.includes(:last_message => :author).all
|
||||
@boards = [] << @boards[0] if @boards.any?
|
||||
if @boards.size == 1
|
||||
@board = @boards.first
|
||||
show and return
|
||||
end
|
||||
render :layout => false if request.xhr?
|
||||
elsif @course
|
||||
@boards = @course.boards.includes(:last_message => :author).all
|
||||
@boards = [] << @boards[0] if @boards.any?
|
||||
if @boards.size == 1
|
||||
@board = @boards.first
|
||||
show and return
|
||||
end
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
sort_init 'updated_on', 'desc'
|
||||
sort_update 'created_on' => "#{Message.table_name}.created_on",
|
||||
'replies' => "#{Message.table_name}.replies_count",
|
||||
'updated_on' => "COALESCE(last_replies_messages.created_on, #{Message.table_name}.created_on)"
|
||||
|
||||
@topic_count = @board.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@topics = @board.topics.
|
||||
reorder("#{Message.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
all
|
||||
@message = Message.new(:board => @board)
|
||||
#modify by nwb
|
||||
if @project
|
||||
render :action => 'show', :layout => 'base_projects'
|
||||
elsif @course
|
||||
render :action => 'show', :layout => 'base_courses'
|
||||
end
|
||||
}
|
||||
format.atom {
|
||||
@messages = @board.messages.
|
||||
reorder('created_on DESC').
|
||||
includes(:author, :board).
|
||||
limit(Setting.feeds_limit.to_i).
|
||||
all
|
||||
if @project
|
||||
render_feed(@messages, :title => "#{@project}: #{@board}")
|
||||
elsif @course
|
||||
render_feed(@messages, :title => "#{@course}: #{@board}")
|
||||
end
|
||||
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@board = @project.boards.build
|
||||
@board.safe_attributes = params[:board]
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@board = @project.boards.build
|
||||
@board.safe_attributes = params[:board]
|
||||
|
||||
if @board.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
#Modified by young
|
||||
#redirect_to_settings_in_projects
|
||||
redirect_to project_board_url(@project, @board)
|
||||
#Ended by young
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@board.safe_attributes = params[:board]
|
||||
if @board.save
|
||||
redirect_to_settings_in_projects
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@board.destroy
|
||||
redirect_to_settings_in_projects
|
||||
end
|
||||
|
||||
private
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'boards')
|
||||
end
|
||||
|
||||
def find_board_if_available
|
||||
if @project
|
||||
@board = @project.boards.find(params[:id]) if params[:id]
|
||||
elsif @course
|
||||
@board = @course.boards.find(params[:id]) if params[:id]
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,55 +1,55 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CommentsController < ApplicationController
|
||||
default_search_scope :news
|
||||
model_object News
|
||||
before_filter :find_model_object
|
||||
before_filter :find_project_from_association
|
||||
before_filter :authorize
|
||||
|
||||
def create
|
||||
raise Unauthorized unless @news.commentable?
|
||||
|
||||
@comment = Comment.new
|
||||
@comment.safe_attributes = params[:comment]
|
||||
@comment.author = User.current
|
||||
if @news.comments << @comment
|
||||
flash[:notice] = l(:label_comment_added)
|
||||
end
|
||||
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@news.comments.find(params[:comment_id]).destroy
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# ApplicationController's find_model_object sets it based on the controller
|
||||
# name so it needs to be overriden and set to @news instead
|
||||
def find_model_object
|
||||
super
|
||||
@news = @object
|
||||
@comment = nil
|
||||
@news
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CommentsController < ApplicationController
|
||||
default_search_scope :news
|
||||
model_object News
|
||||
before_filter :find_model_object
|
||||
before_filter :find_project_from_association
|
||||
before_filter :authorize
|
||||
|
||||
def create
|
||||
raise Unauthorized unless @news.commentable?
|
||||
|
||||
@comment = Comment.new
|
||||
@comment.safe_attributes = params[:comment]
|
||||
@comment.author = User.current
|
||||
if @news.comments << @comment
|
||||
flash[:notice] = l(:label_comment_added)
|
||||
end
|
||||
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@news.comments.find(params[:comment_id]).destroy
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# ApplicationController's find_model_object sets it based on the controller
|
||||
# name so it needs to be overriden and set to @news instead
|
||||
def find_model_object
|
||||
super
|
||||
@news = @object
|
||||
@comment = nil
|
||||
@news
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
class ContestNotificationController < ApplicationController
|
||||
layout 'contest_base'
|
||||
def show
|
||||
@notification = ContestNotification.find(params[:id])
|
||||
end
|
||||
end
|
||||
class ContestNotificationController < ApplicationController
|
||||
layout 'contest_base'
|
||||
def show
|
||||
@notification = ContestNotification.find(params[:id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,187 +1,187 @@
|
|||
class ContestnotificationsController < ApplicationController
|
||||
# GET /contestnotifications
|
||||
# GET /contestnotifications.json
|
||||
layout 'base_newcontest'
|
||||
default_search_scope :contestnotifications
|
||||
model_object Contestnotification
|
||||
# before_filter :find_model_object, :except => [:new, :create, :index]
|
||||
# before_filter :find_contest_from_association, :except => [:new, :create, :index]
|
||||
before_filter :find_contest_by_contest_id, :only => [:new, :create]
|
||||
before_filter :find_contest
|
||||
before_filter :find_author
|
||||
# before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_contest, :only => [:index]
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index
|
||||
|
||||
before_filter :access_edit_destroy, only: [:edit ,:update, :destroy]
|
||||
|
||||
def find_author
|
||||
@user = @contest.author
|
||||
render_404 if @user.nil?
|
||||
end
|
||||
def find_contest
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
render_404 if @contest.nil?
|
||||
end
|
||||
|
||||
|
||||
def index
|
||||
|
||||
# @contestnotifications = Contestnotification.all
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # index.html.erb
|
||||
# format.json { render json: @contestnotifications }
|
||||
# end
|
||||
|
||||
### begin ###
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = 10
|
||||
end
|
||||
|
||||
scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible
|
||||
|
||||
@contestnotifications_count = scope.count
|
||||
@contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page']
|
||||
@offset ||= @contestnotifications_pages.offset
|
||||
@contestnotificationss = scope.all(:include => [:author, :contest],
|
||||
:order => "#{Contestnotification.table_name}.created_at DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@contestnotification = Contestnotification.new # for adding news inline
|
||||
render :layout => 'base_newcontest'
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") }
|
||||
end
|
||||
### end ###
|
||||
end
|
||||
|
||||
# GET /contestnotifications/1
|
||||
# GET /contestnotifications/1.json
|
||||
def show
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # show.html.erb
|
||||
# format.json { render json: @contestnotification }
|
||||
# end
|
||||
@notificationcomments = @contestnotification.notificationcomments
|
||||
@notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order?
|
||||
render :layout => 'base_newcontest'
|
||||
|
||||
end
|
||||
|
||||
# GET /contestnotifications/new
|
||||
# GET /contestnotifications/new.json
|
||||
def new
|
||||
# @contestnotification = Contestnotification.new
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # new.html.erb
|
||||
# format.json { render json: @contestnotification }
|
||||
# end
|
||||
@contestnotification = Contestnotification.new(:contest => @contest, :author => User.current)
|
||||
render :layout => 'base_newcontest'
|
||||
end
|
||||
|
||||
# GET /contestnotifications/1/edit
|
||||
def edit
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /contestnotifications
|
||||
# POST /contestnotifications.json
|
||||
def create
|
||||
# @contestnotification = Contestnotification.new(params[:contestnotification])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# if @contestnotification.save
|
||||
# format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' }
|
||||
# format.json { render json: @contestnotification, status: :created, location: @contestnotification }
|
||||
# else
|
||||
# format.html { render action: "new" }
|
||||
# format.json { render json: @contestnotification.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
@contestnotification = Contestnotification.new(:contest => @contest, :author => User.current)
|
||||
@contestnotification.safe_attributes = params[:contestnotification]
|
||||
@contestnotification.save_attachments(params[:attachments])
|
||||
if @contestnotification.save
|
||||
render_attachment_warning_if_needed(@contestnotification)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to contest_contestnotifications_url(@contest)
|
||||
else
|
||||
layout_file = 'base_newcontest'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /contestnotifications/1
|
||||
# PUT /contestnotifications/1.json
|
||||
def update
|
||||
# @contestnotification = Contestnotification.find(params[:id])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# if @contestnotification.update_attributes(params[:contestnotification])
|
||||
# format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' }
|
||||
# format.json { head :no_content }
|
||||
# else
|
||||
# format.html { render action: "edit" }
|
||||
# format.json { render json: @contestnotification.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
@contestnotification.safe_attributes = params[:contestnotification]
|
||||
@contestnotification.save_attachments(params[:attachments])
|
||||
if @contestnotification.save
|
||||
render_attachment_warning_if_needed(@contestnotification)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to contest_contestnotification_url(@contestnotification.contest, @contestnotification)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /contestnotifications/1
|
||||
# DELETE /contestnotifications/1.json
|
||||
def destroy
|
||||
# @contestnotification = Contestnotification.find(params[:id])
|
||||
# @contestnotification.destroy
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html { redirect_to contestnotifications_url }
|
||||
# format.json { head :no_content }
|
||||
# end
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
@contestnotification.destroy
|
||||
redirect_to contest_contestnotifications_url(@contest)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_optional_contest
|
||||
return true unless params[:id]
|
||||
@contest = Contest.find(params[:id])
|
||||
# authorize
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def access_edit_destroy
|
||||
if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)
|
||||
return true
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class ContestnotificationsController < ApplicationController
|
||||
# GET /contestnotifications
|
||||
# GET /contestnotifications.json
|
||||
layout 'base_newcontest'
|
||||
default_search_scope :contestnotifications
|
||||
model_object Contestnotification
|
||||
# before_filter :find_model_object, :except => [:new, :create, :index]
|
||||
# before_filter :find_contest_from_association, :except => [:new, :create, :index]
|
||||
before_filter :find_contest_by_contest_id, :only => [:new, :create]
|
||||
before_filter :find_contest
|
||||
before_filter :find_author
|
||||
# before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_contest, :only => [:index]
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index
|
||||
|
||||
before_filter :access_edit_destroy, only: [:edit ,:update, :destroy]
|
||||
|
||||
def find_author
|
||||
@user = @contest.author
|
||||
render_404 if @user.nil?
|
||||
end
|
||||
def find_contest
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
render_404 if @contest.nil?
|
||||
end
|
||||
|
||||
|
||||
def index
|
||||
|
||||
# @contestnotifications = Contestnotification.all
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # index.html.erb
|
||||
# format.json { render json: @contestnotifications }
|
||||
# end
|
||||
|
||||
### begin ###
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = 10
|
||||
end
|
||||
|
||||
scope = @contest ? @contest.contestnotifications.visible : Contestnotifications.visible
|
||||
|
||||
@contestnotifications_count = scope.count
|
||||
@contestnotifications_pages = Paginator.new @contestnotifications_count, @limit, params['page']
|
||||
@offset ||= @contestnotifications_pages.offset
|
||||
@contestnotificationss = scope.all(:include => [:author, :contest],
|
||||
:order => "#{Contestnotification.table_name}.created_at DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@contestnotification = Contestnotification.new # for adding news inline
|
||||
render :layout => 'base_newcontest'
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@contestnotificationss, :title => (@contest ? @contest.name : Setting.app_title) + ": #{l(:label_contest_notification)}") }
|
||||
end
|
||||
### end ###
|
||||
end
|
||||
|
||||
# GET /contestnotifications/1
|
||||
# GET /contestnotifications/1.json
|
||||
def show
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # show.html.erb
|
||||
# format.json { render json: @contestnotification }
|
||||
# end
|
||||
@notificationcomments = @contestnotification.notificationcomments
|
||||
@notificationcomments.reverse! if User.current.wants_notificationcomments_in_reverse_order?
|
||||
render :layout => 'base_newcontest'
|
||||
|
||||
end
|
||||
|
||||
# GET /contestnotifications/new
|
||||
# GET /contestnotifications/new.json
|
||||
def new
|
||||
# @contestnotification = Contestnotification.new
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html # new.html.erb
|
||||
# format.json { render json: @contestnotification }
|
||||
# end
|
||||
@contestnotification = Contestnotification.new(:contest => @contest, :author => User.current)
|
||||
render :layout => 'base_newcontest'
|
||||
end
|
||||
|
||||
# GET /contestnotifications/1/edit
|
||||
def edit
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /contestnotifications
|
||||
# POST /contestnotifications.json
|
||||
def create
|
||||
# @contestnotification = Contestnotification.new(params[:contestnotification])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# if @contestnotification.save
|
||||
# format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully created.' }
|
||||
# format.json { render json: @contestnotification, status: :created, location: @contestnotification }
|
||||
# else
|
||||
# format.html { render action: "new" }
|
||||
# format.json { render json: @contestnotification.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
@contestnotification = Contestnotification.new(:contest => @contest, :author => User.current)
|
||||
@contestnotification.safe_attributes = params[:contestnotification]
|
||||
@contestnotification.save_attachments(params[:attachments])
|
||||
if @contestnotification.save
|
||||
render_attachment_warning_if_needed(@contestnotification)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to contest_contestnotifications_url(@contest)
|
||||
else
|
||||
layout_file = 'base_newcontest'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /contestnotifications/1
|
||||
# PUT /contestnotifications/1.json
|
||||
def update
|
||||
# @contestnotification = Contestnotification.find(params[:id])
|
||||
#
|
||||
# respond_to do |format|
|
||||
# if @contestnotification.update_attributes(params[:contestnotification])
|
||||
# format.html { redirect_to @contestnotification, notice: 'Contestnotification was successfully updated.' }
|
||||
# format.json { head :no_content }
|
||||
# else
|
||||
# format.html { render action: "edit" }
|
||||
# format.json { render json: @contestnotification.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
@contestnotification.safe_attributes = params[:contestnotification]
|
||||
@contestnotification.save_attachments(params[:attachments])
|
||||
if @contestnotification.save
|
||||
render_attachment_warning_if_needed(@contestnotification)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to contest_contestnotification_url(@contestnotification.contest, @contestnotification)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /contestnotifications/1
|
||||
# DELETE /contestnotifications/1.json
|
||||
def destroy
|
||||
# @contestnotification = Contestnotification.find(params[:id])
|
||||
# @contestnotification.destroy
|
||||
#
|
||||
# respond_to do |format|
|
||||
# format.html { redirect_to contestnotifications_url }
|
||||
# format.json { head :no_content }
|
||||
# end
|
||||
@contestnotification = Contestnotification.find(params[:id])
|
||||
@contestnotification.destroy
|
||||
redirect_to contest_contestnotifications_url(@contest)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_optional_contest
|
||||
return true unless params[:id]
|
||||
@contest = Contest.find(params[:id])
|
||||
# authorize
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def access_edit_destroy
|
||||
if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?)
|
||||
return true
|
||||
else
|
||||
render_403
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,81 +1,81 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CustomFieldsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :build_new_custom_field, :only => [:new, :create]
|
||||
before_filter :find_custom_field, :only => [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
|
||||
@tab = params[:tab] || 'IssueCustomField'
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if @custom_field.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @custom_field.update_attributes(params[:custom_field])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
begin
|
||||
@custom_field.destroy
|
||||
rescue
|
||||
flash[:error] = l(:error_can_not_delete_custom_field)
|
||||
end
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_new_custom_field
|
||||
@custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
|
||||
if @custom_field.nil?
|
||||
render_404
|
||||
else
|
||||
@custom_field.default_value = nil
|
||||
end
|
||||
end
|
||||
|
||||
def find_custom_field
|
||||
@custom_field = CustomField.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class CustomFieldsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :build_new_custom_field, :only => [:new, :create]
|
||||
before_filter :find_custom_field, :only => [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@custom_fields_by_type = CustomField.all.group_by {|f| f.class.name }
|
||||
@tab = params[:tab] || 'IssueCustomField'
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if @custom_field.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
call_hook(:controller_custom_fields_new_after_save, :params => params, :custom_field => @custom_field)
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @custom_field.update_attributes(params[:custom_field])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
call_hook(:controller_custom_fields_edit_after_save, :params => params, :custom_field => @custom_field)
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
begin
|
||||
@custom_field.destroy
|
||||
rescue
|
||||
flash[:error] = l(:error_can_not_delete_custom_field)
|
||||
end
|
||||
redirect_to custom_fields_url(:tab => @custom_field.class.name)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_new_custom_field
|
||||
@custom_field = CustomField.new_subclass_instance(params[:type], params[:custom_field])
|
||||
if @custom_field.nil?
|
||||
render_404
|
||||
else
|
||||
@custom_field.default_value = nil
|
||||
end
|
||||
end
|
||||
|
||||
def find_custom_field
|
||||
@custom_field = CustomField.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,120 +1,120 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class DocumentsController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :documents
|
||||
model_object Document
|
||||
before_filter :find_project_by_project_id, :only => [:index, :new, :create]
|
||||
before_filter :find_model_object, :except => [:index, :new, :create]
|
||||
before_filter :find_project_from_association, :except => [:index, :new, :create]
|
||||
before_filter :authorize , :except => [:index]#Added by young
|
||||
before_filter :authorize_document
|
||||
|
||||
helper :attachments
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
||||
temp = @project.documents.includes(:attachments, :category).all
|
||||
documents = []
|
||||
temp.each do |doc|
|
||||
if doc.has_right?(@project)
|
||||
documents << doc
|
||||
end
|
||||
end
|
||||
case @sort_by
|
||||
when 'date'
|
||||
@grouped = documents.group_by {|d| d.updated_on.to_date }
|
||||
when 'title'
|
||||
@grouped = documents.group_by {|d| d.title.first.upcase}
|
||||
when 'author'
|
||||
# @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
|
||||
@grouped = documents.group_by {|d| d.user.name }
|
||||
else
|
||||
@grouped = documents.group_by(&:category)
|
||||
end
|
||||
@document = @project.documents.build
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
else
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@attachments = @document.attachments.all
|
||||
if @project.project_type ==1
|
||||
render :action => 'show', :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@document = @project.documents.build
|
||||
@document.safe_attributes = params[:document]
|
||||
end
|
||||
|
||||
def create
|
||||
@document = @project.documents.build
|
||||
@document.safe_attributes = params[:document]
|
||||
@document.user = User.current
|
||||
@document.save_attachments(params[:attachments])
|
||||
if @document.save
|
||||
render_attachment_warning_if_needed(@document)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to project_documents_url(@project)
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@document.safe_attributes = params[:document]
|
||||
if request.put? and @document.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to document_url(@document)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@document.destroy if request.delete?
|
||||
redirect_to project_documents_url(@project)
|
||||
end
|
||||
|
||||
def add_attachment
|
||||
attachments = Attachment.attach_files(@document, params[:attachments])
|
||||
render_attachment_warning_if_needed(@document)
|
||||
|
||||
if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
redirect_to document_url(@document)
|
||||
end
|
||||
|
||||
# 权限判断
|
||||
# add by nwb
|
||||
def authorize_document
|
||||
if !(User.current.admin? || User.current.member_of?(@project) || @document == nil || (@document != nil && @document.is_public==1))
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class DocumentsController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :documents
|
||||
model_object Document
|
||||
before_filter :find_project_by_project_id, :only => [:index, :new, :create]
|
||||
before_filter :find_model_object, :except => [:index, :new, :create]
|
||||
before_filter :find_project_from_association, :except => [:index, :new, :create]
|
||||
before_filter :authorize , :except => [:index]#Added by young
|
||||
before_filter :authorize_document
|
||||
|
||||
helper :attachments
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
@sort_by = %w(category date title author).include?(params[:sort_by]) ? params[:sort_by] : 'category'
|
||||
temp = @project.documents.includes(:attachments, :category).all
|
||||
documents = []
|
||||
temp.each do |doc|
|
||||
if doc.has_right?(@project)
|
||||
documents << doc
|
||||
end
|
||||
end
|
||||
case @sort_by
|
||||
when 'date'
|
||||
@grouped = documents.group_by {|d| d.updated_on.to_date }
|
||||
when 'title'
|
||||
@grouped = documents.group_by {|d| d.title.first.upcase}
|
||||
when 'author'
|
||||
# @grouped = documents.select{|d| d.attachments.any?}.group_by {|d| d.attachments.last.author}
|
||||
@grouped = documents.group_by {|d| d.user.name }
|
||||
else
|
||||
@grouped = documents.group_by(&:category)
|
||||
end
|
||||
@document = @project.documents.build
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
else
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@attachments = @document.attachments.all
|
||||
if @project.project_type ==1
|
||||
render :action => 'show', :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@document = @project.documents.build
|
||||
@document.safe_attributes = params[:document]
|
||||
end
|
||||
|
||||
def create
|
||||
@document = @project.documents.build
|
||||
@document.safe_attributes = params[:document]
|
||||
@document.user = User.current
|
||||
@document.save_attachments(params[:attachments])
|
||||
if @document.save
|
||||
render_attachment_warning_if_needed(@document)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to project_documents_url(@project)
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@document.safe_attributes = params[:document]
|
||||
if request.put? and @document.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to document_url(@document)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@document.destroy if request.delete?
|
||||
redirect_to project_documents_url(@project)
|
||||
end
|
||||
|
||||
def add_attachment
|
||||
attachments = Attachment.attach_files(@document, params[:attachments])
|
||||
render_attachment_warning_if_needed(@document)
|
||||
|
||||
if attachments.present? && attachments[:files].present? && Setting.notified_events.include?('document_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
redirect_to document_url(@document)
|
||||
end
|
||||
|
||||
# 权限判断
|
||||
# add by nwb
|
||||
def authorize_document
|
||||
if !(User.current.admin? || User.current.member_of?(@project) || @document == nil || (@document != nil && @document.is_public==1))
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,98 +1,98 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EnumerationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
before_filter :build_new_enumeration, :only => [:new, :create]
|
||||
before_filter :find_enumeration, :only => [:edit, :update, :destroy]
|
||||
accept_api_auth :index
|
||||
|
||||
helper :custom_fields
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api {
|
||||
@klass = Enumeration.get_subclass(params[:type])
|
||||
if @klass
|
||||
@enumerations = @klass.shared.sorted.all
|
||||
else
|
||||
render_404
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if request.post? && @enumeration.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to enumerations_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if request.put? && @enumeration.update_attributes(params[:enumeration])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to enumerations_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if !@enumeration.in_use?
|
||||
# No associated objects
|
||||
@enumeration.destroy
|
||||
redirect_to enumerations_url
|
||||
return
|
||||
elsif params[:reassign_to_id]
|
||||
if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
|
||||
@enumeration.destroy(reassign_to)
|
||||
redirect_to enumerations_url
|
||||
return
|
||||
end
|
||||
end
|
||||
@enumerations = @enumeration.class.all - [@enumeration]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_new_enumeration
|
||||
class_name = params[:enumeration] && params[:enumeration][:type] || params[:type]
|
||||
@enumeration = Enumeration.new_subclass_instance(class_name, params[:enumeration])
|
||||
if @enumeration.nil?
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def find_enumeration
|
||||
@enumeration = Enumeration.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EnumerationsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
before_filter :build_new_enumeration, :only => [:new, :create]
|
||||
before_filter :find_enumeration, :only => [:edit, :update, :destroy]
|
||||
accept_api_auth :index
|
||||
|
||||
helper :custom_fields
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api {
|
||||
@klass = Enumeration.get_subclass(params[:type])
|
||||
if @klass
|
||||
@enumerations = @klass.shared.sorted.all
|
||||
else
|
||||
render_404
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
end
|
||||
|
||||
def create
|
||||
if request.post? && @enumeration.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to enumerations_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if request.put? && @enumeration.update_attributes(params[:enumeration])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to enumerations_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if !@enumeration.in_use?
|
||||
# No associated objects
|
||||
@enumeration.destroy
|
||||
redirect_to enumerations_url
|
||||
return
|
||||
elsif params[:reassign_to_id]
|
||||
if reassign_to = @enumeration.class.find_by_id(params[:reassign_to_id])
|
||||
@enumeration.destroy(reassign_to)
|
||||
redirect_to enumerations_url
|
||||
return
|
||||
end
|
||||
end
|
||||
@enumerations = @enumeration.class.all - [@enumeration]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def build_new_enumeration
|
||||
class_name = params[:enumeration] && params[:enumeration][:type] || params[:type]
|
||||
@enumeration = Enumeration.new_subclass_instance(class_name, params[:enumeration])
|
||||
if @enumeration.nil?
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def find_enumeration
|
||||
@enumeration = Enumeration.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,280 +1,280 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class FilesController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
menu_item :files
|
||||
|
||||
before_filter :find_project_by_project_id#, :except => [:getattachtype]
|
||||
before_filter :authorize, :except => [:getattachtype]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :project_score
|
||||
|
||||
def show_attachments obj
|
||||
all_attachments = []
|
||||
obj.each do |container|
|
||||
all_attachments += container.attachments
|
||||
end
|
||||
@limit = 10
|
||||
@feedback_count = all_attachments.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@curse_attachments = all_attachments[@offset, @limit]
|
||||
end
|
||||
|
||||
def index
|
||||
#sort_init 'filename', 'asc'
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
sort = ""
|
||||
|
||||
if params[:project_id]
|
||||
@isproject = true
|
||||
|
||||
if params[:sort]
|
||||
params[:sort].split(",").each do |sort_type|
|
||||
order_by = sort_type.split(":")
|
||||
|
||||
case order_by[0]
|
||||
when "filename"
|
||||
attribute = "filename"
|
||||
when "size"
|
||||
attribute = "filesize"
|
||||
when "attach_type"
|
||||
attribute = "attachtype"
|
||||
when "content_type"
|
||||
attribute = "created_on"
|
||||
when "field_file_dense"
|
||||
attribute = "is_public"
|
||||
when "downloads"
|
||||
attribute = "downloads"
|
||||
when "created_on"
|
||||
attribute = "created_on"
|
||||
end
|
||||
|
||||
if order_by.count == 1
|
||||
sort += "#{Attachment.table_name}.#{attribute} desc "
|
||||
elsif order_by.count == 2
|
||||
sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} "
|
||||
end
|
||||
if sort_type != params[:sort].split(",").last
|
||||
sort += ","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)]
|
||||
@containers += @project.versions.includes(:attachments).reorder(sort).all.sort
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
render :layout => !request.xhr?
|
||||
elsif params[:course_id]
|
||||
@isproject = false
|
||||
|
||||
if params[:sort]
|
||||
params[:sort].split(",").each do |sort_type|
|
||||
order_by = sort_type.split(":")
|
||||
|
||||
case order_by[0]
|
||||
when "filename"
|
||||
attribute = "filename"
|
||||
when "size"
|
||||
attribute = "filesize"
|
||||
when "attach_type"
|
||||
attribute = "attachtype"
|
||||
when "content_type"
|
||||
attribute = "created_on"
|
||||
when "field_file_dense"
|
||||
attribute = "is_public"
|
||||
when "downloads"
|
||||
attribute = "downloads"
|
||||
when "created_on"
|
||||
attribute = "created_on"
|
||||
end
|
||||
|
||||
if order_by.count == 1
|
||||
sort += "#{Attachment.table_name}.#{attribute} asc "
|
||||
elsif order_by.count == 2
|
||||
sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} "
|
||||
end
|
||||
if sort_type != params[:sort].split(",").last
|
||||
sort += ","
|
||||
end
|
||||
end
|
||||
end
|
||||
@containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)]
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def new
|
||||
@versions = @project.versions.sort
|
||||
@course_tag = @project.project_type
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:add_tag]
|
||||
@addTag=true
|
||||
#render :back
|
||||
tag_saveEx
|
||||
#render :text =>"success"
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
#modify by nwb
|
||||
if @project
|
||||
@addTag=false
|
||||
container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id]))
|
||||
attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type])
|
||||
render_attachment_warning_if_needed(container)
|
||||
|
||||
if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
|
||||
# TODO: 临时用 nyan
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
@containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun
|
||||
@containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = 0
|
||||
@contenttype = 0
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html {
|
||||
redirect_to project_files_url(@project)
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
@addTag=false
|
||||
attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type])
|
||||
|
||||
if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
|
||||
# TODO: 临时用 nyan
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
@containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)]
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = 0
|
||||
@contenttype = 0
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html {
|
||||
redirect_to course_files_url(@course)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def tag_saveEx
|
||||
@tags = params[:tag_name][:name]
|
||||
@obj_id = params[:object_id]
|
||||
@obj_flag = params[:object_flag]
|
||||
|
||||
case @obj_flag
|
||||
when '1' then
|
||||
@obj = User.find_by_id(@obj_id)
|
||||
when '2' then
|
||||
@obj = Project.find_by_id(@obj_id)
|
||||
when '3' then
|
||||
@obj = Issue.find_by_id(@obj_id)
|
||||
when '4' then
|
||||
@obj = Bid.find_by_id(@obj_id)
|
||||
when '5' then
|
||||
@obj = Forum.find_by_id(@obj_id)
|
||||
when '6'
|
||||
@obj = Attachment.find_by_id(@obj_id)
|
||||
when '7' then
|
||||
@obj = Contest.find_by_id(@obj_id)
|
||||
when '8'
|
||||
@obj = OpenSourceProject.find_by_id(@obj_id)
|
||||
when '9'
|
||||
@obj = Course.find_by_id(@obj_id)
|
||||
else
|
||||
@obj = nil
|
||||
end
|
||||
unless @obj.nil?
|
||||
@obj.tag_list.add(@tags.split(","))
|
||||
else
|
||||
return
|
||||
end
|
||||
if @obj.save
|
||||
## 执行成功的操作。
|
||||
else
|
||||
#捕获异常
|
||||
end
|
||||
end
|
||||
|
||||
# 返回指定资源类型的资源列表
|
||||
# added by nwb
|
||||
def getattachtype
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
if @project
|
||||
@containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)]
|
||||
@containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort
|
||||
elsif @course
|
||||
@containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)]
|
||||
end
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = params[:type].to_i
|
||||
@contenttype = params[:contentType].to_s
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class FilesController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
menu_item :files
|
||||
|
||||
before_filter :find_project_by_project_id#, :except => [:getattachtype]
|
||||
before_filter :authorize, :except => [:getattachtype]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :project_score
|
||||
|
||||
def show_attachments obj
|
||||
all_attachments = []
|
||||
obj.each do |container|
|
||||
all_attachments += container.attachments
|
||||
end
|
||||
@limit = 10
|
||||
@feedback_count = all_attachments.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@curse_attachments = all_attachments[@offset, @limit]
|
||||
end
|
||||
|
||||
def index
|
||||
#sort_init 'filename', 'asc'
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
sort = ""
|
||||
|
||||
if params[:project_id]
|
||||
@isproject = true
|
||||
|
||||
if params[:sort]
|
||||
params[:sort].split(",").each do |sort_type|
|
||||
order_by = sort_type.split(":")
|
||||
|
||||
case order_by[0]
|
||||
when "filename"
|
||||
attribute = "filename"
|
||||
when "size"
|
||||
attribute = "filesize"
|
||||
when "attach_type"
|
||||
attribute = "attachtype"
|
||||
when "content_type"
|
||||
attribute = "created_on"
|
||||
when "field_file_dense"
|
||||
attribute = "is_public"
|
||||
when "downloads"
|
||||
attribute = "downloads"
|
||||
when "created_on"
|
||||
attribute = "created_on"
|
||||
end
|
||||
|
||||
if order_by.count == 1
|
||||
sort += "#{Attachment.table_name}.#{attribute} desc "
|
||||
elsif order_by.count == 2
|
||||
sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} "
|
||||
end
|
||||
if sort_type != params[:sort].split(",").last
|
||||
sort += ","
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@containers = [ Project.includes(:attachments).reorder(sort).find(@project.id)]
|
||||
@containers += @project.versions.includes(:attachments).reorder(sort).all.sort
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
render :layout => !request.xhr?
|
||||
elsif params[:course_id]
|
||||
@isproject = false
|
||||
|
||||
if params[:sort]
|
||||
params[:sort].split(",").each do |sort_type|
|
||||
order_by = sort_type.split(":")
|
||||
|
||||
case order_by[0]
|
||||
when "filename"
|
||||
attribute = "filename"
|
||||
when "size"
|
||||
attribute = "filesize"
|
||||
when "attach_type"
|
||||
attribute = "attachtype"
|
||||
when "content_type"
|
||||
attribute = "created_on"
|
||||
when "field_file_dense"
|
||||
attribute = "is_public"
|
||||
when "downloads"
|
||||
attribute = "downloads"
|
||||
when "created_on"
|
||||
attribute = "created_on"
|
||||
end
|
||||
|
||||
if order_by.count == 1
|
||||
sort += "#{Attachment.table_name}.#{attribute} asc "
|
||||
elsif order_by.count == 2
|
||||
sort += "#{Attachment.table_name}.#{attribute} #{order_by[1]} "
|
||||
end
|
||||
if sort_type != params[:sort].split(",").last
|
||||
sort += ","
|
||||
end
|
||||
end
|
||||
end
|
||||
@containers = [ Course.includes(:attachments).reorder(sort).find(@course.id)]
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def new
|
||||
@versions = @project.versions.sort
|
||||
@course_tag = @project.project_type
|
||||
if @project.project_type == 1
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:add_tag]
|
||||
@addTag=true
|
||||
#render :back
|
||||
tag_saveEx
|
||||
#render :text =>"success"
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
#modify by nwb
|
||||
if @project
|
||||
@addTag=false
|
||||
container = (params[:version_id].blank? ? @project : @project.versions.find_by_id(params[:version_id]))
|
||||
attachments = Attachment.attach_filesex(container, params[:attachments], params[:attachment_type])
|
||||
render_attachment_warning_if_needed(container)
|
||||
|
||||
if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
|
||||
# TODO: 临时用 nyan
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
@containers = [Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)] #modify by Long Jun
|
||||
@containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = 0
|
||||
@contenttype = 0
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html {
|
||||
redirect_to project_files_url(@project)
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
@addTag=false
|
||||
attachments = Attachment.attach_filesex(@course, params[:attachments], params[:attachment_type])
|
||||
|
||||
if !attachments.empty? && !attachments[:files].blank? && Setting.notified_events.include?('file_added')
|
||||
Mailer.attachments_added(attachments[:files]).deliver
|
||||
end
|
||||
|
||||
# TODO: 临时用 nyan
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
@containers = [Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)]
|
||||
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = 0
|
||||
@contenttype = 0
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
format.html {
|
||||
redirect_to course_files_url(@course)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def tag_saveEx
|
||||
@tags = params[:tag_name][:name]
|
||||
@obj_id = params[:object_id]
|
||||
@obj_flag = params[:object_flag]
|
||||
|
||||
case @obj_flag
|
||||
when '1' then
|
||||
@obj = User.find_by_id(@obj_id)
|
||||
when '2' then
|
||||
@obj = Project.find_by_id(@obj_id)
|
||||
when '3' then
|
||||
@obj = Issue.find_by_id(@obj_id)
|
||||
when '4' then
|
||||
@obj = Bid.find_by_id(@obj_id)
|
||||
when '5' then
|
||||
@obj = Forum.find_by_id(@obj_id)
|
||||
when '6'
|
||||
@obj = Attachment.find_by_id(@obj_id)
|
||||
when '7' then
|
||||
@obj = Contest.find_by_id(@obj_id)
|
||||
when '8'
|
||||
@obj = OpenSourceProject.find_by_id(@obj_id)
|
||||
when '9'
|
||||
@obj = Course.find_by_id(@obj_id)
|
||||
else
|
||||
@obj = nil
|
||||
end
|
||||
unless @obj.nil?
|
||||
@obj.tag_list.add(@tags.split(","))
|
||||
else
|
||||
return
|
||||
end
|
||||
if @obj.save
|
||||
## 执行成功的操作。
|
||||
else
|
||||
#捕获异常
|
||||
end
|
||||
end
|
||||
|
||||
# 返回指定资源类型的资源列表
|
||||
# added by nwb
|
||||
def getattachtype
|
||||
sort_init 'created_on', 'desc'
|
||||
sort_update 'created_on' => "#{Attachment.table_name}.created_on",
|
||||
'filename' => "#{Attachment.table_name}.filename",
|
||||
'size' => "#{Attachment.table_name}.filesize",
|
||||
'downloads' => "#{Attachment.table_name}.downloads"
|
||||
|
||||
if @project
|
||||
@containers = [ Project.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@project.id)]
|
||||
@containers += @project.versions.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").all.sort
|
||||
elsif @course
|
||||
@containers = [ Course.includes(:attachments).reorder("#{Attachment.table_name}.created_on DESC").find(@course.id)]
|
||||
end
|
||||
show_attachments @containers
|
||||
|
||||
@attachtype = params[:type].to_i
|
||||
@contenttype = params[:contentType].to_s
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,230 +1,230 @@
|
|||
# added by fq
|
||||
class ForumsController < ApplicationController
|
||||
layout "users_base"
|
||||
|
||||
# GET /forums
|
||||
# GET /forums.json
|
||||
before_filter :find_forum_if_available
|
||||
before_filter :authenticate_user_edit, :only => [:edit, :update]
|
||||
before_filter :authenticate_user_destroy, :only => [:destroy]
|
||||
before_filter :require_login, :only => [:new, :create]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
|
||||
PageLimit = 20
|
||||
|
||||
def create_memo
|
||||
@memo = Memo.new(params[:memo])
|
||||
@memo.forum_id = @forum.id
|
||||
@memo.author_id = User.current.id
|
||||
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
|
||||
respond_to do |format|
|
||||
if @memo.save
|
||||
format.html { redirect_to (forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))), notice: "#{l :label_memo_create_succ}" }
|
||||
format.json { render json: @memo, status: :created, location: @memo }
|
||||
else
|
||||
sort_init 'updated_at', 'desc'
|
||||
sort_update 'created_at' => "#{Memo.table_name}.created_at",
|
||||
'replies' => "#{Memo.table_name}.replies_count",
|
||||
'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)"
|
||||
|
||||
@topic_count = @forum.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @forum.topics.
|
||||
reorder("#{Memo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
all
|
||||
|
||||
flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
|
||||
# back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
|
||||
format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" }
|
||||
format.json { render json: @memo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
@forums_all = Forum.where('1=1')
|
||||
@forums_count = @forums_all.count
|
||||
@forums_pages = Paginator.new @forums_count, @limit, params['page']
|
||||
|
||||
|
||||
@offset ||= @forums_pages.offset
|
||||
@forums = @forums_all.offset(@offset).limit(@limit).all
|
||||
#@forums = Forum.all
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @forums }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/1
|
||||
# GET /forums/1.json
|
||||
def show
|
||||
sort_init 'updated_at', 'desc'
|
||||
sort_update 'created_at' => "#{Memo.table_name}.created_at",
|
||||
'replies' => "#{Memo.table_name}.replies_count",
|
||||
'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)"
|
||||
|
||||
@memo = Memo.new(:forum => @forum)
|
||||
@topic_count = @forum.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @forum.topics.
|
||||
reorder("#{Memo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
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_forums'
|
||||
}# show.html.erb
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/new
|
||||
# GET /forums/new.json
|
||||
def new
|
||||
@forum = Forum.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/1/edit
|
||||
def edit
|
||||
@forum = Forum.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /forums
|
||||
# POST /forums.json
|
||||
def create
|
||||
@forum = Forum.new(params[:forum])
|
||||
@forum.creator_id = User.current.id
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.save
|
||||
format.html { redirect_to @forum, notice: l(:label_forum_create_succ) }
|
||||
format.json { render json: @forum, status: :created, location: @forum }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}"
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @forum.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /forums/1
|
||||
# PUT /forums/1.json
|
||||
def update
|
||||
@forum = Forum.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.update_attributes(params[:forum])
|
||||
format.html { redirect_to @forum, notice: l(:label_forum_update_succ) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_forum_update_fail}: #{@forum.errors.full_messages[0]}"
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @forum.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /forums/1
|
||||
# DELETE /forums/1.json
|
||||
def destroy
|
||||
@forum = Forum.find(params[:id])
|
||||
@forum.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to forums_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
def search_forum
|
||||
# @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'")
|
||||
q = "%#{params[:name].strip}%"
|
||||
(redirect_to forums_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank?
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
@forums_all = Forum.where("name LIKE ?", q)
|
||||
@forums_count = @forums_all.count
|
||||
@forums_pages = Paginator.new @forums_count, @limit, params['page']
|
||||
|
||||
|
||||
@offset ||= @forums_pages.offset
|
||||
@forums = @forums_all.offset(@offset).limit(@limit).all
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render 'index'
|
||||
}
|
||||
format.json { render json: @forums }
|
||||
end
|
||||
end
|
||||
|
||||
def search_memo
|
||||
q = "%#{params[:name].strip}%"
|
||||
|
||||
limit = PageLimit
|
||||
@memo = Memo.new
|
||||
@offset, @limit = api_offset_and_limit({:limit => limit})
|
||||
@forum = Forum.find(params[:id])
|
||||
@memos_all = @forum.topics.where("subject LIKE ?", q)
|
||||
@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 'show', :layout => 'base_forums'
|
||||
}
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
def find_forum_if_available
|
||||
@forum = Forum.find(params[:id]) if params[:id]
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def authenticate_user_edit
|
||||
find_forum_if_available
|
||||
render_403 unless @forum.editable_by? User.current
|
||||
end
|
||||
|
||||
def authenticate_user_destroy
|
||||
find_forum_if_available
|
||||
render_403 unless @forum.destroyable_by? User.current
|
||||
end
|
||||
# added by fq
|
||||
class ForumsController < ApplicationController
|
||||
layout "users_base"
|
||||
|
||||
# GET /forums
|
||||
# GET /forums.json
|
||||
before_filter :find_forum_if_available
|
||||
before_filter :authenticate_user_edit, :only => [:edit, :update]
|
||||
before_filter :authenticate_user_destroy, :only => [:destroy]
|
||||
before_filter :require_login, :only => [:new, :create]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
|
||||
PageLimit = 20
|
||||
|
||||
def create_memo
|
||||
@memo = Memo.new(params[:memo])
|
||||
@memo.forum_id = @forum.id
|
||||
@memo.author_id = User.current.id
|
||||
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
|
||||
respond_to do |format|
|
||||
if @memo.save
|
||||
format.html { redirect_to (forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))), notice: "#{l :label_memo_create_succ}" }
|
||||
format.json { render json: @memo, status: :created, location: @memo }
|
||||
else
|
||||
sort_init 'updated_at', 'desc'
|
||||
sort_update 'created_at' => "#{Memo.table_name}.created_at",
|
||||
'replies' => "#{Memo.table_name}.replies_count",
|
||||
'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)"
|
||||
|
||||
@topic_count = @forum.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @forum.topics.
|
||||
reorder("#{Memo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
all
|
||||
|
||||
flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
|
||||
# back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
|
||||
format.html { render action: :show, layout: 'base_forums' }#, error: "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}" }
|
||||
format.json { render json: @memo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def index
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
@forums_all = Forum.where('1=1')
|
||||
@forums_count = @forums_all.count
|
||||
@forums_pages = Paginator.new @forums_count, @limit, params['page']
|
||||
|
||||
|
||||
@offset ||= @forums_pages.offset
|
||||
@forums = @forums_all.offset(@offset).limit(@limit).all
|
||||
#@forums = Forum.all
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @forums }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/1
|
||||
# GET /forums/1.json
|
||||
def show
|
||||
sort_init 'updated_at', 'desc'
|
||||
sort_update 'created_at' => "#{Memo.table_name}.created_at",
|
||||
'replies' => "#{Memo.table_name}.replies_count",
|
||||
'updated_at' => "COALESCE (last_replies_memos.created_at, #{Memo.table_name}.created_at)"
|
||||
|
||||
@memo = Memo.new(:forum => @forum)
|
||||
@topic_count = @forum.topics.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @forum.topics.
|
||||
reorder("#{Memo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
preload(:author, {:last_reply => :author}).
|
||||
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_forums'
|
||||
}# show.html.erb
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/new
|
||||
# GET /forums/new.json
|
||||
def new
|
||||
@forum = Forum.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /forums/1/edit
|
||||
def edit
|
||||
@forum = Forum.find(params[:id])
|
||||
end
|
||||
|
||||
# POST /forums
|
||||
# POST /forums.json
|
||||
def create
|
||||
@forum = Forum.new(params[:forum])
|
||||
@forum.creator_id = User.current.id
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.save
|
||||
format.html { redirect_to @forum, notice: l(:label_forum_create_succ) }
|
||||
format.json { render json: @forum, status: :created, location: @forum }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_forum_create_fail}: #{@forum.errors.full_messages[0]}"
|
||||
format.html { render action: "new" }
|
||||
format.json { render json: @forum.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /forums/1
|
||||
# PUT /forums/1.json
|
||||
def update
|
||||
@forum = Forum.find(params[:id])
|
||||
|
||||
respond_to do |format|
|
||||
if @forum.update_attributes(params[:forum])
|
||||
format.html { redirect_to @forum, notice: l(:label_forum_update_succ) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_forum_update_fail}: #{@forum.errors.full_messages[0]}"
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @forum.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /forums/1
|
||||
# DELETE /forums/1.json
|
||||
def destroy
|
||||
@forum = Forum.find(params[:id])
|
||||
@forum.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to forums_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
def search_forum
|
||||
# @forums = paginateHelper Forum.where("name LIKE '%#{params[:name]}%'")
|
||||
q = "%#{params[:name].strip}%"
|
||||
(redirect_to forums_url, :notice => l(:label_sumbit_empty);return) if params[:name].blank?
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
@forums_all = Forum.where("name LIKE ?", q)
|
||||
@forums_count = @forums_all.count
|
||||
@forums_pages = Paginator.new @forums_count, @limit, params['page']
|
||||
|
||||
|
||||
@offset ||= @forums_pages.offset
|
||||
@forums = @forums_all.offset(@offset).limit(@limit).all
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render 'index'
|
||||
}
|
||||
format.json { render json: @forums }
|
||||
end
|
||||
end
|
||||
|
||||
def search_memo
|
||||
q = "%#{params[:name].strip}%"
|
||||
|
||||
limit = PageLimit
|
||||
@memo = Memo.new
|
||||
@offset, @limit = api_offset_and_limit({:limit => limit})
|
||||
@forum = Forum.find(params[:id])
|
||||
@memos_all = @forum.topics.where("subject LIKE ?", q)
|
||||
@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 'show', :layout => 'base_forums'
|
||||
}
|
||||
format.json { render json: @forum }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
||||
def find_forum_if_available
|
||||
@forum = Forum.find(params[:id]) if params[:id]
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def authenticate_user_edit
|
||||
find_forum_if_available
|
||||
render_403 unless @forum.editable_by? User.current
|
||||
end
|
||||
|
||||
def authenticate_user_destroy
|
||||
find_forum_if_available
|
||||
render_403 unless @forum.destroyable_by? User.current
|
||||
end
|
||||
end
|
|
@ -1,141 +1,141 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class GroupsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :find_group, :except => [:index, :new, :create]
|
||||
accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
|
||||
|
||||
helper :custom_fields
|
||||
|
||||
def index
|
||||
@groups = Group.sorted.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@group = Group.new
|
||||
end
|
||||
|
||||
def create
|
||||
@group = Group.new
|
||||
@group.safe_attributes = params[:group]
|
||||
|
||||
respond_to do |format|
|
||||
if @group.save
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to(params[:continue] ? new_group_url : groups_url)
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => group_url(@group) }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.api { render_validation_errors(@group) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@group.safe_attributes = params[:group]
|
||||
|
||||
respond_to do |format|
|
||||
if @group.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
format.html { redirect_to(groups_url) }
|
||||
format.api { render_api_ok }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
format.api { render_validation_errors(@group) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@group.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(groups_url) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def add_users
|
||||
@users = User.find_all_by_id(params[:user_id] || params[:user_ids])
|
||||
@group.users << @users if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'users') }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def remove_user
|
||||
@group.users.delete(User.find(params[:user_id])) if request.delete?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'users') }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def autocomplete_for_user
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def edit_membership
|
||||
@membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
|
||||
@membership.save if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'memberships') }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_membership
|
||||
Member.find(params[:membership_id]).destroy if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'memberships') }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_group
|
||||
@group = Group.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class GroupsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin
|
||||
before_filter :find_group, :except => [:index, :new, :create]
|
||||
accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
|
||||
|
||||
helper :custom_fields
|
||||
|
||||
def index
|
||||
@groups = Group.sorted.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@group = Group.new
|
||||
end
|
||||
|
||||
def create
|
||||
@group = Group.new
|
||||
@group.safe_attributes = params[:group]
|
||||
|
||||
respond_to do |format|
|
||||
if @group.save
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to(params[:continue] ? new_group_url : groups_url)
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => group_url(@group) }
|
||||
else
|
||||
format.html { render :action => "new" }
|
||||
format.api { render_validation_errors(@group) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@group.safe_attributes = params[:group]
|
||||
|
||||
respond_to do |format|
|
||||
if @group.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
format.html { redirect_to(groups_url) }
|
||||
format.api { render_api_ok }
|
||||
else
|
||||
format.html { render :action => "edit" }
|
||||
format.api { render_validation_errors(@group) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@group.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to(groups_url) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def add_users
|
||||
@users = User.find_all_by_id(params[:user_id] || params[:user_ids])
|
||||
@group.users << @users if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'users') }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def remove_user
|
||||
@group.users.delete(User.find(params[:user_id])) if request.delete?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'users') }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def autocomplete_for_user
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def edit_membership
|
||||
@membership = Member.edit_membership(params[:membership_id], params[:membership], @group)
|
||||
@membership.save if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'memberships') }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_membership
|
||||
Member.find(params[:membership_id]).destroy if request.post?
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_group_url(@group, :tab => 'memberships') }
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_group
|
||||
@group = Group.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,365 +1,365 @@
|
|||
class HomeworkAttachController < ApplicationController
|
||||
layout "course_base"
|
||||
include CoursesHelper
|
||||
###############################
|
||||
before_filter :can_show_course,except: []
|
||||
#判断当前角色权限时需先找到当前操作的project
|
||||
before_filter :find_course_by_bid_id, :only => [:new]
|
||||
before_filter :find_course_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users]
|
||||
#判断当前角色是否有操作权限
|
||||
#勿删 before_filter :authorize, :only => [:new,:edit,:update,:destroy]
|
||||
|
||||
def find_course_by_bid_id
|
||||
@bid = Bid.find(params[:id])
|
||||
@course = @bid.courses[0]
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_course_by_hoemwork_id
|
||||
@homework = HomeworkAttach.find(params[:id])
|
||||
@course = @homework.bid.courses[0]
|
||||
end
|
||||
|
||||
#获取作业的成员
|
||||
def get_homework_member homework
|
||||
@hoemwork_users = users_for_homework(@homework)
|
||||
@members = members_for_homework(@homework,@hoemwork_users,params[:q])
|
||||
@members = paginateHelper @members,10
|
||||
end
|
||||
|
||||
def index
|
||||
@homeworks = HomeworkAttach.all
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @homeworks }
|
||||
end
|
||||
end
|
||||
|
||||
#作业添加成员(参与人员)
|
||||
def add_homework_users
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
@homework.homework_users.build(:user_id => user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@homework.save
|
||||
get_homework_member @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#作业删除成员(参与人员)
|
||||
def destory_homework_users
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
homework_user = @homework.homework_users.where("user_id = #{params[:user_id]}").first
|
||||
homework_user.destroy
|
||||
get_homework_member @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
bid = Bid.find params[:bid_id]
|
||||
if User.current.admin? || User.current.member_of_course?(bid.courses.first) # modify by nwb
|
||||
if bid.homeworks.where("user_id = ?",User.current).count == 0
|
||||
user_id = params[:user_id]
|
||||
bid_id = params[:bid_id]
|
||||
if params[:homework_attach]
|
||||
if params[:homework_attach][:project_id]
|
||||
project_id = params[:homework_attach][:project_id]
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
sta = 0
|
||||
name = params[:new_form][:name]
|
||||
description = params[:new_form][:description]
|
||||
options = {
|
||||
:user_id => user_id,
|
||||
:state => sta,
|
||||
:name => name,
|
||||
:description => description,
|
||||
:bid_id => bid_id,
|
||||
:project_id => project_id
|
||||
}
|
||||
|
||||
|
||||
#@homework_list = @bid.homeworks
|
||||
|
||||
@homework = HomeworkAttach.new(options)
|
||||
@homework.save_attachments(params[:attachments])
|
||||
render_attachment_warning_if_needed(@homework)
|
||||
|
||||
if @homework.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_has_homework
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@bid = Bid.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@bid.courses.first) #nwb
|
||||
#该课程的学生的集合(新建不实现功能:添加成员)
|
||||
#@members = @bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id <> #{User.current.id}", {:role_id => [5, 10]})
|
||||
|
||||
#@members = paginateHelper @members,10
|
||||
#@all_user = []
|
||||
#@bid.courses.first.members.each do |member|
|
||||
# @all_user << member.user
|
||||
#end
|
||||
@homework = HomeworkAttach.new
|
||||
#@homework_user = members_for_homework(@homework) + User.current
|
||||
#@members = @all_user - @homework_user
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @homework }
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#获取作业成员的集合
|
||||
def get_homework_member_list
|
||||
@homework = HomeworkAttach.find(params[:bid_id])
|
||||
course = @homework.bid.courses.first
|
||||
if User.current.admin? || User.current.member_of_course?(course)
|
||||
get_homework_member @homework
|
||||
else
|
||||
raise "error"
|
||||
end
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#获取指定作业的所有成员
|
||||
def users_for_homework homework
|
||||
homework.nil? ? [] : (homework.users + [homework.user])
|
||||
end
|
||||
|
||||
#获取可选成员列表
|
||||
#homework:作业
|
||||
#users:该作业所有成员
|
||||
#q:模糊匹配的用户的昵称
|
||||
def members_for_homework homework,users,q
|
||||
#homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id not in (:users)", {:role_id => [5, 10],:users => users}).joins(:user).where("users.login like '%#{q}%'")
|
||||
unpartin_users = homework.bid.courses.first.members.where("user_id not in (:users)", {:users => users}).joins(:user).where("users.login like '%#{q}%'")
|
||||
canpartin_users = []
|
||||
unpartin_users.each do |m|
|
||||
if m.user.allowed_to?(:paret_in_homework,homework.bid.courses.first)
|
||||
canpartin_users << m
|
||||
end
|
||||
end
|
||||
canpartin_users
|
||||
end
|
||||
|
||||
def edit
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
#@members = @homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id)", {:role_id => [5, 10]})
|
||||
get_homework_member @homework
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
course = @homework.bid.courses.first
|
||||
if User.current.admin? || User.current.member_of_course?(course)
|
||||
name = params[:homework_name]
|
||||
description = params[:homework_description]
|
||||
if params[:homework_attach]
|
||||
if params[:homework_attach][:project_id]
|
||||
project_id = params[:homework_attach][:project_id]
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
@homework.name = name
|
||||
@homework.description = description
|
||||
@homework.project_id = project_id
|
||||
if params[:attachments]
|
||||
@homework.save_attachments(params[:attachments])
|
||||
end
|
||||
if @homework.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current == @homework.user
|
||||
if @homework.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#显示作业信息
|
||||
def show
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
# 打分统计
|
||||
stars_reates = @homework.
|
||||
rates(:quality)
|
||||
stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
stars_status = stars_reates.select("stars, count(*) as scount").
|
||||
group("stars")
|
||||
@stars_status_map = Hash.new(0.0)
|
||||
stars_status.each do |star_status|
|
||||
percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f
|
||||
percent_m = format("%.2f", percent)
|
||||
@stars_status_map["star#{star_status.stars.to_i}".to_sym] =
|
||||
percent_m.to_s + "%"
|
||||
end
|
||||
#是否已经进行过评价
|
||||
@has_evaluation = stars_reates.where("rater_id = ?",User.current).count > 0
|
||||
#是否开启互评功能
|
||||
@is_evaluation = @homework.bid.is_evaluation == 1 || @homework.bid.is_evaluation == nil
|
||||
@limit = 10
|
||||
@jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC")
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC")
|
||||
|
||||
@totle_score = score_for_homework @homework
|
||||
@teaher_score = teacher_score_for_homework @homework
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#删除留言
|
||||
def destroy_jour
|
||||
@journal_destroyed = JournalsForMessage.delete_message(params[:object_id])
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
#@jours = @homework.journals_for_messages.order("created_on DESC")
|
||||
#@limit = 10
|
||||
#@feedback_count = @jours.count
|
||||
#@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
#@offset ||= @feedback_pages.offset
|
||||
#@jour = @jours[@offset, @limit]
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#添加留言
|
||||
def addjours
|
||||
@homework = HomeworkAttach.find(params[:jour_id])
|
||||
@add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation]
|
||||
@jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC")
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC")
|
||||
|
||||
@totle_score = score_for_homework @homework
|
||||
@teaher_score = teacher_score_for_homework @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#教师综评
|
||||
def comprehensive_evaluation_jour
|
||||
@homework = HomeworkAttach.find(params[:jour_id])
|
||||
@add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation]
|
||||
respond_to do |format|
|
||||
format.html { redirect_to homework_attach_url @homework }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
#获取指定作业的平均得分
|
||||
def score
|
||||
#stars_reates = @homework.rates(:quality)
|
||||
#percent = 0
|
||||
#stars_reates.each do |star_reates|
|
||||
# percent = percent + star_reates.stars
|
||||
#end
|
||||
#stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
#result = percent * 1.0 / stars_reates_count
|
||||
#result
|
||||
end
|
||||
|
||||
#添加回复
|
||||
def add_jour_reply
|
||||
parent_id = params[:reference_id]
|
||||
author_id = User.current.id
|
||||
reply_user_id = params[:reference_user_id]
|
||||
reply_id = params[:reference_message_id] # 暂时不实现
|
||||
content = params[:user_notes]
|
||||
options = {:user_id => author_id,
|
||||
:m_parent_id => parent_id,
|
||||
:m_reply_id => reply_id,
|
||||
:reply_id => reply_user_id,
|
||||
:notes => content,
|
||||
:is_readed => false}
|
||||
@jfm = JournalsForMessage.new(options)
|
||||
@jfm.save
|
||||
respond_to do |format|
|
||||
format.js{
|
||||
@save_succ = true if @jfm.errors.empty?
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#验证是否显示课程
|
||||
def can_show_course
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
if @first_page.show_course == 2
|
||||
render_404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class HomeworkAttachController < ApplicationController
|
||||
layout "course_base"
|
||||
include CoursesHelper
|
||||
###############################
|
||||
before_filter :can_show_course,except: []
|
||||
#判断当前角色权限时需先找到当前操作的project
|
||||
before_filter :find_course_by_bid_id, :only => [:new]
|
||||
before_filter :find_course_by_hoemwork_id, :only => [:edit,:update,:destroy,:show,:add_homework_users,:destory_homework_users]
|
||||
#判断当前角色是否有操作权限
|
||||
#勿删 before_filter :authorize, :only => [:new,:edit,:update,:destroy]
|
||||
|
||||
def find_course_by_bid_id
|
||||
@bid = Bid.find(params[:id])
|
||||
@course = @bid.courses[0]
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_course_by_hoemwork_id
|
||||
@homework = HomeworkAttach.find(params[:id])
|
||||
@course = @homework.bid.courses[0]
|
||||
end
|
||||
|
||||
#获取作业的成员
|
||||
def get_homework_member homework
|
||||
@hoemwork_users = users_for_homework(@homework)
|
||||
@members = members_for_homework(@homework,@hoemwork_users,params[:q])
|
||||
@members = paginateHelper @members,10
|
||||
end
|
||||
|
||||
def index
|
||||
@homeworks = HomeworkAttach.all
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @homeworks }
|
||||
end
|
||||
end
|
||||
|
||||
#作业添加成员(参与人员)
|
||||
def add_homework_users
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
@homework.homework_users.build(:user_id => user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@homework.save
|
||||
get_homework_member @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#作业删除成员(参与人员)
|
||||
def destory_homework_users
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
homework_user = @homework.homework_users.where("user_id = #{params[:user_id]}").first
|
||||
homework_user.destroy
|
||||
get_homework_member @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
bid = Bid.find params[:bid_id]
|
||||
if User.current.admin? || User.current.member_of_course?(bid.courses.first) # modify by nwb
|
||||
if bid.homeworks.where("user_id = ?",User.current).count == 0
|
||||
user_id = params[:user_id]
|
||||
bid_id = params[:bid_id]
|
||||
if params[:homework_attach]
|
||||
if params[:homework_attach][:project_id]
|
||||
project_id = params[:homework_attach][:project_id]
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
sta = 0
|
||||
name = params[:new_form][:name]
|
||||
description = params[:new_form][:description]
|
||||
options = {
|
||||
:user_id => user_id,
|
||||
:state => sta,
|
||||
:name => name,
|
||||
:description => description,
|
||||
:bid_id => bid_id,
|
||||
:project_id => project_id
|
||||
}
|
||||
|
||||
|
||||
#@homework_list = @bid.homeworks
|
||||
|
||||
@homework = HomeworkAttach.new(options)
|
||||
@homework.save_attachments(params[:attachments])
|
||||
render_attachment_warning_if_needed(@homework)
|
||||
|
||||
if @homework.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_has_homework
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@bid = Bid.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@bid.courses.first) #nwb
|
||||
#该课程的学生的集合(新建不实现功能:添加成员)
|
||||
#@members = @bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id <> #{User.current.id}", {:role_id => [5, 10]})
|
||||
|
||||
#@members = paginateHelper @members,10
|
||||
#@all_user = []
|
||||
#@bid.courses.first.members.each do |member|
|
||||
# @all_user << member.user
|
||||
#end
|
||||
@homework = HomeworkAttach.new
|
||||
#@homework_user = members_for_homework(@homework) + User.current
|
||||
#@members = @all_user - @homework_user
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @homework }
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#获取作业成员的集合
|
||||
def get_homework_member_list
|
||||
@homework = HomeworkAttach.find(params[:bid_id])
|
||||
course = @homework.bid.courses.first
|
||||
if User.current.admin? || User.current.member_of_course?(course)
|
||||
get_homework_member @homework
|
||||
else
|
||||
raise "error"
|
||||
end
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#获取指定作业的所有成员
|
||||
def users_for_homework homework
|
||||
homework.nil? ? [] : (homework.users + [homework.user])
|
||||
end
|
||||
|
||||
#获取可选成员列表
|
||||
#homework:作业
|
||||
#users:该作业所有成员
|
||||
#q:模糊匹配的用户的昵称
|
||||
def members_for_homework homework,users,q
|
||||
#homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id) and user_id not in (:users)", {:role_id => [5, 10],:users => users}).joins(:user).where("users.login like '%#{q}%'")
|
||||
unpartin_users = homework.bid.courses.first.members.where("user_id not in (:users)", {:users => users}).joins(:user).where("users.login like '%#{q}%'")
|
||||
canpartin_users = []
|
||||
unpartin_users.each do |m|
|
||||
if m.user.allowed_to?(:paret_in_homework,homework.bid.courses.first)
|
||||
canpartin_users << m
|
||||
end
|
||||
end
|
||||
canpartin_users
|
||||
end
|
||||
|
||||
def edit
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
#@members = @homework.bid.courses.first.members.joins(:member_roles).where("member_roles.role_id IN (:role_id)", {:role_id => [5, 10]})
|
||||
get_homework_member @homework
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
course = @homework.bid.courses.first
|
||||
if User.current.admin? || User.current.member_of_course?(course)
|
||||
name = params[:homework_name]
|
||||
description = params[:homework_description]
|
||||
if params[:homework_attach]
|
||||
if params[:homework_attach][:project_id]
|
||||
project_id = params[:homework_attach][:project_id]
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
else
|
||||
project_id = 0
|
||||
end
|
||||
@homework.name = name
|
||||
@homework.description = description
|
||||
@homework.project_id = project_id
|
||||
if params[:attachments]
|
||||
@homework.save_attachments(params[:attachments])
|
||||
end
|
||||
if @homework.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current == @homework.user
|
||||
if @homework.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to course_for_bid_url @homework.bid }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
end
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#显示作业信息
|
||||
def show
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
if User.current.admin? || User.current.member_of_course?(@homework.bid.courses.first)
|
||||
# 打分统计
|
||||
stars_reates = @homework.
|
||||
rates(:quality)
|
||||
stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
stars_status = stars_reates.select("stars, count(*) as scount").
|
||||
group("stars")
|
||||
@stars_status_map = Hash.new(0.0)
|
||||
stars_status.each do |star_status|
|
||||
percent = (star_status.scount * 1.0/ stars_reates_count) * 100.to_f
|
||||
percent_m = format("%.2f", percent)
|
||||
@stars_status_map["star#{star_status.stars.to_i}".to_sym] =
|
||||
percent_m.to_s + "%"
|
||||
end
|
||||
#是否已经进行过评价
|
||||
@has_evaluation = stars_reates.where("rater_id = ?",User.current).count > 0
|
||||
#是否开启互评功能
|
||||
@is_evaluation = @homework.bid.is_evaluation == 1 || @homework.bid.is_evaluation == nil
|
||||
@limit = 10
|
||||
@jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC")
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC")
|
||||
|
||||
@totle_score = score_for_homework @homework
|
||||
@teaher_score = teacher_score_for_homework @homework
|
||||
else
|
||||
render_403 :message => :notice_not_authorized
|
||||
end
|
||||
end
|
||||
|
||||
#删除留言
|
||||
def destroy_jour
|
||||
@journal_destroyed = JournalsForMessage.delete_message(params[:object_id])
|
||||
#@homework = HomeworkAttach.find(params[:id])
|
||||
#@jours = @homework.journals_for_messages.order("created_on DESC")
|
||||
#@limit = 10
|
||||
#@feedback_count = @jours.count
|
||||
#@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
#@offset ||= @feedback_pages.offset
|
||||
#@jour = @jours[@offset, @limit]
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#添加留言
|
||||
def addjours
|
||||
@homework = HomeworkAttach.find(params[:jour_id])
|
||||
@add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation]
|
||||
@jours = @homework.journals_for_messages.where("is_comprehensive_evaluation is null").order("created_on DESC")
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@comprehensive_evaluation = @homework.journals_for_messages.where("is_comprehensive_evaluation is not null").order("created_on DESC")
|
||||
|
||||
@totle_score = score_for_homework @homework
|
||||
@teaher_score = teacher_score_for_homework @homework
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#教师综评
|
||||
def comprehensive_evaluation_jour
|
||||
@homework = HomeworkAttach.find(params[:jour_id])
|
||||
@add_jour = @homework.addjours User.current.id, params[:new_form][:user_message],0,params[:is_comprehensive_evaluation]
|
||||
respond_to do |format|
|
||||
format.html { redirect_to homework_attach_url @homework }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
#获取指定作业的平均得分
|
||||
def score
|
||||
#stars_reates = @homework.rates(:quality)
|
||||
#percent = 0
|
||||
#stars_reates.each do |star_reates|
|
||||
# percent = percent + star_reates.stars
|
||||
#end
|
||||
#stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
#result = percent * 1.0 / stars_reates_count
|
||||
#result
|
||||
end
|
||||
|
||||
#添加回复
|
||||
def add_jour_reply
|
||||
parent_id = params[:reference_id]
|
||||
author_id = User.current.id
|
||||
reply_user_id = params[:reference_user_id]
|
||||
reply_id = params[:reference_message_id] # 暂时不实现
|
||||
content = params[:user_notes]
|
||||
options = {:user_id => author_id,
|
||||
:m_parent_id => parent_id,
|
||||
:m_reply_id => reply_id,
|
||||
:reply_id => reply_user_id,
|
||||
:notes => content,
|
||||
:is_readed => false}
|
||||
@jfm = JournalsForMessage.new(options)
|
||||
@jfm.save
|
||||
respond_to do |format|
|
||||
format.js{
|
||||
@save_succ = true if @jfm.errors.empty?
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#验证是否显示课程
|
||||
def can_show_course
|
||||
@first_page = FirstPage.find_by_page_type('project')
|
||||
if @first_page.show_course == 2
|
||||
render_404
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,132 +1,132 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueCategoriesController < ApplicationController
|
||||
layout "project_base"
|
||||
menu_item :settings
|
||||
model_object IssueCategory
|
||||
before_filter :find_model_object, :except => [:index, :new, :create]
|
||||
#before_filter :find_model_object_contest, :except => [:index, :new, :create]
|
||||
before_filter :find_project_from_association, :except => [:index, :new, :create]
|
||||
before_filter :find_project_by_project_id, :only => [:index, :new, :create]
|
||||
before_filter :authorize
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api { @categories = @project.issue_categories.all }
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@category = @project.issue_categories.build
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
|
||||
respond_to do |format|
|
||||
format.html{render :layout => 'base_projects'}# by young
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@category = @project.issue_categories.build
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
if @category.save
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to_settings_in_projects
|
||||
end
|
||||
format.js
|
||||
format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new'}
|
||||
format.js { render :action => 'new'}
|
||||
format.api { render_validation_errors(@category) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
if @category.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to_settings_in_projects
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@category) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@issue_count = @category.issues.size
|
||||
if @issue_count == 0 || params[:todo] || api_request?
|
||||
reassign_to = nil
|
||||
if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?)
|
||||
reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id])
|
||||
end
|
||||
@category.destroy(reassign_to)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
return
|
||||
end
|
||||
@categories = @project.issue_categories - [@category]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'categories')
|
||||
end
|
||||
|
||||
# Wrap ApplicationController's find_model_object method to set
|
||||
# @category instead of just @issue_category
|
||||
def find_model_object
|
||||
super
|
||||
@category = @object
|
||||
end
|
||||
|
||||
def find_model_object_contest
|
||||
super
|
||||
@category = @object
|
||||
end
|
||||
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueCategoriesController < ApplicationController
|
||||
layout "project_base"
|
||||
menu_item :settings
|
||||
model_object IssueCategory
|
||||
before_filter :find_model_object, :except => [:index, :new, :create]
|
||||
#before_filter :find_model_object_contest, :except => [:index, :new, :create]
|
||||
before_filter :find_project_from_association, :except => [:index, :new, :create]
|
||||
before_filter :find_project_by_project_id, :only => [:index, :new, :create]
|
||||
before_filter :authorize
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api { @categories = @project.issue_categories.all }
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@category = @project.issue_categories.build
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
|
||||
respond_to do |format|
|
||||
format.html{render :layout => 'base_projects'}# by young
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@category = @project.issue_categories.build
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
if @category.save
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to_settings_in_projects
|
||||
end
|
||||
format.js
|
||||
format.api { render :action => 'show', :status => :created, :location => issue_category_path(@category) }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new'}
|
||||
format.js { render :action => 'new'}
|
||||
format.api { render_validation_errors(@category) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@category.safe_attributes = params[:issue_category]
|
||||
if @category.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to_settings_in_projects
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@category) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@issue_count = @category.issues.size
|
||||
if @issue_count == 0 || params[:todo] || api_request?
|
||||
reassign_to = nil
|
||||
if params[:reassign_to_id] && (params[:todo] == 'reassign' || params[:todo].blank?)
|
||||
reassign_to = @project.issue_categories.find_by_id(params[:reassign_to_id])
|
||||
end
|
||||
@category.destroy(reassign_to)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
return
|
||||
end
|
||||
@categories = @project.issue_categories - [@category]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'categories')
|
||||
end
|
||||
|
||||
# Wrap ApplicationController's find_model_object method to set
|
||||
# @category instead of just @issue_category
|
||||
def find_model_object
|
||||
super
|
||||
@category = @object
|
||||
end
|
||||
|
||||
def find_model_object_contest
|
||||
super
|
||||
@category = @object
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,88 +1,88 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueRelationsController < ApplicationController
|
||||
before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create]
|
||||
before_filter :find_relation, :except => [:index, :create]
|
||||
|
||||
accept_api_auth :index, :show, :create, :destroy
|
||||
|
||||
def index
|
||||
@relations = @issue.relations
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :nothing => true }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
raise Unauthorized unless @relation.visible?
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :nothing => true }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@relation = IssueRelation.new(params[:relation])
|
||||
@relation.issue_from = @issue
|
||||
if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/)
|
||||
@relation.issue_to = Issue.visible.find_by_id(m[1].to_i)
|
||||
end
|
||||
saved = @relation.save
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@issue) }
|
||||
format.js {
|
||||
@relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
}
|
||||
format.api {
|
||||
if saved
|
||||
render :action => 'show', :status => :created, :location => relation_url(@relation)
|
||||
else
|
||||
render_validation_errors(@relation)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise Unauthorized unless @relation.deletable?
|
||||
@relation.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@relation.issue_from) }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_issue
|
||||
@issue = @object = Issue.find(params[:issue_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_relation
|
||||
@relation = IssueRelation.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueRelationsController < ApplicationController
|
||||
before_filter :find_issue, :find_project_from_association, :authorize, :only => [:index, :create]
|
||||
before_filter :find_relation, :except => [:index, :create]
|
||||
|
||||
accept_api_auth :index, :show, :create, :destroy
|
||||
|
||||
def index
|
||||
@relations = @issue.relations
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :nothing => true }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
raise Unauthorized unless @relation.visible?
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :nothing => true }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@relation = IssueRelation.new(params[:relation])
|
||||
@relation.issue_from = @issue
|
||||
if params[:relation] && m = params[:relation][:issue_to_id].to_s.strip.match(/^#?(\d+)$/)
|
||||
@relation.issue_to = Issue.visible.find_by_id(m[1].to_i)
|
||||
end
|
||||
saved = @relation.save
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@issue) }
|
||||
format.js {
|
||||
@relations = @issue.reload.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
}
|
||||
format.api {
|
||||
if saved
|
||||
render :action => 'show', :status => :created, :location => relation_url(@relation)
|
||||
else
|
||||
render_validation_errors(@relation)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
raise Unauthorized unless @relation.deletable?
|
||||
@relation.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@relation.issue_from) }
|
||||
format.js
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_issue
|
||||
@issue = @object = Issue.find(params[:issue_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_relation
|
||||
@relation = IssueRelation.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,81 +1,81 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueStatusesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
accept_api_auth :index
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@issue_statuses = IssueStatus.all(:order => 'position')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@issue_status = IssueStatus.new
|
||||
end
|
||||
|
||||
def create
|
||||
@issue_status = IssueStatus.new(params[:issue_status])
|
||||
if request.post? && @issue_status.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to issue_statuses_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@issue_status = IssueStatus.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@issue_status = IssueStatus.find(params[:id])
|
||||
if request.put? && @issue_status.update_attributes(params[:issue_status])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to issue_statuses_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
IssueStatus.find(params[:id]).destroy
|
||||
redirect_to issue_statuses_url
|
||||
rescue
|
||||
flash[:error] = l(:error_unable_delete_issue_status)
|
||||
redirect_to issue_statuses_url
|
||||
end
|
||||
|
||||
def update_issue_done_ratio
|
||||
if request.post? && IssueStatus.update_issue_done_ratios
|
||||
flash[:notice] = l(:notice_issue_done_ratios_updated)
|
||||
else
|
||||
flash[:error] = l(:error_issue_done_ratios_not_updated)
|
||||
end
|
||||
redirect_to issue_statuses_url
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssueStatusesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
accept_api_auth :index
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@issue_status_pages, @issue_statuses = paginate IssueStatus.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@issue_statuses = IssueStatus.all(:order => 'position')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@issue_status = IssueStatus.new
|
||||
end
|
||||
|
||||
def create
|
||||
@issue_status = IssueStatus.new(params[:issue_status])
|
||||
if request.post? && @issue_status.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to issue_statuses_url
|
||||
else
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@issue_status = IssueStatus.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@issue_status = IssueStatus.find(params[:id])
|
||||
if request.put? && @issue_status.update_attributes(params[:issue_status])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to issue_statuses_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
IssueStatus.find(params[:id]).destroy
|
||||
redirect_to issue_statuses_url
|
||||
rescue
|
||||
flash[:error] = l(:error_unable_delete_issue_status)
|
||||
redirect_to issue_statuses_url
|
||||
end
|
||||
|
||||
def update_issue_done_ratio
|
||||
if request.post? && IssueStatus.update_issue_done_ratios
|
||||
flash[:notice] = l(:notice_issue_done_ratios_updated)
|
||||
else
|
||||
flash[:error] = l(:error_issue_done_ratios_not_updated)
|
||||
end
|
||||
redirect_to issue_statuses_url
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,481 +1,481 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssuesController < ApplicationController
|
||||
layout 'base_projects'#Added by young
|
||||
menu_item :new_issue, :only => [:new, :create]
|
||||
default_search_scope :issues
|
||||
|
||||
before_filter :find_issue, :only => [:show, :edit, :update]
|
||||
before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_filter :find_project, :only => [:new, :create, :update_form]
|
||||
before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_project, :only => [:index]
|
||||
before_filter :check_for_default_issue_status, :only => [:new, :create]
|
||||
before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form]
|
||||
accept_rss_auth :index, :show
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
rescue_from Query::StatementInvalid, :with => :query_statement_invalid
|
||||
|
||||
helper :journals
|
||||
helper :projects
|
||||
include ProjectsHelper
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
helper :issue_relations
|
||||
include IssueRelationsHelper
|
||||
helper :watchers
|
||||
include WatchersHelper
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
helper :repositories
|
||||
include RepositoriesHelper
|
||||
helper :sort
|
||||
include SortHelper
|
||||
include IssuesHelper
|
||||
helper :timelog
|
||||
include Redmine::Export::PDF
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
retrieve_query
|
||||
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns)
|
||||
@query.sort_criteria = sort_criteria.to_a
|
||||
|
||||
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young
|
||||
|
||||
if @query.valid?
|
||||
case params[:format]
|
||||
when 'csv', 'pdf'
|
||||
@limit = 10#Setting.issues_export_limit.to_i
|
||||
when 'atom'
|
||||
@limit = 10#Setting.feeds_limit.to_i
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
else
|
||||
@limit = 10#per_page_option
|
||||
end
|
||||
|
||||
@issue_count = @query.issue_count
|
||||
@issue_pages = Paginator.new @issue_count, @limit, params['page']
|
||||
@offset ||= @issue_pages.offset
|
||||
@issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
|
||||
:order => sort_clause,
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
@issue_count_by_group = @query.issue_count_by_group
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young
|
||||
format.api {
|
||||
Issue.load_visible_relations(@issues) if include_in_api_response?('relations')
|
||||
}
|
||||
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
|
||||
format.csv { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
|
||||
format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young
|
||||
format.any(:atom, :csv, :pdf) { render(:nothing => true) }
|
||||
format.api { render_validation_errors(@query) }
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
@journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all
|
||||
@journals.each_with_index {|j,i| j.indice = i+1}
|
||||
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
|
||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
@changesets = @issue.changesets.visible.all
|
||||
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||
@priorities = IssuePriority.active
|
||||
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
|
||||
|
||||
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young
|
||||
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
retrieve_previous_and_next_issue_ids
|
||||
render :template => 'issues/show', :layout => @project_base_tag#by young
|
||||
}
|
||||
format.api
|
||||
format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
|
||||
format.pdf {
|
||||
pdf = issue_to_pdf(@issue, :journals => @journals)
|
||||
send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Add a new issue
|
||||
# The new issue will be created from an existing one if copy_from parameter is given
|
||||
def new
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new', :layout => 'base_projects' }
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue })
|
||||
@issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
|
||||
if @issue.save
|
||||
call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render_attachment_warning_if_needed(@issue)
|
||||
flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.source_from}", issue_path(@issue), :title => @issue.subject))
|
||||
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
|
||||
if params[:continue]
|
||||
attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?}
|
||||
redirect_to new_project_issue_url(@issue.project, :issue => attrs)
|
||||
else
|
||||
redirect_to issue_url(@issue)
|
||||
end
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) }
|
||||
end
|
||||
return
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new' }
|
||||
format.api { render_validation_errors(@issue) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return unless update_issue_from_params
|
||||
|
||||
respond_to do |format|
|
||||
format.html {render :layout => 'base_projects' }#added by young
|
||||
format.xml { }
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
return unless update_issue_from_params
|
||||
@issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
|
||||
saved = false
|
||||
begin
|
||||
saved = @issue.save_issue_with_child_records(params, @time_entry)
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
@conflict = true
|
||||
if params[:last_journal_id]
|
||||
@conflict_journals = @issue.journals_after(params[:last_journal_id]).all
|
||||
@conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
|
||||
end
|
||||
end
|
||||
|
||||
if saved
|
||||
|
||||
#修改界面增加跟踪者
|
||||
watcherlist = @issue.watcher_users
|
||||
select_users = []
|
||||
if params[:issue]
|
||||
if params[:issue][:watcher_user_ids]
|
||||
params[:issue][:watcher_user_ids].each do |user_id|
|
||||
select_users << User.find(user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
select_users.each do |user|
|
||||
if watcherlist.include? user
|
||||
else
|
||||
@issue.add_watcher user
|
||||
end
|
||||
end
|
||||
watcherlist.each do |user|
|
||||
if select_users.include? user
|
||||
else
|
||||
@issue.remove_watcher user
|
||||
end
|
||||
end
|
||||
|
||||
render_attachment_warning_if_needed(@issue)
|
||||
reply_id = params[:reference_user_id].to_i
|
||||
if reply_id > 0
|
||||
JournalReply.add_reply(@issue.current_journal.id, reply_id, User.current.id)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_default issue_path(@issue) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@issue) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Updates the issue form when changing the project, status or tracker
|
||||
# on issue creation/update
|
||||
def update_form
|
||||
end
|
||||
|
||||
# Bulk edit/copy a set of issues
|
||||
def bulk_edit
|
||||
@issues.sort!
|
||||
@copy = params[:copy].present?
|
||||
@notes = params[:notes]
|
||||
|
||||
if User.current.allowed_to?(:move_issues, @projects)
|
||||
@allowed_projects = Issue.allowed_target_projects_on_move
|
||||
if params[:issue]
|
||||
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s}
|
||||
if @target_project
|
||||
target_projects = [@target_project]
|
||||
end
|
||||
end
|
||||
end
|
||||
target_projects ||= @projects
|
||||
|
||||
if @copy
|
||||
@available_statuses = [IssueStatus.default]
|
||||
else
|
||||
@available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
|
||||
end
|
||||
@custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&)
|
||||
@assignables = target_projects.map(&:assignable_users).reduce(:&)
|
||||
@trackers = target_projects.map(&:trackers).reduce(:&)
|
||||
@versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
|
||||
@categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
|
||||
if @copy
|
||||
@attachments_present = @issues.detect {|i| i.attachments.any?}.present?
|
||||
@subtasks_present = @issues.detect {|i| !i.leaf?}.present?
|
||||
end
|
||||
|
||||
@safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@issues.sort!
|
||||
@copy = params[:copy].present?
|
||||
attributes = parse_params_for_bulk_issue_attributes(params)
|
||||
|
||||
unsaved_issue_ids = []
|
||||
moved_issues = []
|
||||
|
||||
if @copy && params[:copy_subtasks].present?
|
||||
# Descendant issues will be copied with the parent task
|
||||
# Don't copy them twice
|
||||
@issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}}
|
||||
end
|
||||
|
||||
@issues.each do |issue|
|
||||
issue.reload
|
||||
if @copy
|
||||
issue = issue.copy({},
|
||||
:attachments => params[:copy_attachments].present?,
|
||||
:subtasks => params[:copy_subtasks].present?
|
||||
)
|
||||
end
|
||||
journal = issue.init_journal(User.current, params[:notes])
|
||||
issue.safe_attributes = attributes
|
||||
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
|
||||
if issue.save
|
||||
moved_issues << issue
|
||||
else
|
||||
# Keep unsaved issue ids to display them in flash error
|
||||
unsaved_issue_ids << issue.id
|
||||
end
|
||||
end
|
||||
set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
|
||||
|
||||
if params[:follow]
|
||||
if @issues.size == 1 && moved_issues.size == 1
|
||||
redirect_to issue_url(moved_issues.first)
|
||||
elsif moved_issues.map(&:project).uniq.size == 1
|
||||
redirect_to project_issues_url(moved_issues.map(&:project).first)
|
||||
end
|
||||
else
|
||||
redirect_back_or_default _project_issues_path(@project)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
|
||||
if @hours > 0
|
||||
case params[:todo]
|
||||
when 'destroy'
|
||||
# nothing to do
|
||||
when 'nullify'
|
||||
TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
|
||||
when 'reassign'
|
||||
reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
|
||||
if reassign_to.nil?
|
||||
flash.now[:error] = l(:error_issue_not_found_in_project)
|
||||
return
|
||||
else
|
||||
TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
|
||||
end
|
||||
else
|
||||
# display the destroy form if it's a user request
|
||||
return unless api_request?
|
||||
end
|
||||
end
|
||||
@issues.each do |issue|
|
||||
begin
|
||||
issue.reload.destroy
|
||||
rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists
|
||||
# nothing to do, issue was already deleted (eg. by a parent)
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_default _project_issues_path(@project) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id])
|
||||
@project = Project.find(project_id)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def retrieve_previous_and_next_issue_ids
|
||||
retrieve_query_from_session
|
||||
if @query
|
||||
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns, 'issues_index_sort')
|
||||
limit = 500
|
||||
issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version])
|
||||
if (idx = issue_ids.index(@issue.id)) && idx < limit
|
||||
if issue_ids.size < 500
|
||||
@issue_position = idx + 1
|
||||
@issue_count = issue_ids.size
|
||||
end
|
||||
@prev_issue_id = issue_ids[idx - 1] if idx > 0
|
||||
@next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Used by #edit and #update to set some common instance variables
|
||||
# from the params
|
||||
# TODO: Refactor, not everything in here is needed by #edit
|
||||
def update_issue_from_params
|
||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
|
||||
@time_entry.attributes = params[:time_entry]
|
||||
|
||||
@issue.init_journal(User.current)
|
||||
|
||||
issue_attributes = params[:issue]
|
||||
if issue_attributes && params[:conflict_resolution]
|
||||
case params[:conflict_resolution]
|
||||
when 'overwrite'
|
||||
issue_attributes = issue_attributes.dup
|
||||
issue_attributes.delete(:lock_version)
|
||||
when 'add_notes'
|
||||
issue_attributes = issue_attributes.slice(:notes)
|
||||
when 'cancel'
|
||||
redirect_to issue_url(@issue)
|
||||
return false
|
||||
end
|
||||
end
|
||||
@issue.safe_attributes = issue_attributes
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
true
|
||||
end
|
||||
|
||||
# TODO: Refactor, lots of extra code in here
|
||||
# TODO: Changing tracker on an existing issue should not trigger this
|
||||
def build_new_issue_from_params
|
||||
if params[:id].blank?
|
||||
@issue = Issue.new
|
||||
if params[:copy_from]
|
||||
begin
|
||||
@copy_from = Issue.visible.find(params[:copy_from])
|
||||
@copy_attachments = params[:copy_attachments].present? || request.get?
|
||||
@copy_subtasks = params[:copy_subtasks].present? || request.get?
|
||||
@issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
return
|
||||
end
|
||||
end
|
||||
@issue.project = @project
|
||||
else
|
||||
@issue = @project.issues.visible.find(params[:id])
|
||||
end
|
||||
|
||||
@issue.project = @project
|
||||
@issue.author ||= User.current
|
||||
# Tracker must be set before custom field values
|
||||
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
|
||||
if @issue.tracker.nil?
|
||||
render_error l(:error_no_tracker_in_project)
|
||||
return false
|
||||
end
|
||||
@issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
|
||||
@issue.safe_attributes = params[:issue]
|
||||
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
|
||||
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
|
||||
end
|
||||
|
||||
def check_for_default_issue_status
|
||||
if IssueStatus.default.nil?
|
||||
render_error l(:error_no_default_issue_status)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def parse_params_for_bulk_issue_attributes(params)
|
||||
attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
|
||||
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
|
||||
if custom = attributes[:custom_field_values]
|
||||
custom.reject! {|k,v| v.blank?}
|
||||
custom.keys.each do |k|
|
||||
if custom[k].is_a?(Array)
|
||||
custom[k] << '' if custom[k].delete('__none__')
|
||||
else
|
||||
custom[k] = '' if custom[k] == '__none__'
|
||||
end
|
||||
end
|
||||
end
|
||||
attributes
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class IssuesController < ApplicationController
|
||||
layout 'base_projects'#Added by young
|
||||
menu_item :new_issue, :only => [:new, :create]
|
||||
default_search_scope :issues
|
||||
|
||||
before_filter :find_issue, :only => [:show, :edit, :update]
|
||||
before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_filter :find_project, :only => [:new, :create, :update_form]
|
||||
before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_project, :only => [:index]
|
||||
before_filter :check_for_default_issue_status, :only => [:new, :create]
|
||||
before_filter :build_new_issue_from_params, :only => [:new, :create, :update_form]
|
||||
accept_rss_auth :index, :show
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
rescue_from Query::StatementInvalid, :with => :query_statement_invalid
|
||||
|
||||
helper :journals
|
||||
helper :projects
|
||||
include ProjectsHelper
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
helper :issue_relations
|
||||
include IssueRelationsHelper
|
||||
helper :watchers
|
||||
include WatchersHelper
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
helper :repositories
|
||||
include RepositoriesHelper
|
||||
helper :sort
|
||||
include SortHelper
|
||||
include IssuesHelper
|
||||
helper :timelog
|
||||
include Redmine::Export::PDF
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
retrieve_query
|
||||
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns)
|
||||
@query.sort_criteria = sort_criteria.to_a
|
||||
|
||||
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young
|
||||
|
||||
if @query.valid?
|
||||
case params[:format]
|
||||
when 'csv', 'pdf'
|
||||
@limit = 10#Setting.issues_export_limit.to_i
|
||||
when 'atom'
|
||||
@limit = 10#Setting.feeds_limit.to_i
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit({:limit => 10})
|
||||
else
|
||||
@limit = 10#per_page_option
|
||||
end
|
||||
|
||||
@issue_count = @query.issue_count
|
||||
@issue_pages = Paginator.new @issue_count, @limit, params['page']
|
||||
@offset ||= @issue_pages.offset
|
||||
@issues = @query.issues(:include => [:assigned_to, :tracker, :priority, :category, :fixed_version],
|
||||
:order => sort_clause,
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
@issue_count_by_group = @query.issue_count_by_group
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :template => 'issues/index', :layout => @project_base_tag }#by young
|
||||
format.api {
|
||||
Issue.load_visible_relations(@issues) if include_in_api_response?('relations')
|
||||
}
|
||||
format.atom { render_feed(@issues, :title => "#{@project || Setting.app_title}: #{l(:label_issue_plural)}") }
|
||||
format.csv { send_data(query_to_csv(@issues, @query, params), :type => 'text/csv; header=present', :filename => 'issues.csv') }
|
||||
format.pdf { send_data(issues_to_pdf(@issues, @project, @query), :type => 'application/pdf', :filename => 'issues.pdf') }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render(:template => 'issues/index', :layout => @project_base_tag) }#by young
|
||||
format.any(:atom, :csv, :pdf) { render(:nothing => true) }
|
||||
format.api { render_validation_errors(@query) }
|
||||
end
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def show
|
||||
|
||||
@journals = @issue.journals.includes(:user, :details).reorder("#{Journal.table_name}.id ASC").all
|
||||
@journals.each_with_index {|j,i| j.indice = i+1}
|
||||
@journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
|
||||
@journals.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
@changesets = @issue.changesets.visible.all
|
||||
@changesets.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
|
||||
@relations = @issue.relations.select {|r| r.other_issue(@issue) && r.other_issue(@issue).visible? }
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||
@priorities = IssuePriority.active
|
||||
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
|
||||
|
||||
@project_base_tag = (params[:project_id] || @issue.project) ? 'base_projects':'base'#by young
|
||||
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
retrieve_previous_and_next_issue_ids
|
||||
render :template => 'issues/show', :layout => @project_base_tag#by young
|
||||
}
|
||||
format.api
|
||||
format.atom { render :template => 'journals/index', :layout => false, :content_type => 'application/atom+xml' }
|
||||
format.pdf {
|
||||
pdf = issue_to_pdf(@issue, :journals => @journals)
|
||||
send_data(pdf, :type => 'application/pdf', :filename => "#{@project.identifier}-#{@issue.id}.pdf")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Add a new issue
|
||||
# The new issue will be created from an existing one if copy_from parameter is given
|
||||
def new
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new', :layout => 'base_projects' }
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
call_hook(:controller_issues_new_before_save, { :params => params, :issue => @issue })
|
||||
@issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
|
||||
if @issue.save
|
||||
call_hook(:controller_issues_new_after_save, { :params => params, :issue => @issue})
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render_attachment_warning_if_needed(@issue)
|
||||
flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("#{@issue.source_from}", issue_path(@issue), :title => @issue.subject))
|
||||
#flash[:notice] = l(:notice_issue_successful_create, :id => view_context.link_to("##{@issue.id}", issue_path(@issue), :title => @issue.subject))
|
||||
if params[:continue]
|
||||
attrs = {:tracker_id => @issue.tracker, :parent_issue_id => @issue.parent_issue_id}.reject {|k,v| v.nil?}
|
||||
redirect_to new_project_issue_url(@issue.project, :issue => attrs)
|
||||
else
|
||||
redirect_to issue_url(@issue)
|
||||
end
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => issue_url(@issue) }
|
||||
end
|
||||
return
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new' }
|
||||
format.api { render_validation_errors(@issue) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
return unless update_issue_from_params
|
||||
|
||||
respond_to do |format|
|
||||
format.html {render :layout => 'base_projects' }#added by young
|
||||
format.xml { }
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
return unless update_issue_from_params
|
||||
@issue.save_attachments(params[:attachments] || (params[:issue] && params[:issue][:uploads]))
|
||||
saved = false
|
||||
begin
|
||||
saved = @issue.save_issue_with_child_records(params, @time_entry)
|
||||
rescue ActiveRecord::StaleObjectError
|
||||
@conflict = true
|
||||
if params[:last_journal_id]
|
||||
@conflict_journals = @issue.journals_after(params[:last_journal_id]).all
|
||||
@conflict_journals.reject!(&:private_notes?) unless User.current.allowed_to?(:view_private_notes, @issue.project)
|
||||
end
|
||||
end
|
||||
|
||||
if saved
|
||||
|
||||
#修改界面增加跟踪者
|
||||
watcherlist = @issue.watcher_users
|
||||
select_users = []
|
||||
if params[:issue]
|
||||
if params[:issue][:watcher_user_ids]
|
||||
params[:issue][:watcher_user_ids].each do |user_id|
|
||||
select_users << User.find(user_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
select_users.each do |user|
|
||||
if watcherlist.include? user
|
||||
else
|
||||
@issue.add_watcher user
|
||||
end
|
||||
end
|
||||
watcherlist.each do |user|
|
||||
if select_users.include? user
|
||||
else
|
||||
@issue.remove_watcher user
|
||||
end
|
||||
end
|
||||
|
||||
render_attachment_warning_if_needed(@issue)
|
||||
reply_id = params[:reference_user_id].to_i
|
||||
if reply_id > 0
|
||||
JournalReply.add_reply(@issue.current_journal.id, reply_id, User.current.id)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update) unless @issue.current_journal.new_record?
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_default issue_path(@issue) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@issue) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Updates the issue form when changing the project, status or tracker
|
||||
# on issue creation/update
|
||||
def update_form
|
||||
end
|
||||
|
||||
# Bulk edit/copy a set of issues
|
||||
def bulk_edit
|
||||
@issues.sort!
|
||||
@copy = params[:copy].present?
|
||||
@notes = params[:notes]
|
||||
|
||||
if User.current.allowed_to?(:move_issues, @projects)
|
||||
@allowed_projects = Issue.allowed_target_projects_on_move
|
||||
if params[:issue]
|
||||
@target_project = @allowed_projects.detect {|p| p.id.to_s == params[:issue][:project_id].to_s}
|
||||
if @target_project
|
||||
target_projects = [@target_project]
|
||||
end
|
||||
end
|
||||
end
|
||||
target_projects ||= @projects
|
||||
|
||||
if @copy
|
||||
@available_statuses = [IssueStatus.default]
|
||||
else
|
||||
@available_statuses = @issues.map(&:new_statuses_allowed_to).reduce(:&)
|
||||
end
|
||||
@custom_fields = target_projects.map{|p|p.all_issue_custom_fields}.reduce(:&)
|
||||
@assignables = target_projects.map(&:assignable_users).reduce(:&)
|
||||
@trackers = target_projects.map(&:trackers).reduce(:&)
|
||||
@versions = target_projects.map {|p| p.shared_versions.open}.reduce(:&)
|
||||
@categories = target_projects.map {|p| p.issue_categories}.reduce(:&)
|
||||
if @copy
|
||||
@attachments_present = @issues.detect {|i| i.attachments.any?}.present?
|
||||
@subtasks_present = @issues.detect {|i| !i.leaf?}.present?
|
||||
end
|
||||
|
||||
@safe_attributes = @issues.map(&:safe_attribute_names).reduce(:&)
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
@issues.sort!
|
||||
@copy = params[:copy].present?
|
||||
attributes = parse_params_for_bulk_issue_attributes(params)
|
||||
|
||||
unsaved_issue_ids = []
|
||||
moved_issues = []
|
||||
|
||||
if @copy && params[:copy_subtasks].present?
|
||||
# Descendant issues will be copied with the parent task
|
||||
# Don't copy them twice
|
||||
@issues.reject! {|issue| @issues.detect {|other| issue.is_descendant_of?(other)}}
|
||||
end
|
||||
|
||||
@issues.each do |issue|
|
||||
issue.reload
|
||||
if @copy
|
||||
issue = issue.copy({},
|
||||
:attachments => params[:copy_attachments].present?,
|
||||
:subtasks => params[:copy_subtasks].present?
|
||||
)
|
||||
end
|
||||
journal = issue.init_journal(User.current, params[:notes])
|
||||
issue.safe_attributes = attributes
|
||||
call_hook(:controller_issues_bulk_edit_before_save, { :params => params, :issue => issue })
|
||||
if issue.save
|
||||
moved_issues << issue
|
||||
else
|
||||
# Keep unsaved issue ids to display them in flash error
|
||||
unsaved_issue_ids << issue.id
|
||||
end
|
||||
end
|
||||
set_flash_from_bulk_issue_save(@issues, unsaved_issue_ids)
|
||||
|
||||
if params[:follow]
|
||||
if @issues.size == 1 && moved_issues.size == 1
|
||||
redirect_to issue_url(moved_issues.first)
|
||||
elsif moved_issues.map(&:project).uniq.size == 1
|
||||
redirect_to project_issues_url(moved_issues.map(&:project).first)
|
||||
end
|
||||
else
|
||||
redirect_back_or_default _project_issues_path(@project)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@hours = TimeEntry.sum(:hours, :conditions => ['issue_id IN (?)', @issues]).to_f
|
||||
if @hours > 0
|
||||
case params[:todo]
|
||||
when 'destroy'
|
||||
# nothing to do
|
||||
when 'nullify'
|
||||
TimeEntry.update_all('issue_id = NULL', ['issue_id IN (?)', @issues])
|
||||
when 'reassign'
|
||||
reassign_to = @project.issues.find_by_id(params[:reassign_to_id])
|
||||
if reassign_to.nil?
|
||||
flash.now[:error] = l(:error_issue_not_found_in_project)
|
||||
return
|
||||
else
|
||||
TimeEntry.update_all("issue_id = #{reassign_to.id}", ['issue_id IN (?)', @issues])
|
||||
end
|
||||
else
|
||||
# display the destroy form if it's a user request
|
||||
return unless api_request?
|
||||
end
|
||||
end
|
||||
@issues.each do |issue|
|
||||
begin
|
||||
issue.reload.destroy
|
||||
rescue ::ActiveRecord::RecordNotFound # raised by #reload if issue no longer exists
|
||||
# nothing to do, issue was already deleted (eg. by a parent)
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_back_or_default _project_issues_path(@project) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_project
|
||||
project_id = params[:project_id] || (params[:issue] && params[:issue][:project_id])
|
||||
@project = Project.find(project_id)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def retrieve_previous_and_next_issue_ids
|
||||
retrieve_query_from_session
|
||||
if @query
|
||||
sort_init(@query.sort_criteria.empty? ? [['id', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns, 'issues_index_sort')
|
||||
limit = 500
|
||||
issue_ids = @query.issue_ids(:order => sort_clause, :limit => (limit + 1), :include => [:assigned_to, :tracker, :priority, :category, :fixed_version])
|
||||
if (idx = issue_ids.index(@issue.id)) && idx < limit
|
||||
if issue_ids.size < 500
|
||||
@issue_position = idx + 1
|
||||
@issue_count = issue_ids.size
|
||||
end
|
||||
@prev_issue_id = issue_ids[idx - 1] if idx > 0
|
||||
@next_issue_id = issue_ids[idx + 1] if idx < (issue_ids.size - 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Used by #edit and #update to set some common instance variables
|
||||
# from the params
|
||||
# TODO: Refactor, not everything in here is needed by #edit
|
||||
def update_issue_from_params
|
||||
@edit_allowed = User.current.allowed_to?(:edit_issues, @project)
|
||||
@time_entry = TimeEntry.new(:issue => @issue, :project => @issue.project)
|
||||
@time_entry.attributes = params[:time_entry]
|
||||
|
||||
@issue.init_journal(User.current)
|
||||
|
||||
issue_attributes = params[:issue]
|
||||
if issue_attributes && params[:conflict_resolution]
|
||||
case params[:conflict_resolution]
|
||||
when 'overwrite'
|
||||
issue_attributes = issue_attributes.dup
|
||||
issue_attributes.delete(:lock_version)
|
||||
when 'add_notes'
|
||||
issue_attributes = issue_attributes.slice(:notes)
|
||||
when 'cancel'
|
||||
redirect_to issue_url(@issue)
|
||||
return false
|
||||
end
|
||||
end
|
||||
@issue.safe_attributes = issue_attributes
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current)
|
||||
true
|
||||
end
|
||||
|
||||
# TODO: Refactor, lots of extra code in here
|
||||
# TODO: Changing tracker on an existing issue should not trigger this
|
||||
def build_new_issue_from_params
|
||||
if params[:id].blank?
|
||||
@issue = Issue.new
|
||||
if params[:copy_from]
|
||||
begin
|
||||
@copy_from = Issue.visible.find(params[:copy_from])
|
||||
@copy_attachments = params[:copy_attachments].present? || request.get?
|
||||
@copy_subtasks = params[:copy_subtasks].present? || request.get?
|
||||
@issue.copy_from(@copy_from, :attachments => @copy_attachments, :subtasks => @copy_subtasks)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
return
|
||||
end
|
||||
end
|
||||
@issue.project = @project
|
||||
else
|
||||
@issue = @project.issues.visible.find(params[:id])
|
||||
end
|
||||
|
||||
@issue.project = @project
|
||||
@issue.author ||= User.current
|
||||
# Tracker must be set before custom field values
|
||||
@issue.tracker ||= @project.trackers.find((params[:issue] && params[:issue][:tracker_id]) || params[:tracker_id] || :first)
|
||||
if @issue.tracker.nil?
|
||||
render_error l(:error_no_tracker_in_project)
|
||||
return false
|
||||
end
|
||||
@issue.start_date ||= Date.today if Setting.default_issue_start_date_to_creation_date?
|
||||
@issue.safe_attributes = params[:issue]
|
||||
|
||||
@priorities = IssuePriority.active
|
||||
@allowed_statuses = @issue.new_statuses_allowed_to(User.current, true)
|
||||
@available_watchers = (@issue.project.users.sort + @issue.watcher_users).uniq
|
||||
end
|
||||
|
||||
def check_for_default_issue_status
|
||||
if IssueStatus.default.nil?
|
||||
render_error l(:error_no_default_issue_status)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def parse_params_for_bulk_issue_attributes(params)
|
||||
attributes = (params[:issue] || {}).reject {|k,v| v.blank?}
|
||||
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
|
||||
if custom = attributes[:custom_field_values]
|
||||
custom.reject! {|k,v| v.blank?}
|
||||
custom.keys.each do |k|
|
||||
if custom[k].is_a?(Array)
|
||||
custom[k] << '' if custom[k].delete('__none__')
|
||||
else
|
||||
custom[k] = '' if custom[k] == '__none__'
|
||||
end
|
||||
end
|
||||
end
|
||||
attributes
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,117 +1,117 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class JournalsController < ApplicationController
|
||||
before_filter :find_journal, :only => [:edit, :diff, :destroy]
|
||||
before_filter :find_issue, :only => [:new]
|
||||
before_filter :find_optional_project, :only => [:index]
|
||||
before_filter :authorize, :only => [:new, :edit, :diff]
|
||||
accept_rss_auth :index
|
||||
menu_item :issues
|
||||
|
||||
helper :issues
|
||||
helper :custom_fields
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
helper :sort
|
||||
include SortHelper
|
||||
|
||||
def index
|
||||
retrieve_query
|
||||
sort_init 'id', 'desc'
|
||||
sort_update(@query.sortable_columns)
|
||||
|
||||
if @query.valid?
|
||||
@journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC",
|
||||
:limit => 25)
|
||||
end
|
||||
@title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
|
||||
render :layout => false, :content_type => 'application/atom+xml'
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def diff
|
||||
@issue = @journal.issue
|
||||
if params[:detail_id].present?
|
||||
@detail = @journal.details.find_by_id(params[:detail_id])
|
||||
else
|
||||
@detail = @journal.details.detect {|d| d.prop_key == 'description'}
|
||||
end
|
||||
(render_404; return false) unless @issue && @detail
|
||||
@diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value)
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => 'project_base'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@journal = Journal.visible.find(params[:journal_id]) if params[:journal_id]
|
||||
if @journal
|
||||
user = @journal.user
|
||||
text = @journal.notes
|
||||
else
|
||||
user = @issue.author
|
||||
text = @issue.description
|
||||
end
|
||||
# Replaces pre blocks with [...]
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def edit
|
||||
(render_403; return false) unless @journal.editable_by?(User.current)
|
||||
if request.post?
|
||||
@journal.update_attributes(:notes => params[:notes]) if params[:notes]
|
||||
@journal.destroy if @journal.details.empty? && @journal.notes.blank?
|
||||
call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@journal.journalized) }
|
||||
format.js { render :action => 'update' }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
# TODO: implement non-JS journal update
|
||||
render :nothing => true
|
||||
}
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Delete a journals added by young
|
||||
def destroy
|
||||
@journal.destroy
|
||||
redirect_to issue_url(@journal.journalized)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_journal
|
||||
@journal = Journal.visible.find(params[:id])
|
||||
@project = @journal.journalized.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class JournalsController < ApplicationController
|
||||
before_filter :find_journal, :only => [:edit, :diff, :destroy]
|
||||
before_filter :find_issue, :only => [:new]
|
||||
before_filter :find_optional_project, :only => [:index]
|
||||
before_filter :authorize, :only => [:new, :edit, :diff]
|
||||
accept_rss_auth :index
|
||||
menu_item :issues
|
||||
|
||||
helper :issues
|
||||
helper :custom_fields
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
helper :sort
|
||||
include SortHelper
|
||||
|
||||
def index
|
||||
retrieve_query
|
||||
sort_init 'id', 'desc'
|
||||
sort_update(@query.sortable_columns)
|
||||
|
||||
if @query.valid?
|
||||
@journals = @query.journals(:order => "#{Journal.table_name}.created_on DESC",
|
||||
:limit => 25)
|
||||
end
|
||||
@title = (@project ? @project.name : Setting.app_title) + ": " + (@query.new_record? ? l(:label_changes_details) : @query.name)
|
||||
render :layout => false, :content_type => 'application/atom+xml'
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def diff
|
||||
@issue = @journal.issue
|
||||
if params[:detail_id].present?
|
||||
@detail = @journal.details.find_by_id(params[:detail_id])
|
||||
else
|
||||
@detail = @journal.details.detect {|d| d.prop_key == 'description'}
|
||||
end
|
||||
(render_404; return false) unless @issue && @detail
|
||||
@diff = Redmine::Helpers::Diff.new(@detail.value, @detail.old_value)
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => 'project_base'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@journal = Journal.visible.find(params[:journal_id]) if params[:journal_id]
|
||||
if @journal
|
||||
user = @journal.user
|
||||
text = @journal.notes
|
||||
else
|
||||
user = @issue.author
|
||||
text = @issue.description
|
||||
end
|
||||
# Replaces pre blocks with [...]
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def edit
|
||||
(render_403; return false) unless @journal.editable_by?(User.current)
|
||||
if request.post?
|
||||
@journal.update_attributes(:notes => params[:notes]) if params[:notes]
|
||||
@journal.destroy if @journal.details.empty? && @journal.notes.blank?
|
||||
call_hook(:controller_journals_edit_post, { :journal => @journal, :params => params})
|
||||
respond_to do |format|
|
||||
format.html { redirect_to issue_url(@journal.journalized) }
|
||||
format.js { render :action => 'update' }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
# TODO: implement non-JS journal update
|
||||
render :nothing => true
|
||||
}
|
||||
format.js
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Delete a journals added by young
|
||||
def destroy
|
||||
@journal.destroy
|
||||
redirect_to issue_url(@journal.journalized)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_journal
|
||||
@journal = Journal.visible.find(params[:id])
|
||||
@project = @journal.journalized.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,326 +1,326 @@
|
|||
# -*coding:utf-8 -*-
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class MembersController < ApplicationController
|
||||
model_object Member
|
||||
before_filter :find_model_object, :except => [:index, :create, :autocomplete]
|
||||
#before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete]
|
||||
before_filter :find_project_from_association, :except => [:index, :create, :autocomplete]
|
||||
before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete]
|
||||
before_filter :authorize
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
def index
|
||||
@offset, @limit = api_offset_and_limit
|
||||
@member_count = @project.member_principals.count
|
||||
@member_pages = Paginator.new @member_count, @limit, params['page']
|
||||
@offset ||= @member_pages.offset
|
||||
@members = @project.member_principals.all(
|
||||
:order => "#{Member.table_name}.id",
|
||||
:limit => @limit,
|
||||
:offset => @offset
|
||||
)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { head 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html { head 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:refusal_button]
|
||||
members = []
|
||||
applied_members = true
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
AppliedProject.deleteappiled(user_id, @project.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
#modify by nwb
|
||||
#更改课程成员逻辑
|
||||
applied_members = false
|
||||
members = []
|
||||
user_grades = []
|
||||
if @project
|
||||
project_info = []
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id)
|
||||
user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id)
|
||||
## added by nie
|
||||
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) if role.allowed_to?(:is_manager)
|
||||
# ProjectInfo.create(:name => "test", :user_id => 123)
|
||||
end
|
||||
## end
|
||||
end
|
||||
else
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id])
|
||||
user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id)
|
||||
## added by nie
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
## end
|
||||
end
|
||||
@project.members << members
|
||||
# added by nie
|
||||
@project.project_infos << project_info
|
||||
@project.user_grades << user_grades
|
||||
# end
|
||||
end
|
||||
if members.present? && members.all? { |m| m.valid? }
|
||||
members.each do |member|
|
||||
AppliedProject.deleteappiled(member.user_id, @project.id)
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js { @members = members; @applied_members = applied_members; }
|
||||
format.api {
|
||||
@member = members.first
|
||||
if @member.valid?
|
||||
render :action => 'show', :status => :created, :location => membership_url(@member)
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
course_info = []
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
member = Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id)
|
||||
role = Role.find_by_id(params[:membership][:role_ids])
|
||||
# 这里的判断只能通过角色名,可以弄成常量
|
||||
if role.name == "学生"
|
||||
StudentsForCourse.create(:student_id => user_id, :course_id =>@course.id)
|
||||
end
|
||||
members << member
|
||||
#user_grades << UserGrade.new(:user_id => user_id, :course_id => @course.id)
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
course_info << CourseInfo.new(:user_id => user_id, :course_id => @course.id) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
end
|
||||
else
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id])
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
course_info << CourseInfo.new(:course_id => @course.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
end
|
||||
@course.members << members
|
||||
@course.course_infos << course_info
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js { @members = members; @applied_members = applied_members; }
|
||||
format.api {
|
||||
@member = members.first
|
||||
if @member.valid?
|
||||
render :action => 'show', :status => :created, :location => membership_url(@member)
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
end # end of if @project
|
||||
|
||||
end # end of params[:refusal_button]
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
#modify by nwb
|
||||
#增加对课程成员修改的支持
|
||||
if @project
|
||||
if params[:membership]
|
||||
@member.role_ids = params[:membership][:role_ids]
|
||||
|
||||
#added by nie
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
if role.allowed_to?(:is_manager)
|
||||
@projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id)
|
||||
@projectInfo.save
|
||||
else
|
||||
user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
saved = @member.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js
|
||||
format.api {
|
||||
if saved
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
if params[:membership]
|
||||
@member.role_ids = params[:membership][:role_ids]
|
||||
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
# 这里的判断只能通过角色名,可以弄成常量
|
||||
if role.name == "学生"
|
||||
StudentsForCourse.create(:student_id => @member.user_id, :course_id =>@course.id)
|
||||
else
|
||||
joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id)
|
||||
joined.each do |join|
|
||||
join.delete
|
||||
end
|
||||
end
|
||||
if role.allowed_to?(:is_manager)
|
||||
@courseInfo = CourseInfos.new(:user_id => @member.user_id, :course_id => @course.id)
|
||||
@courseInfo.save
|
||||
else
|
||||
user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
saved = @member.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js
|
||||
format.api {
|
||||
if saved
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def destroy
|
||||
#modify by nwb
|
||||
#课程成员删除修改
|
||||
if @project
|
||||
if request.delete? && @member.deletable?
|
||||
@member.destroy
|
||||
# end
|
||||
user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_grade.size > 0
|
||||
user_grade.each do |grade|
|
||||
grade.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js
|
||||
format.api {
|
||||
if @member.destroyed?
|
||||
render_api_ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
if request.delete? && @member.deletable?
|
||||
@member.destroy
|
||||
user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id)
|
||||
joined.each do |join|
|
||||
join.delete
|
||||
end
|
||||
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js
|
||||
format.api {
|
||||
if @member.destroyed?
|
||||
render_api_ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def autocomplete
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'members')
|
||||
end
|
||||
|
||||
def redirect_to_settings_in_courses
|
||||
redirect_to settings_course_url(@course, :tab => 'members')
|
||||
end
|
||||
end
|
||||
# -*coding:utf-8 -*-
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class MembersController < ApplicationController
|
||||
model_object Member
|
||||
before_filter :find_model_object, :except => [:index, :create, :autocomplete]
|
||||
#before_filter :find_model_object_contest, :except => [:index, :create, :autocomplete]
|
||||
before_filter :find_project_from_association, :except => [:index, :create, :autocomplete]
|
||||
before_filter :find_project_by_project_id, :only => [:index, :create, :autocomplete]
|
||||
before_filter :authorize
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
def index
|
||||
@offset, @limit = api_offset_and_limit
|
||||
@member_count = @project.member_principals.count
|
||||
@member_pages = Paginator.new @member_count, @limit, params['page']
|
||||
@offset ||= @member_pages.offset
|
||||
@members = @project.member_principals.all(
|
||||
:order => "#{Member.table_name}.id",
|
||||
:limit => @limit,
|
||||
:offset => @offset
|
||||
)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { head 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.html { head 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
if params[:refusal_button]
|
||||
members = []
|
||||
applied_members = true
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
AppliedProject.deleteappiled(user_id, @project.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
#modify by nwb
|
||||
#更改课程成员逻辑
|
||||
applied_members = false
|
||||
members = []
|
||||
user_grades = []
|
||||
if @project
|
||||
project_info = []
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id)
|
||||
user_grades << UserGrade.new(:user_id => user_id, :project_id => @project.id)
|
||||
## added by nie
|
||||
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
project_info << ProjectInfo.new(:user_id => user_id, :project_id => @project.id) if role.allowed_to?(:is_manager)
|
||||
# ProjectInfo.create(:name => "test", :user_id => 123)
|
||||
end
|
||||
## end
|
||||
end
|
||||
else
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id])
|
||||
user_grades << UserGrade.new(:user_id => params[:membership][:user_id], :project_id => @project.id)
|
||||
## added by nie
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
project_info << ProjectInfo.new(:project_id => @project.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
## end
|
||||
end
|
||||
@project.members << members
|
||||
# added by nie
|
||||
@project.project_infos << project_info
|
||||
@project.user_grades << user_grades
|
||||
# end
|
||||
end
|
||||
if members.present? && members.all? { |m| m.valid? }
|
||||
members.each do |member|
|
||||
AppliedProject.deleteappiled(member.user_id, @project.id)
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js { @members = members; @applied_members = applied_members; }
|
||||
format.api {
|
||||
@member = members.first
|
||||
if @member.valid?
|
||||
render :action => 'show', :status => :created, :location => membership_url(@member)
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
course_info = []
|
||||
if params[:membership]
|
||||
if params[:membership][:user_ids]
|
||||
attrs = params[:membership].dup
|
||||
user_ids = attrs.delete(:user_ids)
|
||||
user_ids.each do |user_id|
|
||||
member = Member.new(:role_ids => params[:membership][:role_ids], :user_id => user_id)
|
||||
role = Role.find_by_id(params[:membership][:role_ids])
|
||||
# 这里的判断只能通过角色名,可以弄成常量
|
||||
if role.name == "学生"
|
||||
StudentsForCourse.create(:student_id => user_id, :course_id =>@course.id)
|
||||
end
|
||||
members << member
|
||||
#user_grades << UserGrade.new(:user_id => user_id, :course_id => @course.id)
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
course_info << CourseInfo.new(:user_id => user_id, :course_id => @course.id) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
end
|
||||
else
|
||||
members << Member.new(:role_ids => params[:membership][:role_ids], :user_id => params[:membership][:user_id])
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
course_info << CourseInfo.new(:course_id => @course.id, :user_id => params[:membership][:user_id]) if role.allowed_to?(:is_manager)
|
||||
end
|
||||
end
|
||||
@course.members << members
|
||||
@course.course_infos << course_info
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js { @members = members; @applied_members = applied_members; }
|
||||
format.api {
|
||||
@member = members.first
|
||||
if @member.valid?
|
||||
render :action => 'show', :status => :created, :location => membership_url(@member)
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
end # end of if @project
|
||||
|
||||
end # end of params[:refusal_button]
|
||||
|
||||
end
|
||||
|
||||
def update
|
||||
#modify by nwb
|
||||
#增加对课程成员修改的支持
|
||||
if @project
|
||||
if params[:membership]
|
||||
@member.role_ids = params[:membership][:role_ids]
|
||||
|
||||
#added by nie
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
if role.allowed_to?(:is_manager)
|
||||
@projectInfo = ProjectInfo.new(:user_id => @member.user_id, :project_id => @project.id)
|
||||
@projectInfo.save
|
||||
else
|
||||
user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
saved = @member.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js
|
||||
format.api {
|
||||
if saved
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
if params[:membership]
|
||||
@member.role_ids = params[:membership][:role_ids]
|
||||
|
||||
if (params[:membership][:role_ids])
|
||||
role = Role.find(params[:membership][:role_ids][0])
|
||||
# 这里的判断只能通过角色名,可以弄成常量
|
||||
if role.name == "学生"
|
||||
StudentsForCourse.create(:student_id => @member.user_id, :course_id =>@course.id)
|
||||
else
|
||||
joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id)
|
||||
joined.each do |join|
|
||||
join.delete
|
||||
end
|
||||
end
|
||||
if role.allowed_to?(:is_manager)
|
||||
@courseInfo = CourseInfos.new(:user_id => @member.user_id, :course_id => @course.id)
|
||||
@courseInfo.save
|
||||
else
|
||||
user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
saved = @member.save
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js
|
||||
format.api {
|
||||
if saved
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@member)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def destroy
|
||||
#modify by nwb
|
||||
#课程成员删除修改
|
||||
if @project
|
||||
if request.delete? && @member.deletable?
|
||||
@member.destroy
|
||||
# end
|
||||
user_admin = ProjectInfo.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
user_grade = UserGrade.where("user_id = ? and project_id = ?", @member.user_id, @project.id)
|
||||
if user_grade.size > 0
|
||||
user_grade.each do |grade|
|
||||
grade.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_projects }
|
||||
format.js
|
||||
format.api {
|
||||
if @member.destroyed?
|
||||
render_api_ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
}
|
||||
end
|
||||
elsif @course
|
||||
if request.delete? && @member.deletable?
|
||||
@member.destroy
|
||||
user_admin = CourseInfos.where("user_id = ? and course_id = ?", @member.user_id, @course.id)
|
||||
if user_admin.size > 0
|
||||
user_admin.each do |user|
|
||||
user.destroy
|
||||
end
|
||||
end
|
||||
joined = StudentsForCourse.where('student_id = ? and course_id = ?', @member.user_id,@course.id)
|
||||
joined.each do |join|
|
||||
join.delete
|
||||
end
|
||||
|
||||
end
|
||||
respond_to do |format|
|
||||
format.html { redirect_to_settings_in_courses }
|
||||
format.js
|
||||
format.api {
|
||||
if @member.destroyed?
|
||||
render_api_ok
|
||||
else
|
||||
head :unprocessable_entity
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def autocomplete
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def redirect_to_settings_in_projects
|
||||
redirect_to settings_project_url(@project, :tab => 'members')
|
||||
end
|
||||
|
||||
def redirect_to_settings_in_courses
|
||||
redirect_to settings_course_url(@course, :tab => 'members')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,207 +1,207 @@
|
|||
class MemosController < ApplicationController
|
||||
default_search_scope :memos
|
||||
before_filter :find_forum, :only => [:new, :create, :preview]
|
||||
before_filter :find_attachments, :only => [:preview]
|
||||
before_filter :find_memo, :except => [:new, :create, :preview]
|
||||
before_filter :authenticate_user_edit, :only => [:edit, :update]
|
||||
before_filter :authenticate_user_destroy, :only => [:destroy]
|
||||
before_filter :require_login, :only => [:new, :create]
|
||||
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
include ApplicationHelper
|
||||
|
||||
layout 'base_memos'
|
||||
|
||||
def quote
|
||||
@subject = @memo.subject
|
||||
@subject = "RE: #{@subject}" unless @subject.starts_with?('RE:')
|
||||
|
||||
@content = "#{ll(Setting.default_language, :text_user_wrote, @memo.author)} <br/> "
|
||||
@content << @memo.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "</blockquote>\n\n<br/>"
|
||||
@content = "<blockquote>" << @content
|
||||
#@content = "> #{ll(Setting.default_language, :text_user_wrote, @memo.author)}\n> "
|
||||
#@content << @memo.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
#@content_html = textilizable(@content)
|
||||
@temp = Memo.new
|
||||
@temp.content = @content
|
||||
end
|
||||
|
||||
def new
|
||||
@memo = Memo.new
|
||||
@memo.forum_id = @forum.id
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render action: :new ,layout: 'base'
|
||||
}
|
||||
format.json { render json: @memo }
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
if params[:quote].nil?
|
||||
@quote = ""
|
||||
else
|
||||
@quote = params[:quote]
|
||||
end
|
||||
|
||||
#unless params[:quote].nil?
|
||||
# @quote = params[:quote][:quote]
|
||||
#end
|
||||
|
||||
@memo = Memo.new(params[:memo])
|
||||
@memo.forum_id = params[:forum_id]
|
||||
@memo.author_id = User.current.id
|
||||
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
@memo.content = @quote + @memo.content
|
||||
respond_to do |format|
|
||||
if @memo.save
|
||||
format.html { redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}" }
|
||||
format.json { render json: @memo, status: :created, location: @memo }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
|
||||
# back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
|
||||
pre_count = REPLIES_PER_PAGE
|
||||
|
||||
@memo_new = @memo.dup
|
||||
@memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示
|
||||
unless @memo.new_record?
|
||||
@memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1))
|
||||
end
|
||||
|
||||
|
||||
page = params[:page]
|
||||
if params[:r] && page.nil?
|
||||
offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count
|
||||
page = 1 + offset / pre_count
|
||||
else
|
||||
|
||||
end
|
||||
@reply_count = @memo.children.count
|
||||
@reply_pages = Paginator.new @reply_count, pre_count, page
|
||||
@replies = @memo.children.
|
||||
includes(:author, :attachments).
|
||||
reorder("#{Memo.table_name}.created_at DESC").
|
||||
limit(@reply_pages.per_page).
|
||||
offset(@reply_pages.offset).
|
||||
all
|
||||
if @memo.new_record?
|
||||
format.html { render :new,:layout=>'base'}
|
||||
else
|
||||
format.html { render action: :show }
|
||||
format.json { render json: @memo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE)
|
||||
def show
|
||||
pre_count = REPLIES_PER_PAGE
|
||||
|
||||
@memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示
|
||||
@memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1))
|
||||
|
||||
page = params[:page]
|
||||
if params[:r] && page.nil?
|
||||
offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count
|
||||
page = 1 + offset / pre_count
|
||||
else
|
||||
|
||||
end
|
||||
@reply_count = @memo.children.count
|
||||
@reply_pages = Paginator.new @reply_count, pre_count, page
|
||||
@replies = @memo.children.
|
||||
includes(:author, :attachments).
|
||||
reorder("#{Memo.table_name}.created_at DESC").
|
||||
limit(@reply_pages.per_page).
|
||||
offset(@reply_pages.offset).
|
||||
all
|
||||
|
||||
@memo_new = Memo.new
|
||||
|
||||
|
||||
# @memo = Memo.find_by_id(params[:id])
|
||||
# @forum = Forum.find(params[:forum_id])
|
||||
# @replies = @memo.replies
|
||||
# @mome_new = Memo.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @memo }
|
||||
format.xml { render xml: @memo }
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@replying = false
|
||||
end
|
||||
|
||||
def update
|
||||
respond_to do |format|
|
||||
if( @memo.update_column(:subject, params[:memo][:subject]) &&
|
||||
@memo.update_column(:content, params[:memo][:content]) &&
|
||||
@memo.update_column(:sticky, params[:memo][:sticky]) &&
|
||||
@memo.update_column(:lock, params[:memo][:lock]))
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
@memo.save
|
||||
# @memo.root.update_attribute(:updated_at, @memo.updated_at)
|
||||
format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"}
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @person.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@memo.destroy
|
||||
|
||||
respond_to do |format|
|
||||
# format.html { redirect_to @back_url }
|
||||
format.html { redirect_to back_memo_or_forum_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_memo
|
||||
return unless find_forum
|
||||
#@memo = @forum.memos.find(params[:id])
|
||||
@memo = Memo.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def find_forum
|
||||
@forum = Forum.find(params[:forum_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def authenticate_user_edit
|
||||
find_memo
|
||||
render_403 unless @memo.editable_by? User.current
|
||||
end
|
||||
|
||||
def authenticate_user_destroy
|
||||
find_memo
|
||||
render_403 unless @memo.destroyable_by? User.current
|
||||
end
|
||||
|
||||
def back_memo_url
|
||||
forum_memo_path(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))
|
||||
end
|
||||
|
||||
def back_memo_or_forum_url
|
||||
@memo.parent_id.nil? ? forum_url(@forum) : forum_memo_url(@forum, @memo.parent_id)
|
||||
end
|
||||
|
||||
end
|
||||
class MemosController < ApplicationController
|
||||
default_search_scope :memos
|
||||
before_filter :find_forum, :only => [:new, :create, :preview]
|
||||
before_filter :find_attachments, :only => [:preview]
|
||||
before_filter :find_memo, :except => [:new, :create, :preview]
|
||||
before_filter :authenticate_user_edit, :only => [:edit, :update]
|
||||
before_filter :authenticate_user_destroy, :only => [:destroy]
|
||||
before_filter :require_login, :only => [:new, :create]
|
||||
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
include ApplicationHelper
|
||||
|
||||
layout 'base_memos'
|
||||
|
||||
def quote
|
||||
@subject = @memo.subject
|
||||
@subject = "RE: #{@subject}" unless @subject.starts_with?('RE:')
|
||||
|
||||
@content = "#{ll(Setting.default_language, :text_user_wrote, @memo.author)} <br/> "
|
||||
@content << @memo.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n") + "</blockquote>\n\n<br/>"
|
||||
@content = "<blockquote>" << @content
|
||||
#@content = "> #{ll(Setting.default_language, :text_user_wrote, @memo.author)}\n> "
|
||||
#@content << @memo.content.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]').gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
#@content_html = textilizable(@content)
|
||||
@temp = Memo.new
|
||||
@temp.content = @content
|
||||
end
|
||||
|
||||
def new
|
||||
@memo = Memo.new
|
||||
@memo.forum_id = @forum.id
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render action: :new ,layout: 'base'
|
||||
}
|
||||
format.json { render json: @memo }
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
if params[:quote].nil?
|
||||
@quote = ""
|
||||
else
|
||||
@quote = params[:quote]
|
||||
end
|
||||
|
||||
#unless params[:quote].nil?
|
||||
# @quote = params[:quote][:quote]
|
||||
#end
|
||||
|
||||
@memo = Memo.new(params[:memo])
|
||||
@memo.forum_id = params[:forum_id]
|
||||
@memo.author_id = User.current.id
|
||||
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
@memo.content = @quote + @memo.content
|
||||
respond_to do |format|
|
||||
if @memo.save
|
||||
format.html { redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}" }
|
||||
format.json { render json: @memo, status: :created, location: @memo }
|
||||
else
|
||||
flash.now[:error] = "#{l :label_memo_create_fail}: #{@memo.errors.full_messages[0]}"
|
||||
# back_error_page = @memo.parent_id.nil? ? forum_path(@forum) : forum_memo_path(@forum, @memo.parent_id)
|
||||
pre_count = REPLIES_PER_PAGE
|
||||
|
||||
@memo_new = @memo.dup
|
||||
@memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示
|
||||
unless @memo.new_record?
|
||||
@memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1))
|
||||
end
|
||||
|
||||
|
||||
page = params[:page]
|
||||
if params[:r] && page.nil?
|
||||
offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count
|
||||
page = 1 + offset / pre_count
|
||||
else
|
||||
|
||||
end
|
||||
@reply_count = @memo.children.count
|
||||
@reply_pages = Paginator.new @reply_count, pre_count, page
|
||||
@replies = @memo.children.
|
||||
includes(:author, :attachments).
|
||||
reorder("#{Memo.table_name}.created_at DESC").
|
||||
limit(@reply_pages.per_page).
|
||||
offset(@reply_pages.offset).
|
||||
all
|
||||
if @memo.new_record?
|
||||
format.html { render :new,:layout=>'base'}
|
||||
else
|
||||
format.html { render action: :show }
|
||||
format.json { render json: @memo.errors, status: :unprocessable_entity }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
REPLIES_PER_PAGE = 20 unless const_defined?(:REPLIES_PER_PAGE)
|
||||
def show
|
||||
pre_count = REPLIES_PER_PAGE
|
||||
|
||||
@memo = @memo.root # 取出楼主,防止输入帖子id让回复作为主贴显示
|
||||
@memo.update_column(:viewed_count, (@memo.viewed_count.to_i + 1))
|
||||
|
||||
page = params[:page]
|
||||
if params[:r] && page.nil?
|
||||
offset = @memo.children.where("#{Memo.table_name}.id < ?", params[:r].to_i).count
|
||||
page = 1 + offset / pre_count
|
||||
else
|
||||
|
||||
end
|
||||
@reply_count = @memo.children.count
|
||||
@reply_pages = Paginator.new @reply_count, pre_count, page
|
||||
@replies = @memo.children.
|
||||
includes(:author, :attachments).
|
||||
reorder("#{Memo.table_name}.created_at DESC").
|
||||
limit(@reply_pages.per_page).
|
||||
offset(@reply_pages.offset).
|
||||
all
|
||||
|
||||
@memo_new = Memo.new
|
||||
|
||||
|
||||
# @memo = Memo.find_by_id(params[:id])
|
||||
# @forum = Forum.find(params[:forum_id])
|
||||
# @replies = @memo.replies
|
||||
# @mome_new = Memo.new
|
||||
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @memo }
|
||||
format.xml { render xml: @memo }
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@replying = false
|
||||
end
|
||||
|
||||
def update
|
||||
respond_to do |format|
|
||||
if( @memo.update_column(:subject, params[:memo][:subject]) &&
|
||||
@memo.update_column(:content, params[:memo][:content]) &&
|
||||
@memo.update_column(:sticky, params[:memo][:sticky]) &&
|
||||
@memo.update_column(:lock, params[:memo][:lock]))
|
||||
@memo.save_attachments(params[:attachments] || (params[:memo] && params[:memo][:uploads]))
|
||||
@memo.save
|
||||
# @memo.root.update_attribute(:updated_at, @memo.updated_at)
|
||||
format.html {redirect_to back_memo_url, notice: "#{l :label_memo_create_succ}"}
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @person.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@memo.destroy
|
||||
|
||||
respond_to do |format|
|
||||
# format.html { redirect_to @back_url }
|
||||
format.html { redirect_to back_memo_or_forum_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_memo
|
||||
return unless find_forum
|
||||
#@memo = @forum.memos.find(params[:id])
|
||||
@memo = Memo.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def find_forum
|
||||
@forum = Forum.find(params[:forum_id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
nil
|
||||
end
|
||||
|
||||
def authenticate_user_edit
|
||||
find_memo
|
||||
render_403 unless @memo.editable_by? User.current
|
||||
end
|
||||
|
||||
def authenticate_user_destroy
|
||||
find_memo
|
||||
render_403 unless @memo.destroyable_by? User.current
|
||||
end
|
||||
|
||||
def back_memo_url
|
||||
forum_memo_path(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))
|
||||
end
|
||||
|
||||
def back_memo_or_forum_url
|
||||
@memo.parent_id.nil? ? forum_url(@forum) : forum_memo_url(@forum, @memo.parent_id)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,3 +1,287 @@
|
|||
<<<<<<< HEAD
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#+
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class MyController < ApplicationController
|
||||
layout "users_base"
|
||||
before_filter :require_login
|
||||
|
||||
helper :issues
|
||||
helper :users
|
||||
helper :custom_fields
|
||||
|
||||
BLOCKS = { 'issuesassignedtome' => :label_assigned_to_me_issues,
|
||||
'issuesreportedbyme' => :label_reported_issues,
|
||||
'issueswatched' => :label_watched_issues,
|
||||
'news' => :label_news_latest,
|
||||
'calendar' => :label_calendar,
|
||||
'documents' => :label_document_plural,
|
||||
'timelog' => :label_spent_time
|
||||
}.merge(Redmine::Views::MyPage::Block.additional_blocks).freeze
|
||||
|
||||
DEFAULT_LAYOUT = { 'left' => ['issuesassignedtome'],
|
||||
'right' => ['issuesreportedbyme']
|
||||
}.freeze
|
||||
|
||||
def index
|
||||
|
||||
page
|
||||
render :action => 'page'
|
||||
end
|
||||
|
||||
# Show user's page
|
||||
def page
|
||||
@user = User.current
|
||||
@Issues= Issue.visible.open.
|
||||
where(:assigned_to_id => ([User.current.id] + User.current.group_ids))
|
||||
@limit = 10
|
||||
@feedback_count = @Issues.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@curse_attachments = @Issues[@offset, @limit]
|
||||
|
||||
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
|
||||
end
|
||||
|
||||
def page2
|
||||
@limit = 10
|
||||
@user = User.current
|
||||
@Issues= Issue.visible.open.
|
||||
where(:assigned_to_id => ([User.current.id] + User.current.group_ids))
|
||||
@feedback_count = @Issues.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@curse_attachments = @Issues[@offset, @limit]
|
||||
@state = false
|
||||
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
# Edit user's account
|
||||
def account
|
||||
@user = User.current
|
||||
lg=@user.login
|
||||
@pref = @user.pref
|
||||
diskfile = disk_filename('User', @user.id)
|
||||
diskfile1 = diskfile + 'temp'
|
||||
if request.post?
|
||||
@user.safe_attributes = params[:user]
|
||||
@user.pref.attributes = params[:pref]
|
||||
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
|
||||
@user.login = params[:login]
|
||||
unless @user.user_extensions.nil?
|
||||
if @user.user_extensions.identity == 2
|
||||
@user.firstname = params[:enterprise_name]
|
||||
end
|
||||
end
|
||||
|
||||
@se = @user.extensions
|
||||
@se.school_id = params[:occupation] if params[:occupation]
|
||||
@se.gender = params[:gender]
|
||||
@se.location = params[:province] if params[:province]
|
||||
@se.location_city = params[:city] if params[:city]
|
||||
@se.identity = params[:identity].to_i if params[:identity]
|
||||
@se.technical_title = params[:technical_title] if params[:technical_title]
|
||||
@se.student_id = params[:no] if params[:no]
|
||||
|
||||
if @user.save && @se.save
|
||||
# 头像保存
|
||||
if File.exist?(diskfile1)
|
||||
if File.exist?(diskfile)
|
||||
File.delete(diskfile)
|
||||
end
|
||||
File.open(diskfile1, "rb") do |f|
|
||||
buffer = f.read(10)
|
||||
if buffer != "DELETE"
|
||||
File.open(diskfile1, "rb") do |f1|
|
||||
File.open(diskfile, "wb") do |f|
|
||||
buffer = ""
|
||||
while (buffer = f1.read(8192))
|
||||
f.write(buffer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# File.rename(diskfile + 'temp',diskfile);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# 确保文件被删除
|
||||
if File.exist?(diskfile1)
|
||||
File.delete(diskfile1)
|
||||
end
|
||||
|
||||
@user.pref.save
|
||||
@user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
|
||||
set_language_if_valid @user.language
|
||||
flash.now[:notice] = l(:notice_account_updated)
|
||||
redirect_to user_url(@user)
|
||||
return
|
||||
else
|
||||
# 确保文件被删除
|
||||
if File.exist?(diskfile1)
|
||||
File.delete(diskfile1)
|
||||
end
|
||||
@user.login = lg
|
||||
end
|
||||
else
|
||||
# 确保文件被删除
|
||||
if File.exist?(diskfile1)
|
||||
File.delete(diskfile1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Destroys user's account
|
||||
def destroy
|
||||
@user = User.current
|
||||
unless @user.own_account_deletable?
|
||||
redirect_to my_account_url
|
||||
return
|
||||
end
|
||||
|
||||
if request.post? && params[:confirm]
|
||||
@user.destroy
|
||||
if @user.destroyed?
|
||||
logout_user
|
||||
flash.now[:notice] = l(:notice_account_deleted)
|
||||
end
|
||||
redirect_to home_url
|
||||
end
|
||||
end
|
||||
|
||||
# Manage user's password
|
||||
def password
|
||||
@user = User.current
|
||||
unless @user.change_password_allowed?
|
||||
flash.now[:error] = l(:notice_can_t_change_password)
|
||||
redirect_to my_account_url
|
||||
return
|
||||
end
|
||||
if request.post?
|
||||
if @user.check_password?(params[:password])
|
||||
@user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
|
||||
|
||||
if @user.save
|
||||
flash.now[:notice] = l(:notice_account_password_updated)
|
||||
redirect_to my_account_url
|
||||
end
|
||||
else
|
||||
flash.now[:error] = l(:notice_account_wrong_password)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Create a new feeds key
|
||||
def reset_rss_key
|
||||
if request.post?
|
||||
if User.current.rss_token
|
||||
User.current.rss_token.destroy
|
||||
User.current.reload
|
||||
end
|
||||
User.current.rss_key
|
||||
flash[:notice] = l(:notice_feeds_access_key_reseted)
|
||||
end
|
||||
redirect_to my_account_url
|
||||
end
|
||||
|
||||
# Create a new API key
|
||||
def reset_api_key
|
||||
if request.post?
|
||||
if User.current.api_token
|
||||
User.current.api_token.destroy
|
||||
User.current.reload
|
||||
end
|
||||
User.current.api_key
|
||||
flash[:notice] = l(:notice_api_access_key_reseted)
|
||||
end
|
||||
redirect_to my_account_url
|
||||
end
|
||||
|
||||
# User's page layout configuration
|
||||
def page_layout
|
||||
@user = User.current
|
||||
@blocks = @user.pref[:my_page_layout] || DEFAULT_LAYOUT.dup
|
||||
@block_options = []
|
||||
BLOCKS.each do |k, v|
|
||||
unless %w(top left right).detect {|f| (@blocks[f] ||= []).include?(k)}
|
||||
@block_options << [l("my.blocks.#{v}", :default => [v, v.to_s.humanize]), k.dasherize]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Add a block to user's page
|
||||
# The block is added on top of the page
|
||||
# params[:block] : id of the block to add
|
||||
def add_block
|
||||
block = params[:block].to_s.underscore
|
||||
if block.present? && BLOCKS.key?(block)
|
||||
@user = User.current
|
||||
layout = @user.pref[:my_page_layout] || {}
|
||||
# remove if already present in a group
|
||||
%w(top left right).each {|f| (layout[f] ||= []).delete block }
|
||||
# add it on top
|
||||
layout['top'].unshift block
|
||||
@user.pref[:my_page_layout] = layout
|
||||
@user.pref.save
|
||||
end
|
||||
redirect_to my_page_layout_url
|
||||
end
|
||||
|
||||
# Remove a block to user's page
|
||||
# params[:block] : id of the block to remove
|
||||
def remove_block
|
||||
block = params[:block].to_s.underscore
|
||||
@user = User.current
|
||||
# remove block in all groups
|
||||
layout = @user.pref[:my_page_layout] || {}
|
||||
%w(top left right).each {|f| (layout[f] ||= []).delete block }
|
||||
@user.pref[:my_page_layout] = layout
|
||||
@user.pref.save
|
||||
redirect_to my_page_layout_url
|
||||
end
|
||||
|
||||
# Change blocks order on user's page
|
||||
# params[:group] : group to order (top, left or right)
|
||||
# params[:list-(top|left|right)] : array of block ids of the group
|
||||
def order_blocks
|
||||
group = params[:group]
|
||||
@user = User.current
|
||||
if group.is_a?(String)
|
||||
group_items = (params["blocks"] || []).collect(&:underscore)
|
||||
group_items.each {|s| s.sub!(/^block_/, '')}
|
||||
if group_items and group_items.is_a? Array
|
||||
layout = @user.pref[:my_page_layout] || {}
|
||||
# remove group blocks if they are presents in other groups
|
||||
%w(top left right).each {|f|
|
||||
layout[f] = (layout[f] || []) - group_items
|
||||
}
|
||||
layout[group] = group_items
|
||||
@user.pref[:my_page_layout] = layout
|
||||
@user.pref.save
|
||||
end
|
||||
end
|
||||
render :nothing => true
|
||||
end
|
||||
end
|
||||
=======
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
|
@ -130,7 +414,7 @@ class MyController < ApplicationController
|
|||
@user.pref.save
|
||||
@user.notified_project_ids = (@user.mail_notification == 'selected' ? params[:notified_project_ids] : [])
|
||||
set_language_if_valid @user.language
|
||||
flash.now[:notice] = l(:notice_account_updated)
|
||||
flash[:notice] = l(:notice_account_updated)
|
||||
redirect_to user_url(@user)
|
||||
return
|
||||
else
|
||||
|
@ -280,3 +564,4 @@ class MyController < ApplicationController
|
|||
render :nothing => true
|
||||
end
|
||||
end
|
||||
>>>>>>> d2f4b38eb6fd68a67940b8ffe735d8f7437acde1
|
||||
|
|
|
@ -1,176 +1,176 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class NewsController < ApplicationController
|
||||
layout 'base_projects'# by young
|
||||
default_search_scope :news
|
||||
model_object News
|
||||
before_filter :find_model_object, :except => [:new, :create, :index]
|
||||
before_filter :find_project_from_association, :except => [:new, :create, :index]
|
||||
before_filter :find_project_by_project_id, :only => [:new, :create]
|
||||
before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_project, :only => :index
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index
|
||||
|
||||
helper :watchers
|
||||
helper :attachments
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = 10
|
||||
end
|
||||
|
||||
# modify by nwb
|
||||
if params[:course_id] && @course==nil
|
||||
@course = Course.find(params[:course_id])
|
||||
end
|
||||
if @project
|
||||
scope = @project ? @project.news.visible : News.visible
|
||||
|
||||
@news_count = scope.count
|
||||
@news_pages = Paginator.new @news_count, @limit, params['page']
|
||||
@offset ||= @news_pages.offset
|
||||
@newss = scope.all(:include => [:author, :project],
|
||||
:order => "#{News.table_name}.created_on DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@news = News.new # for adding news inline
|
||||
# huang
|
||||
|
||||
render :layout => false if request.xhr?
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
|
||||
end
|
||||
elsif @course
|
||||
scope = @course ? @course.news.course_visible : News.course_visible
|
||||
|
||||
@news_count = scope.count
|
||||
@news_pages = Paginator.new @news_count, @limit, params['page']
|
||||
@offset ||= @news_pages.offset
|
||||
@newss = scope.all(:include => [:author, :course],
|
||||
:order => "#{News.table_name}.created_on DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@news = News.new
|
||||
render :layout => 'base_courses'
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@comments = @news.comments
|
||||
@comments.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
#modify by nwb
|
||||
if @news.course_id
|
||||
@course = Course.find(@news.course_id)
|
||||
if @course
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
#modify by nwb
|
||||
if @project
|
||||
@news = News.new(:project => @project, :author => User.current)
|
||||
elsif @course
|
||||
@news = News.new(:course => @course, :author => User.current)
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
#modify by nwb
|
||||
if @project
|
||||
@news = News.new(:project => @project, :author => User.current)
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to project_news_index_url(@project)
|
||||
else
|
||||
layout_file = @project ? 'base_projects' : 'base_courses'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
elsif @course
|
||||
@news = News.new(:course => @course, :author => User.current)
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to course_news_index_url(@course)
|
||||
else
|
||||
layout_file = 'base_courses'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to news_url(@news)
|
||||
else
|
||||
#flash[:error] = l(:notice_successful_update)
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@news.destroy
|
||||
# modify by nwb
|
||||
if @project
|
||||
redirect_to project_news_index_url(@project)
|
||||
elsif @course
|
||||
redirect_to course_news_index_url(@course)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_optional_project
|
||||
return true unless params[:project_id]
|
||||
@project = Project.find(params[:project_id])
|
||||
authorize
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class NewsController < ApplicationController
|
||||
layout 'base_projects'# by young
|
||||
default_search_scope :news
|
||||
model_object News
|
||||
before_filter :find_model_object, :except => [:new, :create, :index]
|
||||
before_filter :find_project_from_association, :except => [:new, :create, :index]
|
||||
before_filter :find_project_by_project_id, :only => [:new, :create]
|
||||
before_filter :authorize, :except => [:index]
|
||||
before_filter :find_optional_project, :only => :index
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index
|
||||
|
||||
helper :watchers
|
||||
helper :attachments
|
||||
helper :project_score
|
||||
|
||||
def index
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = 10
|
||||
end
|
||||
|
||||
# modify by nwb
|
||||
if params[:course_id] && @course==nil
|
||||
@course = Course.find(params[:course_id])
|
||||
end
|
||||
if @project
|
||||
scope = @project ? @project.news.visible : News.visible
|
||||
|
||||
@news_count = scope.count
|
||||
@news_pages = Paginator.new @news_count, @limit, params['page']
|
||||
@offset ||= @news_pages.offset
|
||||
@newss = scope.all(:include => [:author, :project],
|
||||
:order => "#{News.table_name}.created_on DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@news = News.new # for adding news inline
|
||||
# huang
|
||||
|
||||
render :layout => false if request.xhr?
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@newss, :title => (@project ? @project.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
|
||||
end
|
||||
elsif @course
|
||||
scope = @course ? @course.news.course_visible : News.course_visible
|
||||
|
||||
@news_count = scope.count
|
||||
@news_pages = Paginator.new @news_count, @limit, params['page']
|
||||
@offset ||= @news_pages.offset
|
||||
@newss = scope.all(:include => [:author, :course],
|
||||
:order => "#{News.table_name}.created_on DESC",
|
||||
:offset => @offset,
|
||||
:limit => @limit)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@news = News.new
|
||||
render :layout => 'base_courses'
|
||||
}
|
||||
format.api
|
||||
format.atom { render_feed(@newss, :title => (@course ? @course.name : Setting.app_title) + ": #{l(:label_news_plural)}") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
@comments = @news.comments
|
||||
@comments.reverse! if User.current.wants_comments_in_reverse_order?
|
||||
#modify by nwb
|
||||
if @news.course_id
|
||||
@course = Course.find(@news.course_id)
|
||||
if @course
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
#modify by nwb
|
||||
if @project
|
||||
@news = News.new(:project => @project, :author => User.current)
|
||||
elsif @course
|
||||
@news = News.new(:course => @course, :author => User.current)
|
||||
render :layout => 'base_courses'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
#modify by nwb
|
||||
if @project
|
||||
@news = News.new(:project => @project, :author => User.current)
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to project_news_index_url(@project)
|
||||
else
|
||||
layout_file = @project ? 'base_projects' : 'base_courses'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
elsif @course
|
||||
@news = News.new(:course => @course, :author => User.current)
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to course_news_index_url(@course)
|
||||
else
|
||||
layout_file = 'base_courses'
|
||||
render :action => 'new', :layout => layout_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@news.safe_attributes = params[:news]
|
||||
@news.save_attachments(params[:attachments])
|
||||
if @news.save
|
||||
render_attachment_warning_if_needed(@news)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to news_url(@news)
|
||||
else
|
||||
#flash[:error] = l(:notice_successful_update)
|
||||
redirect_to news_url(@news)
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@news.destroy
|
||||
# modify by nwb
|
||||
if @project
|
||||
redirect_to project_news_index_url(@project)
|
||||
elsif @course
|
||||
redirect_to course_news_index_url(@course)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_optional_project
|
||||
return true unless params[:project_id]
|
||||
@project = Project.find(params[:project_id])
|
||||
authorize
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
class NotificationcommentsController < ApplicationController
|
||||
def show
|
||||
|
||||
end
|
||||
# default_search_scope :contestnotifications
|
||||
# model_object Contestnotifications
|
||||
# before_filter :authorize
|
||||
|
||||
def create
|
||||
#raise Unauthorized unless @contestnotifications.notificationcommentable?
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
@contestnotification = Contestnotification.find(params[:contestnotification_id])
|
||||
|
||||
# @notificaioncomment = Notificationcomment.new
|
||||
# @notificaioncomment.safe_attributes = params[:notificationcomment]
|
||||
# @notificaioncomment.author = User.current
|
||||
comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id))
|
||||
if comment.save
|
||||
flash[:notice] = l(:label_comment_added)
|
||||
end
|
||||
|
||||
redirect_to contest_contestnotification_url(@contest, @contestnotification)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
@contestnotification = Contestnotification.find(params[:contestnotification_id])
|
||||
notificaioncomments = Notificationcomment.find(params[:id])
|
||||
notificaioncomments.destroy if notificaioncomments
|
||||
#@contestnotifications = notificaioncomments.Contestnotification
|
||||
#@contest = @contestnotifications.contest
|
||||
#@contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy
|
||||
redirect_to contest_contestnotification_url(@contest,@contestnotification)
|
||||
end
|
||||
|
||||
end
|
||||
class NotificationcommentsController < ApplicationController
|
||||
def show
|
||||
|
||||
end
|
||||
# default_search_scope :contestnotifications
|
||||
# model_object Contestnotifications
|
||||
# before_filter :authorize
|
||||
|
||||
def create
|
||||
#raise Unauthorized unless @contestnotifications.notificationcommentable?
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
@contestnotification = Contestnotification.find(params[:contestnotification_id])
|
||||
|
||||
# @notificaioncomment = Notificationcomment.new
|
||||
# @notificaioncomment.safe_attributes = params[:notificationcomment]
|
||||
# @notificaioncomment.author = User.current
|
||||
comment = @contestnotification.notificationcomments.new(params[:notificationcomment].merge(author_id: User.current.id))
|
||||
if comment.save
|
||||
flash[:notice] = l(:label_comment_added)
|
||||
end
|
||||
|
||||
redirect_to contest_contestnotification_url(@contest, @contestnotification)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@contest = Contest.find(params[:contest_id])
|
||||
@contestnotification = Contestnotification.find(params[:contestnotification_id])
|
||||
notificaioncomments = Notificationcomment.find(params[:id])
|
||||
notificaioncomments.destroy if notificaioncomments
|
||||
#@contestnotifications = notificaioncomments.Contestnotification
|
||||
#@contest = @contestnotifications.contest
|
||||
#@contestnotifications.notificaioncomments.find(params[:notificaioncomment_id]).destroy
|
||||
redirect_to contest_contestnotification_url(@contest,@contestnotification)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,262 +1,262 @@
|
|||
class OpenSourceProjectsController < ApplicationController
|
||||
|
||||
before_filter :find_osp, :only => [:master_apply, :accept_master_apply, :refuse_master_apply]
|
||||
before_filter :require_master, :only => [:master_apply, :accept_master_apply, :refuse_master_apply]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :apply_project_masters
|
||||
include ApplyProjectMastersHelper
|
||||
helper :no_uses
|
||||
include NoUsesHelper
|
||||
# GET /open_source_projects
|
||||
# GET /open_source_projects.json
|
||||
def index
|
||||
|
||||
@app_dir = params[:app_dir]
|
||||
@language = params[:language]
|
||||
@created_at = params[:created_at]
|
||||
per_page_option = 10
|
||||
|
||||
@open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at)
|
||||
@open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present?
|
||||
|
||||
@os_project_count = @open_source_projects.count
|
||||
@os_project_pages = Paginator.new @os_project_count, per_page_option, params['page']
|
||||
|
||||
@open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page)
|
||||
|
||||
@bugs = BugToOsp.order('created_at desc').limit(8)
|
||||
|
||||
# @open_source_projects = OpenSourceProject.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @open_source_projects }
|
||||
end
|
||||
end
|
||||
|
||||
def master_apply
|
||||
@apply = @open_source_project.apply_tips
|
||||
@applicants = @open_source_project.applicants
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
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, 10, 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
|
||||
|
||||
@bugs = @open_source_project.bugs.limit(6)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
def allbug
|
||||
@bugs = BugToOsp.visible
|
||||
|
||||
@bug_count = @bugs.count
|
||||
@bug_pages = Paginator.new @bug_count, per_page_option, params['page']
|
||||
@bugs = @bugs.includes(:bug).reorder("#{RelativeMemo.table_name}.created_at DESC").limit(@bug_pages.per_page).offset(@bug_pages.offset).all
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
|
||||
end
|
||||
|
||||
def showbug
|
||||
@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.bugs.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @open_source_project.bugs.
|
||||
reorder("#{RelativeMemo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
all
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
# added by yiang 暴力添加,请绕道
|
||||
def showmemo
|
||||
@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
|
||||
|
||||
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
|
||||
|
||||
def remove_condition
|
||||
@app_dir = params[:app_dir]
|
||||
@language = params[:language]
|
||||
@created_at = params[:created_at]
|
||||
redirect_to open_source_projects_url(:app_dir => @app_dir, :language => @language, :created_at => @created_at, :name => params[:name])
|
||||
end
|
||||
|
||||
def search
|
||||
# per_page_option = 10
|
||||
#
|
||||
# @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at)
|
||||
# @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present?
|
||||
#
|
||||
# @os_project_count = @open_source_projects.count
|
||||
# @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page']
|
||||
#
|
||||
# @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page)
|
||||
|
||||
redirect_to open_source_projects_url(:name => params[:name])
|
||||
|
||||
end
|
||||
|
||||
def refuse_master_apply
|
||||
@apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id)
|
||||
@apply.first.destory
|
||||
|
||||
redirect_to master_apply_open_source_project_url
|
||||
end
|
||||
|
||||
def accept_master_apply
|
||||
@apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id)
|
||||
if @apply.count == 1
|
||||
@apply.first.update_attributes(:status => 2)
|
||||
end
|
||||
|
||||
redirect_to master_apply_open_source_project_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_master
|
||||
render_403 unless @open_source_project.admin?(User.current)
|
||||
end
|
||||
|
||||
def find_osp
|
||||
@open_source_project = OpenSourceProject.find(params[:id])
|
||||
render_404 unless @open_source_project.present?
|
||||
end
|
||||
end
|
||||
class OpenSourceProjectsController < ApplicationController
|
||||
|
||||
before_filter :find_osp, :only => [:master_apply, :accept_master_apply, :refuse_master_apply]
|
||||
before_filter :require_master, :only => [:master_apply, :accept_master_apply, :refuse_master_apply]
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :apply_project_masters
|
||||
include ApplyProjectMastersHelper
|
||||
helper :no_uses
|
||||
include NoUsesHelper
|
||||
# GET /open_source_projects
|
||||
# GET /open_source_projects.json
|
||||
def index
|
||||
|
||||
@app_dir = params[:app_dir]
|
||||
@language = params[:language]
|
||||
@created_at = params[:created_at]
|
||||
per_page_option = 10
|
||||
|
||||
@open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at)
|
||||
@open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present?
|
||||
|
||||
@os_project_count = @open_source_projects.count
|
||||
@os_project_pages = Paginator.new @os_project_count, per_page_option, params['page']
|
||||
|
||||
@open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page)
|
||||
|
||||
@bugs = BugToOsp.order('created_at desc').limit(8)
|
||||
|
||||
# @open_source_projects = OpenSourceProject.all
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @open_source_projects }
|
||||
end
|
||||
end
|
||||
|
||||
def master_apply
|
||||
@apply = @open_source_project.apply_tips
|
||||
@applicants = @open_source_project.applicants
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
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, 10, 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
|
||||
|
||||
@bugs = @open_source_project.bugs.limit(6)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
def allbug
|
||||
@bugs = BugToOsp.visible
|
||||
|
||||
@bug_count = @bugs.count
|
||||
@bug_pages = Paginator.new @bug_count, per_page_option, params['page']
|
||||
@bugs = @bugs.includes(:bug).reorder("#{RelativeMemo.table_name}.created_at DESC").limit(@bug_pages.per_page).offset(@bug_pages.offset).all
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
|
||||
end
|
||||
|
||||
def showbug
|
||||
@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.bugs.count
|
||||
@topic_pages = Paginator.new @topic_count, per_page_option, params['page']
|
||||
@memos = @open_source_project.bugs.
|
||||
reorder("#{RelativeMemo.table_name}.sticky DESC").
|
||||
includes(:last_reply).
|
||||
limit(@topic_pages.per_page).
|
||||
offset(@topic_pages.offset).
|
||||
order(sort_clause).
|
||||
all
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
render :layout => "base_opensource_p"
|
||||
}
|
||||
format.json { render json: @open_source_project }
|
||||
end
|
||||
end
|
||||
|
||||
# added by yiang 暴力添加,请绕道
|
||||
def showmemo
|
||||
@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
|
||||
|
||||
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
|
||||
|
||||
def remove_condition
|
||||
@app_dir = params[:app_dir]
|
||||
@language = params[:language]
|
||||
@created_at = params[:created_at]
|
||||
redirect_to open_source_projects_url(:app_dir => @app_dir, :language => @language, :created_at => @created_at, :name => params[:name])
|
||||
end
|
||||
|
||||
def search
|
||||
# per_page_option = 10
|
||||
#
|
||||
# @open_source_projects = OpenSourceProject.filter(@app_dir, @language, @created_at)
|
||||
# @open_source_projects = @open_source_projects.like(params[:name]) if params[:name].present?
|
||||
#
|
||||
# @os_project_count = @open_source_projects.count
|
||||
# @os_project_pages = Paginator.new @os_project_count, per_page_option, params['page']
|
||||
#
|
||||
# @open_source_projects = @open_source_projects.offset(@os_project_pages.offset).limit(@os_project_pages.per_page)
|
||||
|
||||
redirect_to open_source_projects_url(:name => params[:name])
|
||||
|
||||
end
|
||||
|
||||
def refuse_master_apply
|
||||
@apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id)
|
||||
@apply.first.destory
|
||||
|
||||
redirect_to master_apply_open_source_project_url
|
||||
end
|
||||
|
||||
def accept_master_apply
|
||||
@apply = ApplyProjectMaster.where("user_id = ? and apply_id = ? and apply_type = 'OpenSourceProject'", params[:user_id], @open_source_project.id)
|
||||
if @apply.count == 1
|
||||
@apply.first.update_attributes(:status => 2)
|
||||
end
|
||||
|
||||
redirect_to master_apply_open_source_project_url
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def require_master
|
||||
render_403 unless @open_source_project.admin?(User.current)
|
||||
end
|
||||
|
||||
def find_osp
|
||||
@open_source_project = OpenSourceProject.find(params[:id])
|
||||
render_404 unless @open_source_project.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,42 +1,42 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class ProjectEnumerationsController < ApplicationController
|
||||
before_filter :find_project_by_project_id
|
||||
before_filter :authorize
|
||||
|
||||
def update
|
||||
if request.put? && params[:enumerations]
|
||||
Project.transaction do
|
||||
params[:enumerations].each do |id, activity|
|
||||
@project.update_or_create_time_entry_activity(id, activity)
|
||||
end
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
end
|
||||
|
||||
redirect_to settings_project_url(@project, :tab => 'activities')
|
||||
end
|
||||
|
||||
def destroy
|
||||
@project.time_entry_activities.each do |time_entry_activity|
|
||||
time_entry_activity.destroy(time_entry_activity.parent)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to settings_project_url(@project, :tab => 'activities')
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class ProjectEnumerationsController < ApplicationController
|
||||
before_filter :find_project_by_project_id
|
||||
before_filter :authorize
|
||||
|
||||
def update
|
||||
if request.put? && params[:enumerations]
|
||||
Project.transaction do
|
||||
params[:enumerations].each do |id, activity|
|
||||
@project.update_or_create_time_entry_activity(id, activity)
|
||||
end
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
end
|
||||
|
||||
redirect_to settings_project_url(@project, :tab => 'activities')
|
||||
end
|
||||
|
||||
def destroy
|
||||
@project.time_entry_activities.each do |time_entry_activity|
|
||||
time_entry_activity.destroy(time_entry_activity.parent)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to settings_project_url(@project, :tab => 'activities')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,106 +1,106 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class QueriesController < ApplicationController
|
||||
menu_item :issues
|
||||
before_filter :find_query, :except => [:new, :create, :index]
|
||||
before_filter :find_optional_project, :only => [:new, :create]
|
||||
|
||||
accept_api_auth :index
|
||||
|
||||
include QueriesHelper
|
||||
|
||||
def index
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = per_page_option
|
||||
end
|
||||
|
||||
@query_count = IssueQuery.visible.count
|
||||
@query_pages = Paginator.new @query_count, @limit, params['page']
|
||||
@queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
|
||||
|
||||
respond_to do |format|
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@query = IssueQuery.new
|
||||
@query.user = User.current
|
||||
@query.project = @project
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
end
|
||||
|
||||
def create
|
||||
@query = IssueQuery.new(params[:query])
|
||||
@query.user = User.current
|
||||
@query.project = params[:query_is_for_all] ? nil : @project
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
@query.column_names = nil if params[:default_columns]
|
||||
|
||||
if @query.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to _project_issues_url(@project, :query_id => @query)
|
||||
else
|
||||
render :action => 'new', :layout => !request.xhr?
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@query.attributes = params[:query]
|
||||
@query.project = nil if params[:query_is_for_all]
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
@query.column_names = nil if params[:default_columns]
|
||||
|
||||
if @query.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to _project_issues_url(@project, :query_id => @query)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@query.destroy
|
||||
redirect_to _project_issues_url(@project, :set_filter => 1)
|
||||
end
|
||||
|
||||
private
|
||||
def find_query
|
||||
@query = IssueQuery.find(params[:id])
|
||||
@project = @query.project
|
||||
render_403 unless @query.editable_by?(User.current)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_optional_project
|
||||
@project = Project.find(params[:project_id]) if params[:project_id]
|
||||
render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class QueriesController < ApplicationController
|
||||
menu_item :issues
|
||||
before_filter :find_query, :except => [:new, :create, :index]
|
||||
before_filter :find_optional_project, :only => [:new, :create]
|
||||
|
||||
accept_api_auth :index
|
||||
|
||||
include QueriesHelper
|
||||
|
||||
def index
|
||||
case params[:format]
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
else
|
||||
@limit = per_page_option
|
||||
end
|
||||
|
||||
@query_count = IssueQuery.visible.count
|
||||
@query_pages = Paginator.new @query_count, @limit, params['page']
|
||||
@queries = IssueQuery.visible.all(:limit => @limit, :offset => @offset, :order => "#{Query.table_name}.name")
|
||||
|
||||
respond_to do |format|
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@query = IssueQuery.new
|
||||
@query.user = User.current
|
||||
@query.project = @project
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
end
|
||||
|
||||
def create
|
||||
@query = IssueQuery.new(params[:query])
|
||||
@query.user = User.current
|
||||
@query.project = params[:query_is_for_all] ? nil : @project
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
@query.column_names = nil if params[:default_columns]
|
||||
|
||||
if @query.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to _project_issues_url(@project, :query_id => @query)
|
||||
else
|
||||
render :action => 'new', :layout => !request.xhr?
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@query.attributes = params[:query]
|
||||
@query.project = nil if params[:query_is_for_all]
|
||||
@query.is_public = false unless User.current.allowed_to?(:manage_public_queries, @project) || User.current.admin?
|
||||
@query.build_from_params(params)
|
||||
@query.column_names = nil if params[:default_columns]
|
||||
|
||||
if @query.save
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to _project_issues_url(@project, :query_id => @query)
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@query.destroy
|
||||
redirect_to _project_issues_url(@project, :set_filter => 1)
|
||||
end
|
||||
|
||||
private
|
||||
def find_query
|
||||
@query = IssueQuery.find(params[:id])
|
||||
@project = @query.project
|
||||
render_403 unless @query.editable_by?(User.current)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_optional_project
|
||||
@project = Project.find(params[:project_id]) if params[:project_id]
|
||||
render_403 unless User.current.allowed_to?(:save_queries, @project, :global => true)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,108 +1,108 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class RolesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => [:index, :show]
|
||||
before_filter :require_admin_or_api_request, :only => [:index, :show]
|
||||
before_filter :find_role, :only => [:show, :edit, :update, :destroy]
|
||||
accept_api_auth :index, :show
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@role_pages, @roles = paginate Role.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@roles = Role.givable.all
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
# Prefills the form with 'Non member' role permissions by default
|
||||
@role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
|
||||
if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
|
||||
@role.copy_from(@copy_from)
|
||||
end
|
||||
@roles = Role.sorted.all
|
||||
end
|
||||
|
||||
def create
|
||||
@role = Role.new(params[:role])
|
||||
if request.post? && @role.save
|
||||
# workflow copy
|
||||
if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
|
||||
@role.workflow_rules.copy(copy_from)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to roles_url
|
||||
else
|
||||
@roles = Role.sorted.all
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if request.put? and @role.update_attributes(params[:role])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to roles_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@role.destroy
|
||||
redirect_to roles_url
|
||||
rescue
|
||||
flash[:error] = l(:error_can_not_remove_role)
|
||||
redirect_to roles_url
|
||||
end
|
||||
|
||||
def permissions
|
||||
@roles = Role.sorted.all
|
||||
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
|
||||
if request.post?
|
||||
@roles.each do |role|
|
||||
role.permissions = params[:permissions][role.id.to_s]
|
||||
role.save
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to roles_url
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_role
|
||||
@role = Role.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class RolesController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :except => [:index, :show]
|
||||
before_filter :require_admin_or_api_request, :only => [:index, :show]
|
||||
before_filter :find_role, :only => [:show, :edit, :update, :destroy]
|
||||
accept_api_auth :index, :show
|
||||
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@role_pages, @roles = paginate Role.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@roles = Role.givable.all
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
# Prefills the form with 'Non member' role permissions by default
|
||||
@role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
|
||||
if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
|
||||
@role.copy_from(@copy_from)
|
||||
end
|
||||
@roles = Role.sorted.all
|
||||
end
|
||||
|
||||
def create
|
||||
@role = Role.new(params[:role])
|
||||
if request.post? && @role.save
|
||||
# workflow copy
|
||||
if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
|
||||
@role.workflow_rules.copy(copy_from)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to roles_url
|
||||
else
|
||||
@roles = Role.sorted.all
|
||||
render :action => 'new'
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if request.put? and @role.update_attributes(params[:role])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to roles_url
|
||||
else
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@role.destroy
|
||||
redirect_to roles_url
|
||||
rescue
|
||||
flash[:error] = l(:error_can_not_remove_role)
|
||||
redirect_to roles_url
|
||||
end
|
||||
|
||||
def permissions
|
||||
@roles = Role.sorted.all
|
||||
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
|
||||
if request.post?
|
||||
@roles.each do |role|
|
||||
role.permissions = params[:permissions][role.id.to_s]
|
||||
role.save
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to roles_url
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_role
|
||||
@role = Role.find(params[:id])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,111 +1,111 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class SearchController < ApplicationController
|
||||
before_filter :find_optional_project
|
||||
|
||||
def index
|
||||
@question = params[:q] || ""
|
||||
@question.strip!
|
||||
@all_words = params[:all_words] ? params[:all_words].present? : true
|
||||
@titles_only = params[:titles_only] ? params[:titles_only].present? : false
|
||||
|
||||
projects_to_search =
|
||||
case params[:scope]
|
||||
when 'all'
|
||||
nil
|
||||
when 'my_projects'
|
||||
User.current.memberships.collect(&:project)
|
||||
when 'subprojects'
|
||||
@project ? (@project.self_and_descendants.active.all) : nil
|
||||
else
|
||||
@project
|
||||
end
|
||||
|
||||
offset = nil
|
||||
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
||||
|
||||
# quick jump to an issue
|
||||
if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
|
||||
redirect_to issue_url(issue)
|
||||
return
|
||||
end
|
||||
|
||||
@object_types = Redmine::Search.available_search_types.dup
|
||||
if projects_to_search.is_a? Project
|
||||
# don't search projects
|
||||
@object_types.delete('projects')
|
||||
# only show what the user is allowed to view
|
||||
@object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
|
||||
end
|
||||
|
||||
@scope = @object_types.select {|t| params[t]}
|
||||
@scope = @object_types if @scope.empty?
|
||||
|
||||
# extract tokens from the question
|
||||
# eg. hello "bye bye" => ["hello", "bye bye"]
|
||||
@tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
|
||||
# tokens must be at least 2 characters long
|
||||
@tokens = @tokens.uniq.select {|w| w.length > 1 }
|
||||
|
||||
if !@tokens.empty?
|
||||
# no more than 5 tokens to search for
|
||||
@tokens.slice! 5..-1 if @tokens.size > 5
|
||||
|
||||
@results = []
|
||||
@results_by_type = Hash.new {|h,k| h[k] = 0}
|
||||
|
||||
limit = 10
|
||||
@scope.each do |s|
|
||||
r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
|
||||
:all_words => @all_words,
|
||||
:titles_only => @titles_only,
|
||||
:limit => (limit+1),
|
||||
:offset => offset,
|
||||
:before => params[:previous].nil?)
|
||||
@results += r
|
||||
@results_by_type[s] += c
|
||||
end
|
||||
@results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
|
||||
if params[:previous].nil?
|
||||
@pagination_previous_date = @results[0].event_datetime if offset && @results[0]
|
||||
if @results.size > limit
|
||||
@pagination_next_date = @results[limit-1].event_datetime
|
||||
@results = @results[0, limit]
|
||||
end
|
||||
else
|
||||
@pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
|
||||
if @results.size > limit
|
||||
@pagination_previous_date = @results[-(limit)].event_datetime
|
||||
@results = @results[-(limit), limit]
|
||||
end
|
||||
end
|
||||
else
|
||||
@question = ""
|
||||
end
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
private
|
||||
def find_optional_project
|
||||
return true unless params[:id]
|
||||
@project = Project.find(params[:id])
|
||||
check_project_privacy
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class SearchController < ApplicationController
|
||||
before_filter :find_optional_project
|
||||
|
||||
def index
|
||||
@question = params[:q] || ""
|
||||
@question.strip!
|
||||
@all_words = params[:all_words] ? params[:all_words].present? : true
|
||||
@titles_only = params[:titles_only] ? params[:titles_only].present? : false
|
||||
|
||||
projects_to_search =
|
||||
case params[:scope]
|
||||
when 'all'
|
||||
nil
|
||||
when 'my_projects'
|
||||
User.current.memberships.collect(&:project)
|
||||
when 'subprojects'
|
||||
@project ? (@project.self_and_descendants.active.all) : nil
|
||||
else
|
||||
@project
|
||||
end
|
||||
|
||||
offset = nil
|
||||
begin; offset = params[:offset].to_time if params[:offset]; rescue; end
|
||||
|
||||
# quick jump to an issue
|
||||
if (m = @question.match(/^#?(\d+)$/)) && (issue = Issue.visible.find_by_id(m[1].to_i))
|
||||
redirect_to issue_url(issue)
|
||||
return
|
||||
end
|
||||
|
||||
@object_types = Redmine::Search.available_search_types.dup
|
||||
if projects_to_search.is_a? Project
|
||||
# don't search projects
|
||||
@object_types.delete('projects')
|
||||
# only show what the user is allowed to view
|
||||
@object_types = @object_types.select {|o| User.current.allowed_to?("view_#{o}".to_sym, projects_to_search)}
|
||||
end
|
||||
|
||||
@scope = @object_types.select {|t| params[t]}
|
||||
@scope = @object_types if @scope.empty?
|
||||
|
||||
# extract tokens from the question
|
||||
# eg. hello "bye bye" => ["hello", "bye bye"]
|
||||
@tokens = @question.scan(%r{((\s|^)"[\s\w]+"(\s|$)|\S+)}).collect {|m| m.first.gsub(%r{(^\s*"\s*|\s*"\s*$)}, '')}
|
||||
# tokens must be at least 2 characters long
|
||||
@tokens = @tokens.uniq.select {|w| w.length > 1 }
|
||||
|
||||
if !@tokens.empty?
|
||||
# no more than 5 tokens to search for
|
||||
@tokens.slice! 5..-1 if @tokens.size > 5
|
||||
|
||||
@results = []
|
||||
@results_by_type = Hash.new {|h,k| h[k] = 0}
|
||||
|
||||
limit = 10
|
||||
@scope.each do |s|
|
||||
r, c = s.singularize.camelcase.constantize.search(@tokens, projects_to_search,
|
||||
:all_words => @all_words,
|
||||
:titles_only => @titles_only,
|
||||
:limit => (limit+1),
|
||||
:offset => offset,
|
||||
:before => params[:previous].nil?)
|
||||
@results += r
|
||||
@results_by_type[s] += c
|
||||
end
|
||||
@results = @results.sort {|a,b| b.event_datetime <=> a.event_datetime}
|
||||
if params[:previous].nil?
|
||||
@pagination_previous_date = @results[0].event_datetime if offset && @results[0]
|
||||
if @results.size > limit
|
||||
@pagination_next_date = @results[limit-1].event_datetime
|
||||
@results = @results[0, limit]
|
||||
end
|
||||
else
|
||||
@pagination_next_date = @results[-1].event_datetime if offset && @results[-1]
|
||||
if @results.size > limit
|
||||
@pagination_previous_date = @results[-(limit)].event_datetime
|
||||
@results = @results[-(limit), limit]
|
||||
end
|
||||
end
|
||||
else
|
||||
@question = ""
|
||||
end
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
private
|
||||
def find_optional_project
|
||||
return true unless params[:id]
|
||||
@project = Project.find(params[:id])
|
||||
check_project_privacy
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,73 +1,73 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class SettingsController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :plugins, :only => :plugin
|
||||
|
||||
helper :queries
|
||||
|
||||
before_filter :require_admin
|
||||
|
||||
def index
|
||||
edit
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
||||
def edit
|
||||
@notifiables = Redmine::Notifiable.all
|
||||
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
|
||||
settings = (params[:settings] || {}).dup.symbolize_keys
|
||||
settings.each do |name, value|
|
||||
# remove blank values in array settings
|
||||
value.delete_if {|v| v.blank? } if value.is_a?(Array)
|
||||
Setting[name] = value
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to settings_url(:tab => params[:tab])
|
||||
else
|
||||
@options = {}
|
||||
user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]}
|
||||
@options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]}
|
||||
@deliveries = ActionMailer::Base.perform_deliveries
|
||||
|
||||
@guessed_host_and_path = request.host_with_port.dup
|
||||
@guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
|
||||
|
||||
Redmine::Themes.rescan
|
||||
end
|
||||
end
|
||||
|
||||
def plugin
|
||||
@plugin = Redmine::Plugin.find(params[:id])
|
||||
unless @plugin.configurable?
|
||||
render_404
|
||||
return
|
||||
end
|
||||
|
||||
if request.post?
|
||||
Setting.send "plugin_#{@plugin.id}=", params[:settings]
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to plugin_settings_url(@plugin)
|
||||
else
|
||||
@partial = @plugin.settings[:partial]
|
||||
@settings = Setting.send "plugin_#{@plugin.id}"
|
||||
end
|
||||
rescue Redmine::PluginNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class SettingsController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :plugins, :only => :plugin
|
||||
|
||||
helper :queries
|
||||
|
||||
before_filter :require_admin
|
||||
|
||||
def index
|
||||
edit
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
||||
def edit
|
||||
@notifiables = Redmine::Notifiable.all
|
||||
if request.post? && params[:settings] && params[:settings].is_a?(Hash)
|
||||
settings = (params[:settings] || {}).dup.symbolize_keys
|
||||
settings.each do |name, value|
|
||||
# remove blank values in array settings
|
||||
value.delete_if {|v| v.blank? } if value.is_a?(Array)
|
||||
Setting[name] = value
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to settings_url(:tab => params[:tab])
|
||||
else
|
||||
@options = {}
|
||||
user_format = User::USER_FORMATS.collect{|key, value| [key, value[:setting_order]]}.sort{|a, b| a[1] <=> b[1]}
|
||||
@options[:user_format] = user_format.collect{|f| [User.current.name(f[0]), f[0].to_s]}
|
||||
@deliveries = ActionMailer::Base.perform_deliveries
|
||||
|
||||
@guessed_host_and_path = request.host_with_port.dup
|
||||
@guessed_host_and_path << ('/'+ Redmine::Utils.relative_url_root.gsub(%r{^\/}, '')) unless Redmine::Utils.relative_url_root.blank?
|
||||
|
||||
Redmine::Themes.rescan
|
||||
end
|
||||
end
|
||||
|
||||
def plugin
|
||||
@plugin = Redmine::Plugin.find(params[:id])
|
||||
unless @plugin.configurable?
|
||||
render_404
|
||||
return
|
||||
end
|
||||
|
||||
if request.post?
|
||||
Setting.send "plugin_#{@plugin.id}=", params[:settings]
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to plugin_settings_url(@plugin)
|
||||
else
|
||||
@partial = @plugin.settings[:partial]
|
||||
@settings = Setting.send "plugin_#{@plugin.id}"
|
||||
end
|
||||
rescue Redmine::PluginNotFound
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,356 +1,356 @@
|
|||
class SoftapplicationsController < ApplicationController
|
||||
layout "contest_base"
|
||||
before_filter :find_softapplication, only: [:edit, :update, :destroy]
|
||||
before_filter :editable, only: [:edit, :update]
|
||||
before_filter :destroyable, only: :destroy
|
||||
|
||||
# GET /softapplications
|
||||
# GET /softapplications.json
|
||||
def index
|
||||
@softapplications = Softapplication.all
|
||||
|
||||
#new added fenyefunction
|
||||
@limit = 5
|
||||
@softapplication_count = @softapplications.count
|
||||
@softapplication_pages = Paginator.new @softapplication_count, @limit, params['page']
|
||||
@offset ||= @softapplication_pages.offset
|
||||
#@softapplications = @softapplications[@offset,@limit]
|
||||
#new added end
|
||||
|
||||
#new added sort
|
||||
if params[:softapplication_sort_type].present?
|
||||
case params[:softapplication_sort_type]
|
||||
when '0'
|
||||
@softapplications = @softapplications[@offset, @limit]
|
||||
@s_state = 0
|
||||
when '1'
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
else
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
#new added end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @softapplications }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/1
|
||||
# GET /softapplications/1.json
|
||||
|
||||
def percent_of(num, percent)
|
||||
num.to_f / percent.to_f * 100.0
|
||||
end
|
||||
|
||||
def show
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@project = @softapplication.project
|
||||
# 打分统计
|
||||
stars_reates = @softapplication.
|
||||
rates(:quality)
|
||||
stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
stars_status = stars_reates.select("stars, count(*) as scount").
|
||||
group("stars")
|
||||
|
||||
@stars_status_map = Hash.new(0.0)
|
||||
stars_status.each do |star_status|
|
||||
percent = percent_of(star_status.scount, stars_reates_count).to_f
|
||||
percent_m = format("%.2f", percent)
|
||||
@stars_status_map["star#{star_status.stars.to_i}".to_sym] =
|
||||
percent_m.to_s + "%"
|
||||
end
|
||||
@jours = @softapplication.journals_for_messages.order('created_on DESC')
|
||||
@image_results = []
|
||||
@softapplication.attachments.each do |f|
|
||||
f.image? ? @image_results << f : @image_results
|
||||
end
|
||||
@app_items = []
|
||||
@softapplication.attachments.each do |f|
|
||||
f.pack? ? @app_items << f : @app_items
|
||||
end
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @softapplication }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/new
|
||||
# GET /softapplications/new.json
|
||||
def new
|
||||
@softapplication = Softapplication.new
|
||||
|
||||
#添加当前用户创建过的项目作为托管项目(下拉项目列表)
|
||||
project = Project.find(params[:user_id])
|
||||
#end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @softapplication }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/1/edit
|
||||
def edit
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
|
||||
@membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current))
|
||||
@option = []
|
||||
# @contesting_project_count = @contesting_project_all.count
|
||||
# @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page']
|
||||
@membership.each do |membership|
|
||||
unless(membership.project.project_type==1)
|
||||
#拥有编辑项目权限的可操作该项目
|
||||
if User.current.allowed_to?(:quote_project,membership.project)
|
||||
@option << membership.project
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# POST /softapplications
|
||||
# POST /softapplications.json
|
||||
# def create
|
||||
# @softapplication = Softapplication.new(params[:softapplication])
|
||||
# @softapplication.user = User.current
|
||||
# @softapplication.save_attachments(params[:attachments])
|
||||
# respond_to do |format|
|
||||
# if @softapplication.save
|
||||
# format.js
|
||||
# format.html { redirect_to @softapplication, notice: 'Softapplication was successfully created.' }
|
||||
# # format.json { render json: @softapplication, status: :created, location: @softapplication }
|
||||
# else
|
||||
# format.js { render status: 406 }
|
||||
# format.html { render action: "new" }
|
||||
# # format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
#new changed created function
|
||||
def create
|
||||
#options = params[:softapplication]
|
||||
#options[:app_type_name] = params[:other_input] if options[:app_type_name] == "其他" && params[:other_input]
|
||||
@softapplication = Softapplication.new(params[:softapplication])
|
||||
@softapplication.user = User.current
|
||||
#@softapplication.deposit_project = params[:project]
|
||||
@softapplication.project = Project.find_by_id(params[:project])
|
||||
@softapplication.app_type_name = params[:other_input] if params[:other_input] != ""
|
||||
@softapplication.save_attachments(params[:attachments])
|
||||
respond_to do |format|
|
||||
if @softapplication.save
|
||||
ContestingSoftapplication.create(:contest_id => params[:contest_id], :softapplication_id => @softapplication.id)
|
||||
#ProjectingSoftapplication.create_softapplication_projecting(:project_id => params[:project_id], :softapplication_id => @softapplication.id)
|
||||
#ProjectingSoftapplication.create_softapplication_projecting(@project.id, softapplication.id)
|
||||
format.html { redirect_to show_attendingcontest_contest_url(:id => params[:contest_id]), notice: l(:notice_attendingcontest_work_successfully_created) }
|
||||
# format.json { render json: @softapplication, status: :created, location: @softapplication }
|
||||
else
|
||||
#format.js { render status: 406 }
|
||||
format.html { render action: "contests/show_attendingcontest" }
|
||||
# format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
#关联新建的参赛作品
|
||||
|
||||
# @contesting_softapplication = paginateHelper @contest.contesting_softapplications
|
||||
|
||||
|
||||
|
||||
end
|
||||
# PUT /softapplications/1
|
||||
# PUT /softapplications/1.json
|
||||
def update
|
||||
# @softapplication = Softapplication.find(params[:id])
|
||||
#@softapplication.attachments.map{|attach| attach.destroy }
|
||||
@softapplication.save_attachments(params[:attachments]) if params[:attachments]
|
||||
#@softapplication.deposit_project = params[:project]
|
||||
@softapplication.project = Project.find_by_id(params[:project])
|
||||
|
||||
@softapplication.name = params[:softapplication][:name]
|
||||
@softapplication.android_min_version_available = params[:softapplication][:android_min_version_available]
|
||||
@softapplication.app_type_name = params[:other_input] == "" ? params[:softapplication][:app_type_name] : params[:other_input]
|
||||
@softapplication.description = params[:softapplication][:description]
|
||||
@softapplication.application_developers = params[:softapplication][:application_developers]
|
||||
#@softapplication.app_type_name = params[:other_input] if params[:other_input] != ""
|
||||
respond_to do |format|
|
||||
#if @softapplication.update_attributes(params[:softapplication])
|
||||
if @softapplication.save
|
||||
format.html { redirect_to @softapplication, notice: l(:notice_softapplication_was_successfully_updated) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_attach
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.save_attachments(params[:attachments])
|
||||
end
|
||||
|
||||
# DELETE /softapplications/1
|
||||
# DELETE /softapplications/1.json
|
||||
def destroy
|
||||
# @softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to home_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
#应用评价涉及到的方法
|
||||
def new_message
|
||||
@jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id]
|
||||
if @jour
|
||||
user = @jour.user
|
||||
text = @jour.notes
|
||||
else
|
||||
user = @softapplication.user
|
||||
text = @softapplication.description
|
||||
end
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
#新建评价
|
||||
def create_message
|
||||
|
||||
if params[:reference_content]
|
||||
message = params[:softapplication_message][:message] + "\n" + params[:reference_content]
|
||||
else
|
||||
message = params[:softapplication_message][:message]
|
||||
end
|
||||
refer_user_id = params[:softapplication_message][:reference_user_id].to_i
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.add_jour(User.current, message, refer_user_id)
|
||||
|
||||
|
||||
@user = @softapplication.user
|
||||
@jours = @softapplication.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
|
||||
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
#@softapplication.set_commit(@feedback_count)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
##删除评价
|
||||
def destroy_message
|
||||
@user = @softapplication.user
|
||||
if User.current.admin? || User.current.id == @user.id
|
||||
JournalsForMessage.delete_message(params[:object_id])
|
||||
end
|
||||
@jours = @softapplication.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
|
||||
@softapplication.set_commit(@feedback_count)
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def more
|
||||
@jour = @softapplication.journals_for_messages
|
||||
@jour.each_with_index {|j,i| j.indice = i+1}
|
||||
@state = true
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def back
|
||||
@jour = @softapplication.journals_for_messages
|
||||
@jour.each_with_index {|j,i| j.indice = i+1}
|
||||
@state = false
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
@softapplications = Softapplication.where("name like '%#{params[:name]}%'")
|
||||
|
||||
#new added fenyefunction
|
||||
@limit = 5
|
||||
@softapplication_count = @softapplications.count
|
||||
@softapplication_pages = Paginator.new @softapplication_count, @limit, params['page']
|
||||
@offset ||= @softapplication_pages.offset
|
||||
|
||||
#new added sort
|
||||
if params[:softapplication_sort_type].present?
|
||||
case params[:softapplication_sort_type]
|
||||
when '0'
|
||||
@softapplications = @softapplications[@offset, @limit]
|
||||
@s_state = 0
|
||||
when '1'
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
else
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
#new added end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_softapplication
|
||||
@softapplication = Softapplication.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def editable
|
||||
unless @softapplication.editable_by? User.current
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def destroyable
|
||||
unless @softapplication.destroyable_by? User.current
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class SoftapplicationsController < ApplicationController
|
||||
layout "contest_base"
|
||||
before_filter :find_softapplication, only: [:edit, :update, :destroy]
|
||||
before_filter :editable, only: [:edit, :update]
|
||||
before_filter :destroyable, only: :destroy
|
||||
|
||||
# GET /softapplications
|
||||
# GET /softapplications.json
|
||||
def index
|
||||
@softapplications = Softapplication.all
|
||||
|
||||
#new added fenyefunction
|
||||
@limit = 5
|
||||
@softapplication_count = @softapplications.count
|
||||
@softapplication_pages = Paginator.new @softapplication_count, @limit, params['page']
|
||||
@offset ||= @softapplication_pages.offset
|
||||
#@softapplications = @softapplications[@offset,@limit]
|
||||
#new added end
|
||||
|
||||
#new added sort
|
||||
if params[:softapplication_sort_type].present?
|
||||
case params[:softapplication_sort_type]
|
||||
when '0'
|
||||
@softapplications = @softapplications[@offset, @limit]
|
||||
@s_state = 0
|
||||
when '1'
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
else
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
#new added end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # index.html.erb
|
||||
format.json { render json: @softapplications }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/1
|
||||
# GET /softapplications/1.json
|
||||
|
||||
def percent_of(num, percent)
|
||||
num.to_f / percent.to_f * 100.0
|
||||
end
|
||||
|
||||
def show
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@project = @softapplication.project
|
||||
# 打分统计
|
||||
stars_reates = @softapplication.
|
||||
rates(:quality)
|
||||
stars_reates_count = stars_reates.count == 0 ? 1 : stars_reates.count
|
||||
stars_status = stars_reates.select("stars, count(*) as scount").
|
||||
group("stars")
|
||||
|
||||
@stars_status_map = Hash.new(0.0)
|
||||
stars_status.each do |star_status|
|
||||
percent = percent_of(star_status.scount, stars_reates_count).to_f
|
||||
percent_m = format("%.2f", percent)
|
||||
@stars_status_map["star#{star_status.stars.to_i}".to_sym] =
|
||||
percent_m.to_s + "%"
|
||||
end
|
||||
@jours = @softapplication.journals_for_messages.order('created_on DESC')
|
||||
@image_results = []
|
||||
@softapplication.attachments.each do |f|
|
||||
f.image? ? @image_results << f : @image_results
|
||||
end
|
||||
@app_items = []
|
||||
@softapplication.attachments.each do |f|
|
||||
f.pack? ? @app_items << f : @app_items
|
||||
end
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
respond_to do |format|
|
||||
format.html # show.html.erb
|
||||
format.json { render json: @softapplication }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/new
|
||||
# GET /softapplications/new.json
|
||||
def new
|
||||
@softapplication = Softapplication.new
|
||||
|
||||
#添加当前用户创建过的项目作为托管项目(下拉项目列表)
|
||||
project = Project.find(params[:user_id])
|
||||
#end
|
||||
|
||||
respond_to do |format|
|
||||
format.html # new.html.erb
|
||||
format.json { render json: @softapplication }
|
||||
end
|
||||
end
|
||||
|
||||
# GET /softapplications/1/edit
|
||||
def edit
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
|
||||
@membership = User.current.memberships.all(:conditions => Project.visible_condition(User.current))
|
||||
@option = []
|
||||
# @contesting_project_count = @contesting_project_all.count
|
||||
# @contesting_project_pages = Paginator.new @contesting_project_count, per_page_option, params['page']
|
||||
@membership.each do |membership|
|
||||
unless(membership.project.project_type==1)
|
||||
#拥有编辑项目权限的可操作该项目
|
||||
if User.current.allowed_to?(:quote_project,membership.project)
|
||||
@option << membership.project
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# POST /softapplications
|
||||
# POST /softapplications.json
|
||||
# def create
|
||||
# @softapplication = Softapplication.new(params[:softapplication])
|
||||
# @softapplication.user = User.current
|
||||
# @softapplication.save_attachments(params[:attachments])
|
||||
# respond_to do |format|
|
||||
# if @softapplication.save
|
||||
# format.js
|
||||
# format.html { redirect_to @softapplication, notice: 'Softapplication was successfully created.' }
|
||||
# # format.json { render json: @softapplication, status: :created, location: @softapplication }
|
||||
# else
|
||||
# format.js { render status: 406 }
|
||||
# format.html { render action: "new" }
|
||||
# # format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
#new changed created function
|
||||
def create
|
||||
#options = params[:softapplication]
|
||||
#options[:app_type_name] = params[:other_input] if options[:app_type_name] == "其他" && params[:other_input]
|
||||
@softapplication = Softapplication.new(params[:softapplication])
|
||||
@softapplication.user = User.current
|
||||
#@softapplication.deposit_project = params[:project]
|
||||
@softapplication.project = Project.find_by_id(params[:project])
|
||||
@softapplication.app_type_name = params[:other_input] if params[:other_input] != ""
|
||||
@softapplication.save_attachments(params[:attachments])
|
||||
respond_to do |format|
|
||||
if @softapplication.save
|
||||
ContestingSoftapplication.create(:contest_id => params[:contest_id], :softapplication_id => @softapplication.id)
|
||||
#ProjectingSoftapplication.create_softapplication_projecting(:project_id => params[:project_id], :softapplication_id => @softapplication.id)
|
||||
#ProjectingSoftapplication.create_softapplication_projecting(@project.id, softapplication.id)
|
||||
format.html { redirect_to show_attendingcontest_contest_url(:id => params[:contest_id]), notice: l(:notice_attendingcontest_work_successfully_created) }
|
||||
# format.json { render json: @softapplication, status: :created, location: @softapplication }
|
||||
else
|
||||
#format.js { render status: 406 }
|
||||
format.html { render action: "contests/show_attendingcontest" }
|
||||
# format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
#关联新建的参赛作品
|
||||
|
||||
# @contesting_softapplication = paginateHelper @contest.contesting_softapplications
|
||||
|
||||
|
||||
|
||||
end
|
||||
# PUT /softapplications/1
|
||||
# PUT /softapplications/1.json
|
||||
def update
|
||||
# @softapplication = Softapplication.find(params[:id])
|
||||
#@softapplication.attachments.map{|attach| attach.destroy }
|
||||
@softapplication.save_attachments(params[:attachments]) if params[:attachments]
|
||||
#@softapplication.deposit_project = params[:project]
|
||||
@softapplication.project = Project.find_by_id(params[:project])
|
||||
|
||||
@softapplication.name = params[:softapplication][:name]
|
||||
@softapplication.android_min_version_available = params[:softapplication][:android_min_version_available]
|
||||
@softapplication.app_type_name = params[:other_input] == "" ? params[:softapplication][:app_type_name] : params[:other_input]
|
||||
@softapplication.description = params[:softapplication][:description]
|
||||
@softapplication.application_developers = params[:softapplication][:application_developers]
|
||||
#@softapplication.app_type_name = params[:other_input] if params[:other_input] != ""
|
||||
respond_to do |format|
|
||||
#if @softapplication.update_attributes(params[:softapplication])
|
||||
if @softapplication.save
|
||||
format.html { redirect_to @softapplication, notice: l(:notice_softapplication_was_successfully_updated) }
|
||||
format.json { head :no_content }
|
||||
else
|
||||
format.html { render action: "edit" }
|
||||
format.json { render json: @softapplication.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_attach
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.save_attachments(params[:attachments])
|
||||
end
|
||||
|
||||
# DELETE /softapplications/1
|
||||
# DELETE /softapplications/1.json
|
||||
def destroy
|
||||
# @softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.destroy
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to home_url }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
#应用评价涉及到的方法
|
||||
def new_message
|
||||
@jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id]
|
||||
if @jour
|
||||
user = @jour.user
|
||||
text = @jour.notes
|
||||
else
|
||||
user = @softapplication.user
|
||||
text = @softapplication.description
|
||||
end
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
#新建评价
|
||||
def create_message
|
||||
|
||||
if params[:reference_content]
|
||||
message = params[:softapplication_message][:message] + "\n" + params[:reference_content]
|
||||
else
|
||||
message = params[:softapplication_message][:message]
|
||||
end
|
||||
refer_user_id = params[:softapplication_message][:reference_user_id].to_i
|
||||
@softapplication = Softapplication.find(params[:id])
|
||||
@softapplication.add_jour(User.current, message, refer_user_id)
|
||||
|
||||
|
||||
@user = @softapplication.user
|
||||
@jours = @softapplication.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
|
||||
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
#@softapplication.set_commit(@feedback_count)
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
##删除评价
|
||||
def destroy_message
|
||||
@user = @softapplication.user
|
||||
if User.current.admin? || User.current.id == @user.id
|
||||
JournalsForMessage.delete_message(params[:object_id])
|
||||
end
|
||||
@jours = @softapplication.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
|
||||
@softapplication.set_commit(@feedback_count)
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def more
|
||||
@jour = @softapplication.journals_for_messages
|
||||
@jour.each_with_index {|j,i| j.indice = i+1}
|
||||
@state = true
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
def back
|
||||
@jour = @softapplication.journals_for_messages
|
||||
@jour.each_with_index {|j,i| j.indice = i+1}
|
||||
@state = false
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def search
|
||||
@softapplications = Softapplication.where("name like '%#{params[:name]}%'")
|
||||
|
||||
#new added fenyefunction
|
||||
@limit = 5
|
||||
@softapplication_count = @softapplications.count
|
||||
@softapplication_pages = Paginator.new @softapplication_count, @limit, params['page']
|
||||
@offset ||= @softapplication_pages.offset
|
||||
|
||||
#new added sort
|
||||
if params[:softapplication_sort_type].present?
|
||||
case params[:softapplication_sort_type]
|
||||
when '0'
|
||||
@softapplications = @softapplications[@offset, @limit]
|
||||
@s_state = 0
|
||||
when '1'
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
else
|
||||
@softapplications = @softapplications.sort { |x, y| y[:created_at] <=> x[:created_at]}[@offset, @limit]
|
||||
@s_state = 1
|
||||
end
|
||||
#new added end
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_softapplication
|
||||
@softapplication = Softapplication.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def editable
|
||||
unless @softapplication.editable_by? User.current
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def destroyable
|
||||
unless @softapplication.destroyable_by? User.current
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,315 +1,315 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class TimelogController < ApplicationController
|
||||
layout 'base_projects'#added by young
|
||||
menu_item :issues
|
||||
|
||||
before_filter :find_project_for_new_time_entry, :only => [:create]
|
||||
before_filter :find_time_entry, :only => [:show, :edit, :update]
|
||||
before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_filter :authorize, :except => [:new, :index, :report]
|
||||
|
||||
before_filter :find_optional_project, :only => [:index, :report]
|
||||
before_filter :find_optional_project_for_new_time_entry, :only => [:new]
|
||||
before_filter :authorize_global, :only => [:new, :index, :report]
|
||||
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
rescue_from Query::StatementInvalid, :with => :query_statement_invalid
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :issues
|
||||
include TimelogHelper
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
|
||||
def index
|
||||
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
||||
scope = time_entry_scope
|
||||
|
||||
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
# Paginate results
|
||||
@entry_count = scope.count
|
||||
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => sort_clause,
|
||||
:limit => @entry_pages.per_page,
|
||||
:offset => @entry_pages.offset
|
||||
)
|
||||
@total_hours = scope.sum(:hours).to_f
|
||||
|
||||
render :layout => !request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@entry_count = scope.count
|
||||
@offset, @limit = api_offset_and_limit
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => sort_clause,
|
||||
:limit => @limit,
|
||||
:offset => @offset
|
||||
)
|
||||
}
|
||||
format.atom {
|
||||
entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => "#{TimeEntry.table_name}.created_on DESC",
|
||||
:limit => Setting.feeds_limit.to_i
|
||||
)
|
||||
render_feed(entries, :title => l(:label_spent_time))
|
||||
}
|
||||
format.csv {
|
||||
# Export all entries
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
||||
:order => sort_clause
|
||||
)
|
||||
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def report
|
||||
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
||||
scope = time_entry_scope
|
||||
|
||||
@report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :layout => !request.xhr? }
|
||||
format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
# TODO: Implement html response
|
||||
format.html { render :nothing => true, :status => 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
end
|
||||
|
||||
def create
|
||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
|
||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||
|
||||
if @time_entry.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
if params[:continue]
|
||||
if params[:project_id]
|
||||
options = {
|
||||
:time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
|
||||
:back_url => params[:back_url]
|
||||
}
|
||||
if @time_entry.issue
|
||||
redirect_to new_project_issue_time_entry_url(@time_entry.project, @time_entry.issue, options)
|
||||
else
|
||||
redirect_to new_project_time_entry_url(@time_entry.project, options)
|
||||
end
|
||||
else
|
||||
options = {
|
||||
:time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
|
||||
:back_url => params[:back_url]
|
||||
}
|
||||
redirect_to new_time_entry_url(options)
|
||||
end
|
||||
else
|
||||
redirect_back_or_default project_time_entries_path(@time_entry.project)
|
||||
end
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new' }
|
||||
format.api { render_validation_errors(@time_entry) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
end
|
||||
|
||||
def update
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
|
||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||
|
||||
if @time_entry.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_back_or_default project_time_entries_path(@time_entry.project)
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@time_entry) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bulk_edit
|
||||
@available_activities = TimeEntryActivity.shared.active
|
||||
@custom_fields = TimeEntry.first.available_custom_fields
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
attributes = parse_params_for_bulk_time_entry_attributes(params)
|
||||
|
||||
unsaved_time_entry_ids = []
|
||||
@time_entries.each do |time_entry|
|
||||
time_entry.reload
|
||||
time_entry.safe_attributes = attributes
|
||||
call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry })
|
||||
unless time_entry.save
|
||||
# Keep unsaved time_entry ids to display them in flash error
|
||||
unsaved_time_entry_ids << time_entry.id
|
||||
end
|
||||
end
|
||||
set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids)
|
||||
redirect_back_or_default project_time_entries_path(@projects.first)
|
||||
end
|
||||
|
||||
def destroy
|
||||
destroyed = TimeEntry.transaction do
|
||||
@time_entries.each do |t|
|
||||
unless t.destroy && t.destroyed?
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
if destroyed
|
||||
flash[:notice] = l(:notice_successful_delete)
|
||||
else
|
||||
flash[:error] = l(:notice_unable_delete_time_entry)
|
||||
end
|
||||
redirect_back_or_default project_time_entries_path(@projects.first)
|
||||
}
|
||||
format.api {
|
||||
if destroyed
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@time_entries)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_time_entry
|
||||
@time_entry = TimeEntry.find(params[:id])
|
||||
unless @time_entry.editable_by?(User.current)
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
@project = @time_entry.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_time_entries
|
||||
@time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids])
|
||||
raise ActiveRecord::RecordNotFound if @time_entries.empty?
|
||||
@projects = @time_entries.collect(&:project).compact.uniq
|
||||
@project = @projects.first if @projects.size == 1
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids)
|
||||
if unsaved_time_entry_ids.empty?
|
||||
flash[:notice] = l(:notice_successful_update) unless time_entries.empty?
|
||||
else
|
||||
flash[:error] = l(:notice_failed_to_save_time_entries,
|
||||
:count => unsaved_time_entry_ids.size,
|
||||
:total => time_entries.size,
|
||||
:ids => '#' + unsaved_time_entry_ids.join(', #'))
|
||||
end
|
||||
end
|
||||
|
||||
def find_optional_project_for_new_time_entry
|
||||
if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present?
|
||||
@project = Project.find(project_id)
|
||||
end
|
||||
if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present?
|
||||
@issue = Issue.find(issue_id)
|
||||
@project ||= @issue.project
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_project_for_new_time_entry
|
||||
find_optional_project_for_new_time_entry
|
||||
if @project.nil?
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def find_optional_project
|
||||
if !params[:issue_id].blank?
|
||||
@issue = Issue.find(params[:issue_id])
|
||||
@project = @issue.project
|
||||
elsif !params[:project_id].blank?
|
||||
@project = Project.find(params[:project_id])
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the TimeEntry scope for index and report actions
|
||||
def time_entry_scope
|
||||
scope = TimeEntry.visible.where(@query.statement)
|
||||
if @issue
|
||||
scope = scope.on_issue(@issue)
|
||||
elsif @project
|
||||
scope = scope.on_project(@project, Setting.display_subprojects_issues?)
|
||||
end
|
||||
scope
|
||||
end
|
||||
|
||||
def parse_params_for_bulk_time_entry_attributes(params)
|
||||
attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?}
|
||||
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
|
||||
attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values]
|
||||
attributes
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class TimelogController < ApplicationController
|
||||
layout 'base_projects'#added by young
|
||||
menu_item :issues
|
||||
|
||||
before_filter :find_project_for_new_time_entry, :only => [:create]
|
||||
before_filter :find_time_entry, :only => [:show, :edit, :update]
|
||||
before_filter :find_time_entries, :only => [:bulk_edit, :bulk_update, :destroy]
|
||||
before_filter :authorize, :except => [:new, :index, :report]
|
||||
|
||||
before_filter :find_optional_project, :only => [:index, :report]
|
||||
before_filter :find_optional_project_for_new_time_entry, :only => [:new]
|
||||
before_filter :authorize_global, :only => [:new, :index, :report]
|
||||
|
||||
accept_rss_auth :index
|
||||
accept_api_auth :index, :show, :create, :update, :destroy
|
||||
|
||||
rescue_from Query::StatementInvalid, :with => :query_statement_invalid
|
||||
|
||||
helper :sort
|
||||
include SortHelper
|
||||
helper :issues
|
||||
include TimelogHelper
|
||||
helper :custom_fields
|
||||
include CustomFieldsHelper
|
||||
helper :queries
|
||||
include QueriesHelper
|
||||
|
||||
def index
|
||||
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
||||
scope = time_entry_scope
|
||||
|
||||
sort_init(@query.sort_criteria.empty? ? [['spent_on', 'desc']] : @query.sort_criteria)
|
||||
sort_update(@query.sortable_columns)
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
# Paginate results
|
||||
@entry_count = scope.count
|
||||
@entry_pages = Paginator.new @entry_count, per_page_option, params['page']
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => sort_clause,
|
||||
:limit => @entry_pages.per_page,
|
||||
:offset => @entry_pages.offset
|
||||
)
|
||||
@total_hours = scope.sum(:hours).to_f
|
||||
|
||||
render :layout => !request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@entry_count = scope.count
|
||||
@offset, @limit = api_offset_and_limit
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => sort_clause,
|
||||
:limit => @limit,
|
||||
:offset => @offset
|
||||
)
|
||||
}
|
||||
format.atom {
|
||||
entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => :tracker}],
|
||||
:order => "#{TimeEntry.table_name}.created_on DESC",
|
||||
:limit => Setting.feeds_limit.to_i
|
||||
)
|
||||
render_feed(entries, :title => l(:label_spent_time))
|
||||
}
|
||||
format.csv {
|
||||
# Export all entries
|
||||
@entries = scope.all(
|
||||
:include => [:project, :activity, :user, {:issue => [:tracker, :assigned_to, :priority]}],
|
||||
:order => sort_clause
|
||||
)
|
||||
send_data(query_to_csv(@entries, @query, params), :type => 'text/csv; header=present', :filename => 'timelog.csv')
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def report
|
||||
@query = TimeEntryQuery.build_from_params(params, :project => @project, :name => '_')
|
||||
scope = time_entry_scope
|
||||
|
||||
@report = Redmine::Helpers::TimeReport.new(@project, @issue, params[:criteria], params[:columns], scope)
|
||||
|
||||
respond_to do |format|
|
||||
format.html { render :layout => !request.xhr? }
|
||||
format.csv { send_data(report_to_csv(@report), :type => 'text/csv; header=present', :filename => 'timelog.csv') }
|
||||
end
|
||||
end
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
# TODO: Implement html response
|
||||
format.html { render :nothing => true, :status => 406 }
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
end
|
||||
|
||||
def create
|
||||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => User.current, :spent_on => User.current.today)
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
|
||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||
|
||||
if @time_entry.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
if params[:continue]
|
||||
if params[:project_id]
|
||||
options = {
|
||||
:time_entry => {:issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
|
||||
:back_url => params[:back_url]
|
||||
}
|
||||
if @time_entry.issue
|
||||
redirect_to new_project_issue_time_entry_url(@time_entry.project, @time_entry.issue, options)
|
||||
else
|
||||
redirect_to new_project_time_entry_url(@time_entry.project, options)
|
||||
end
|
||||
else
|
||||
options = {
|
||||
:time_entry => {:project_id => @time_entry.project_id, :issue_id => @time_entry.issue_id, :activity_id => @time_entry.activity_id},
|
||||
:back_url => params[:back_url]
|
||||
}
|
||||
redirect_to new_time_entry_url(options)
|
||||
end
|
||||
else
|
||||
redirect_back_or_default project_time_entries_path(@time_entry.project)
|
||||
end
|
||||
}
|
||||
format.api { render :action => 'show', :status => :created, :location => time_entry_url(@time_entry) }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new' }
|
||||
format.api { render_validation_errors(@time_entry) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
end
|
||||
|
||||
def update
|
||||
@time_entry.safe_attributes = params[:time_entry]
|
||||
|
||||
call_hook(:controller_timelog_edit_before_save, { :params => params, :time_entry => @time_entry })
|
||||
|
||||
if @time_entry.save
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_back_or_default project_time_entries_path(@time_entry.project)
|
||||
}
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@time_entry) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def bulk_edit
|
||||
@available_activities = TimeEntryActivity.shared.active
|
||||
@custom_fields = TimeEntry.first.available_custom_fields
|
||||
end
|
||||
|
||||
def bulk_update
|
||||
attributes = parse_params_for_bulk_time_entry_attributes(params)
|
||||
|
||||
unsaved_time_entry_ids = []
|
||||
@time_entries.each do |time_entry|
|
||||
time_entry.reload
|
||||
time_entry.safe_attributes = attributes
|
||||
call_hook(:controller_time_entries_bulk_edit_before_save, { :params => params, :time_entry => time_entry })
|
||||
unless time_entry.save
|
||||
# Keep unsaved time_entry ids to display them in flash error
|
||||
unsaved_time_entry_ids << time_entry.id
|
||||
end
|
||||
end
|
||||
set_flash_from_bulk_time_entry_save(@time_entries, unsaved_time_entry_ids)
|
||||
redirect_back_or_default project_time_entries_path(@projects.first)
|
||||
end
|
||||
|
||||
def destroy
|
||||
destroyed = TimeEntry.transaction do
|
||||
@time_entries.each do |t|
|
||||
unless t.destroy && t.destroyed?
|
||||
raise ActiveRecord::Rollback
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
if destroyed
|
||||
flash[:notice] = l(:notice_successful_delete)
|
||||
else
|
||||
flash[:error] = l(:notice_unable_delete_time_entry)
|
||||
end
|
||||
redirect_back_or_default project_time_entries_path(@projects.first)
|
||||
}
|
||||
format.api {
|
||||
if destroyed
|
||||
render_api_ok
|
||||
else
|
||||
render_validation_errors(@time_entries)
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_time_entry
|
||||
@time_entry = TimeEntry.find(params[:id])
|
||||
unless @time_entry.editable_by?(User.current)
|
||||
render_403
|
||||
return false
|
||||
end
|
||||
@project = @time_entry.project
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_time_entries
|
||||
@time_entries = TimeEntry.find_all_by_id(params[:id] || params[:ids])
|
||||
raise ActiveRecord::RecordNotFound if @time_entries.empty?
|
||||
@projects = @time_entries.collect(&:project).compact.uniq
|
||||
@project = @projects.first if @projects.size == 1
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def set_flash_from_bulk_time_entry_save(time_entries, unsaved_time_entry_ids)
|
||||
if unsaved_time_entry_ids.empty?
|
||||
flash[:notice] = l(:notice_successful_update) unless time_entries.empty?
|
||||
else
|
||||
flash[:error] = l(:notice_failed_to_save_time_entries,
|
||||
:count => unsaved_time_entry_ids.size,
|
||||
:total => time_entries.size,
|
||||
:ids => '#' + unsaved_time_entry_ids.join(', #'))
|
||||
end
|
||||
end
|
||||
|
||||
def find_optional_project_for_new_time_entry
|
||||
if (project_id = (params[:project_id] || params[:time_entry] && params[:time_entry][:project_id])).present?
|
||||
@project = Project.find(project_id)
|
||||
end
|
||||
if (issue_id = (params[:issue_id] || params[:time_entry] && params[:time_entry][:issue_id])).present?
|
||||
@issue = Issue.find(issue_id)
|
||||
@project ||= @issue.project
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def find_project_for_new_time_entry
|
||||
find_optional_project_for_new_time_entry
|
||||
if @project.nil?
|
||||
render_404
|
||||
end
|
||||
end
|
||||
|
||||
def find_optional_project
|
||||
if !params[:issue_id].blank?
|
||||
@issue = Issue.find(params[:issue_id])
|
||||
@project = @issue.project
|
||||
elsif !params[:project_id].blank?
|
||||
@project = Project.find(params[:project_id])
|
||||
end
|
||||
end
|
||||
|
||||
# Returns the TimeEntry scope for index and report actions
|
||||
def time_entry_scope
|
||||
scope = TimeEntry.visible.where(@query.statement)
|
||||
if @issue
|
||||
scope = scope.on_issue(@issue)
|
||||
elsif @project
|
||||
scope = scope.on_project(@project, Setting.display_subprojects_issues?)
|
||||
end
|
||||
scope
|
||||
end
|
||||
|
||||
def parse_params_for_bulk_time_entry_attributes(params)
|
||||
attributes = (params[:time_entry] || {}).reject {|k,v| v.blank?}
|
||||
attributes.keys.each {|k| attributes[k] = '' if attributes[k] == 'none'}
|
||||
attributes[:custom_field_values].reject! {|k,v| v.blank?} if attributes[:custom_field_values]
|
||||
attributes
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,108 +1,108 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class TrackersController < ApplicationController
|
||||
layout 'admin'
|
||||
helper "project_score"
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
accept_api_auth :index
|
||||
include CoursesHelper
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@trackers = Tracker.sorted.all
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@tracker ||= Tracker.new(params[:tracker])
|
||||
@trackers = Tracker.sorted.all
|
||||
@projects = Project.where("project_type = #{Project::ProjectType_project}").all
|
||||
@courses = Course.all
|
||||
@course_activity_count=Hash.new
|
||||
@courses.each do |course|
|
||||
@course_activity_count[course.id]=0
|
||||
end
|
||||
@course_activity_count=get_course_activity @courses,@course_activity_count
|
||||
end
|
||||
|
||||
def create
|
||||
@tracker = Tracker.new(params[:tracker])
|
||||
if @tracker.save
|
||||
# workflow copy
|
||||
if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
|
||||
@tracker.workflow_rules.copy(copy_from)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to trackers_url
|
||||
return
|
||||
end
|
||||
new
|
||||
render :action => 'new'
|
||||
end
|
||||
|
||||
def edit
|
||||
@tracker ||= Tracker.find(params[:id])
|
||||
@projects = Project.where("project_type = #{Project::ProjectType_project}").all
|
||||
@courses = Course.all
|
||||
end
|
||||
|
||||
def update
|
||||
@tracker = Tracker.find(params[:id])
|
||||
if @tracker.update_attributes(params[:tracker])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to trackers_url
|
||||
return
|
||||
end
|
||||
edit
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
||||
def destroy
|
||||
@tracker = Tracker.find(params[:id])
|
||||
unless @tracker.issues.empty?
|
||||
flash[:error] = l(:error_can_not_delete_tracker)
|
||||
else
|
||||
@tracker.destroy
|
||||
end
|
||||
redirect_to trackers_url
|
||||
end
|
||||
|
||||
def fields
|
||||
if request.post? && params[:trackers]
|
||||
params[:trackers].each do |tracker_id, tracker_params|
|
||||
tracker = Tracker.find_by_id(tracker_id)
|
||||
if tracker
|
||||
tracker.core_fields = tracker_params[:core_fields]
|
||||
tracker.custom_field_ids = tracker_params[:custom_field_ids]
|
||||
tracker.save
|
||||
end
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to fields_trackers_url
|
||||
return
|
||||
end
|
||||
@trackers = Tracker.sorted.all
|
||||
@custom_fields = IssueCustomField.all.sort
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class TrackersController < ApplicationController
|
||||
layout 'admin'
|
||||
helper "project_score"
|
||||
before_filter :require_admin, :except => :index
|
||||
before_filter :require_admin_or_api_request, :only => :index
|
||||
accept_api_auth :index
|
||||
include CoursesHelper
|
||||
def index
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@tracker_pages, @trackers = paginate Tracker.sorted, :per_page => 25
|
||||
render :action => "index", :layout => false if request.xhr?
|
||||
}
|
||||
format.api {
|
||||
@trackers = Tracker.sorted.all
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@tracker ||= Tracker.new(params[:tracker])
|
||||
@trackers = Tracker.sorted.all
|
||||
@projects = Project.where("project_type = #{Project::ProjectType_project}").all
|
||||
@courses = Course.all
|
||||
@course_activity_count=Hash.new
|
||||
@courses.each do |course|
|
||||
@course_activity_count[course.id]=0
|
||||
end
|
||||
@course_activity_count=get_course_activity @courses,@course_activity_count
|
||||
end
|
||||
|
||||
def create
|
||||
@tracker = Tracker.new(params[:tracker])
|
||||
if @tracker.save
|
||||
# workflow copy
|
||||
if !params[:copy_workflow_from].blank? && (copy_from = Tracker.find_by_id(params[:copy_workflow_from]))
|
||||
@tracker.workflow_rules.copy(copy_from)
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to trackers_url
|
||||
return
|
||||
end
|
||||
new
|
||||
render :action => 'new'
|
||||
end
|
||||
|
||||
def edit
|
||||
@tracker ||= Tracker.find(params[:id])
|
||||
@projects = Project.where("project_type = #{Project::ProjectType_project}").all
|
||||
@courses = Course.all
|
||||
end
|
||||
|
||||
def update
|
||||
@tracker = Tracker.find(params[:id])
|
||||
if @tracker.update_attributes(params[:tracker])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to trackers_url
|
||||
return
|
||||
end
|
||||
edit
|
||||
render :action => 'edit'
|
||||
end
|
||||
|
||||
def destroy
|
||||
@tracker = Tracker.find(params[:id])
|
||||
unless @tracker.issues.empty?
|
||||
flash[:error] = l(:error_can_not_delete_tracker)
|
||||
else
|
||||
@tracker.destroy
|
||||
end
|
||||
redirect_to trackers_url
|
||||
end
|
||||
|
||||
def fields
|
||||
if request.post? && params[:trackers]
|
||||
params[:trackers].each do |tracker_id, tracker_params|
|
||||
tracker = Tracker.find_by_id(tracker_id)
|
||||
if tracker
|
||||
tracker.core_fields = tracker_params[:core_fields]
|
||||
tracker.custom_field_ids = tracker_params[:custom_field_ids]
|
||||
tracker.save
|
||||
end
|
||||
end
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to fields_trackers_url
|
||||
return
|
||||
end
|
||||
@trackers = Tracker.sorted.all
|
||||
@custom_fields = IssueCustomField.all.sort
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +1,52 @@
|
|||
class WebFooterCompaniesController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :projects, :only => :projects
|
||||
menu_item :plugins, :only => :plugins
|
||||
menu_item :info, :only => :info
|
||||
before_filter :require_admin
|
||||
|
||||
def index
|
||||
@companys = WebFooterCompany.all
|
||||
end
|
||||
|
||||
def new
|
||||
@company ||= WebFooterCompany.new
|
||||
end
|
||||
|
||||
def create
|
||||
@company = WebFooterCompany.new(params[:web_footer_company])
|
||||
if @company.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to web_footer_companies_url
|
||||
else
|
||||
flash[:error] = "#{l :web_footer_company_create_fail}: #{@company.errors.full_messages[0]}"
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new'}
|
||||
format.api { render_validation_errors(@company) }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
@company.destroy
|
||||
redirect_to web_footer_companies_url
|
||||
end
|
||||
|
||||
def edit
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
if @company.update_attributes(params[:web_footer_company])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to web_footer_companies_url
|
||||
else
|
||||
flash[:error] = "#{l :web_footer_company_update_fail}: #{@company.errors.full_messages[0]}"
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
class WebFooterCompaniesController < ApplicationController
|
||||
layout 'admin'
|
||||
menu_item :projects, :only => :projects
|
||||
menu_item :plugins, :only => :plugins
|
||||
menu_item :info, :only => :info
|
||||
before_filter :require_admin
|
||||
|
||||
def index
|
||||
@companys = WebFooterCompany.all
|
||||
end
|
||||
|
||||
def new
|
||||
@company ||= WebFooterCompany.new
|
||||
end
|
||||
|
||||
def create
|
||||
@company = WebFooterCompany.new(params[:web_footer_company])
|
||||
if @company.save
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
redirect_to web_footer_companies_url
|
||||
else
|
||||
flash[:error] = "#{l :web_footer_company_create_fail}: #{@company.errors.full_messages[0]}"
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'new'}
|
||||
format.api { render_validation_errors(@company) }
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
@company.destroy
|
||||
redirect_to web_footer_companies_url
|
||||
end
|
||||
|
||||
def edit
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@company = WebFooterCompany.find(params[:id])
|
||||
if @company.update_attributes(params[:web_footer_company])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to web_footer_companies_url
|
||||
else
|
||||
flash[:error] = "#{l :web_footer_company_update_fail}: #{@company.errors.full_messages[0]}"
|
||||
render :action => 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,358 +1,358 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'diff'
|
||||
|
||||
# The WikiController follows the Rails REST controller pattern but with
|
||||
# a few differences
|
||||
#
|
||||
# * index - shows a list of WikiPages grouped by page or date
|
||||
# * new - not used
|
||||
# * create - not used
|
||||
# * show - will also show the form for creating a new wiki page
|
||||
# * edit - used to edit an existing or new page
|
||||
# * update - used to save a wiki page update to the database, including new pages
|
||||
# * destroy - normal
|
||||
#
|
||||
# Other member and collection methods are also used
|
||||
#
|
||||
# TODO: still being worked on
|
||||
class WikiController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :wiki_pages
|
||||
before_filter :find_wiki, :authorize
|
||||
before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
|
||||
before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
|
||||
accept_api_auth :index, :show, :update, :destroy
|
||||
before_filter :find_attachments, :only => [:preview]
|
||||
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
helper :watchers
|
||||
include Redmine::Export::PDF
|
||||
helper :project_score
|
||||
|
||||
# List of pages, sorted alphabetically and by parent (hierarchy)
|
||||
def index
|
||||
load_pages_for_index
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@pages_by_parent_id = @pages.group_by(&:parent_id)
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
# List of page, by last update
|
||||
def date_index
|
||||
load_pages_for_index
|
||||
@pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
|
||||
end
|
||||
|
||||
# display a page (in editing mode if it doesn't exist)
|
||||
def show
|
||||
if @page.new_record?
|
||||
if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
|
||||
edit
|
||||
render :action => 'edit'
|
||||
else
|
||||
render_404
|
||||
end
|
||||
return
|
||||
end
|
||||
if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
|
||||
deny_access
|
||||
return
|
||||
end
|
||||
@content = @page.content_for_version(params[:version])
|
||||
if User.current.allowed_to?(:export_wiki_pages, @project)
|
||||
if params[:format] == 'pdf'
|
||||
send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
|
||||
return
|
||||
elsif params[:format] == 'html'
|
||||
export = render_to_string :action => 'export', :layout => false
|
||||
send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
|
||||
return
|
||||
elsif params[:format] == 'txt'
|
||||
send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
|
||||
return
|
||||
end
|
||||
end
|
||||
@editable = editable?
|
||||
@sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
|
||||
@content.current_version? &&
|
||||
Redmine::WikiFormatting.supports_section_edit?
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
# edit an existing page or a new one
|
||||
def edit
|
||||
return render_403 unless editable?
|
||||
if @page.new_record?
|
||||
@page.content = WikiContent.new(:page => @page)
|
||||
if params[:parent].present?
|
||||
@page.parent = @page.wiki.find_page(params[:parent].to_s)
|
||||
end
|
||||
end
|
||||
|
||||
@content = @page.content_for_version(params[:version])
|
||||
@content.text = initial_page_content(@page) if @content.text.blank?
|
||||
# don't keep previous comment
|
||||
@content.comments = nil
|
||||
|
||||
# To prevent StaleObjectError exception when reverting to a previous version
|
||||
@content.version = @page.content.version
|
||||
|
||||
@text = @content.text
|
||||
if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
|
||||
@section = params[:section].to_i
|
||||
@text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
|
||||
render_404 if @text.blank?
|
||||
end
|
||||
end
|
||||
|
||||
# Creates a new page or updates an existing one
|
||||
def update
|
||||
return render_403 unless editable?
|
||||
was_new_page = @page.new_record?
|
||||
@page.content = WikiContent.new(:page => @page) if @page.new_record?
|
||||
@page.safe_attributes = params[:wiki_page]
|
||||
|
||||
@content = @page.content
|
||||
content_params = params[:content]
|
||||
if content_params.nil? && params[:wiki_page].is_a?(Hash)
|
||||
content_params = params[:wiki_page].slice(:text, :comments, :version)
|
||||
end
|
||||
content_params ||= {}
|
||||
|
||||
@content.comments = content_params[:comments]
|
||||
@text = content_params[:text]
|
||||
if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
|
||||
@section = params[:section].to_i
|
||||
@section_hash = params[:section_hash]
|
||||
@content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
|
||||
else
|
||||
@content.version = content_params[:version] if content_params[:version]
|
||||
@content.text = @text
|
||||
end
|
||||
@content.author = User.current
|
||||
|
||||
if @page.save_with_content
|
||||
attachments = Attachment.attach_files(@page, params[:attachments])
|
||||
render_attachment_warning_if_needed(@page)
|
||||
call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_wiki_page_url(@project, @page.title) }
|
||||
format.api {
|
||||
if was_new_page
|
||||
render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
|
||||
else
|
||||
render_api_ok
|
||||
end
|
||||
}
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@content) }
|
||||
end
|
||||
end
|
||||
|
||||
rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
|
||||
# Optimistic locking exception
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash.now[:error] = l(:notice_locking_conflict)
|
||||
render :action => 'edit'
|
||||
}
|
||||
format.api { render_api_head :conflict }
|
||||
end
|
||||
rescue ActiveRecord::RecordNotSaved
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@content) }
|
||||
end
|
||||
end
|
||||
|
||||
# rename a page
|
||||
def rename
|
||||
return render_403 unless editable?
|
||||
@page.redirect_existing_links = true
|
||||
# used to display the *original* title if some AR validation errors occur
|
||||
@original_title = @page.pretty_title
|
||||
if request.post? && @page.update_attributes(params[:wiki_page])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
def protect
|
||||
@page.update_attribute :protected, params[:protected]
|
||||
redirect_to project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
|
||||
# show page history
|
||||
def history
|
||||
@version_count = @page.content.versions.count
|
||||
@version_pages = Paginator.new @version_count, per_page_option, params['page']
|
||||
# don't load text
|
||||
@versions = @page.content.versions.
|
||||
select("id, author_id, comments, updated_on, version").
|
||||
reorder('version DESC').
|
||||
limit(@version_pages.per_page + 1).
|
||||
offset(@version_pages.offset).
|
||||
all
|
||||
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def diff
|
||||
@diff = @page.diff(params[:version], params[:version_from])
|
||||
render_404 unless @diff
|
||||
end
|
||||
|
||||
def annotate
|
||||
@annotate = @page.annotate(params[:version])
|
||||
render_404 unless @annotate
|
||||
end
|
||||
|
||||
# Removes a wiki page and its history
|
||||
# Children can be either set as root pages, removed or reassigned to another parent page
|
||||
def destroy
|
||||
return render_403 unless editable?
|
||||
|
||||
@descendants_count = @page.descendants.size
|
||||
if @descendants_count > 0
|
||||
case params[:todo]
|
||||
when 'nullify'
|
||||
# Nothing to do
|
||||
when 'destroy'
|
||||
# Removes all its descendants
|
||||
@page.descendants.each(&:destroy)
|
||||
when 'reassign'
|
||||
# Reassign children to another parent page
|
||||
reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
|
||||
return unless reassign_to
|
||||
@page.children.each do |child|
|
||||
child.update_attribute(:parent, reassign_to)
|
||||
end
|
||||
else
|
||||
@reassignable_to = @wiki.pages - @page.self_and_descendants
|
||||
# display the destroy form if it's a user request
|
||||
return unless api_request?
|
||||
end
|
||||
end
|
||||
@page.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_wiki_index_url(@project) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_version
|
||||
return render_403 unless editable?
|
||||
|
||||
@content = @page.content_for_version(params[:version])
|
||||
@content.destroy
|
||||
redirect_to_referer_or history_project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
|
||||
# Export wiki to a single pdf or html file
|
||||
def export
|
||||
@pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}])
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
export = render_to_string :action => 'export_multiple', :layout => false
|
||||
send_data(export, :type => 'text/html', :filename => "wiki.html")
|
||||
}
|
||||
format.pdf {
|
||||
send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def preview
|
||||
page = @wiki.find_page(params[:id])
|
||||
# page is nil when previewing a new page
|
||||
return render_403 unless page.nil? || editable?(page)
|
||||
if page
|
||||
@attachments += page.attachments
|
||||
@previewed = page.content
|
||||
end
|
||||
@text = params[:content][:text]
|
||||
render :partial => 'common/preview'
|
||||
end
|
||||
|
||||
def add_attachment
|
||||
return render_403 unless editable?
|
||||
attachments = Attachment.attach_files(@page, params[:attachments])
|
||||
render_attachment_warning_if_needed(@page)
|
||||
redirect_to :action => 'show', :id => @page.title, :project_id => @project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_wiki
|
||||
@project = Project.find(params[:project_id])
|
||||
@wiki = @project.wiki
|
||||
render_404 unless @wiki
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
# Finds the requested page or a new page if it doesn't exist
|
||||
def find_existing_or_new_page
|
||||
@page = @wiki.find_or_new_page(params[:id])
|
||||
if @wiki.page_found_with_redirect?
|
||||
redirect_to params.update(:id => @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
# Finds the requested page and returns a 404 error if it doesn't exist
|
||||
def find_existing_page
|
||||
@page = @wiki.find_page(params[:id])
|
||||
if @page.nil?
|
||||
render_404
|
||||
return
|
||||
end
|
||||
if @wiki.page_found_with_redirect?
|
||||
redirect_to params.update(:id => @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the current user is allowed to edit the page, otherwise false
|
||||
def editable?(page = @page)
|
||||
page.editable_by?(User.current)
|
||||
end
|
||||
|
||||
# Returns the default content of a new wiki page
|
||||
def initial_page_content(page)
|
||||
helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
|
||||
extend helper unless self.instance_of?(helper)
|
||||
helper.instance_method(:initial_page_content).bind(self).call(page)
|
||||
end
|
||||
|
||||
def load_pages_for_index
|
||||
@pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'diff'
|
||||
|
||||
# The WikiController follows the Rails REST controller pattern but with
|
||||
# a few differences
|
||||
#
|
||||
# * index - shows a list of WikiPages grouped by page or date
|
||||
# * new - not used
|
||||
# * create - not used
|
||||
# * show - will also show the form for creating a new wiki page
|
||||
# * edit - used to edit an existing or new page
|
||||
# * update - used to save a wiki page update to the database, including new pages
|
||||
# * destroy - normal
|
||||
#
|
||||
# Other member and collection methods are also used
|
||||
#
|
||||
# TODO: still being worked on
|
||||
class WikiController < ApplicationController
|
||||
layout 'base_projects'#by young
|
||||
default_search_scope :wiki_pages
|
||||
before_filter :find_wiki, :authorize
|
||||
before_filter :find_existing_or_new_page, :only => [:show, :edit, :update]
|
||||
before_filter :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
|
||||
accept_api_auth :index, :show, :update, :destroy
|
||||
before_filter :find_attachments, :only => [:preview]
|
||||
|
||||
helper :attachments
|
||||
include AttachmentsHelper
|
||||
helper :watchers
|
||||
include Redmine::Export::PDF
|
||||
helper :project_score
|
||||
|
||||
# List of pages, sorted alphabetically and by parent (hierarchy)
|
||||
def index
|
||||
load_pages_for_index
|
||||
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
@pages_by_parent_id = @pages.group_by(&:parent_id)
|
||||
}
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
# List of page, by last update
|
||||
def date_index
|
||||
load_pages_for_index
|
||||
@pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
|
||||
end
|
||||
|
||||
# display a page (in editing mode if it doesn't exist)
|
||||
def show
|
||||
if @page.new_record?
|
||||
if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
|
||||
edit
|
||||
render :action => 'edit'
|
||||
else
|
||||
render_404
|
||||
end
|
||||
return
|
||||
end
|
||||
if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
|
||||
deny_access
|
||||
return
|
||||
end
|
||||
@content = @page.content_for_version(params[:version])
|
||||
if User.current.allowed_to?(:export_wiki_pages, @project)
|
||||
if params[:format] == 'pdf'
|
||||
send_data(wiki_page_to_pdf(@page, @project), :type => 'application/pdf', :filename => "#{@page.title}.pdf")
|
||||
return
|
||||
elsif params[:format] == 'html'
|
||||
export = render_to_string :action => 'export', :layout => false
|
||||
send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
|
||||
return
|
||||
elsif params[:format] == 'txt'
|
||||
send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
|
||||
return
|
||||
end
|
||||
end
|
||||
@editable = editable?
|
||||
@sections_editable = @editable && User.current.allowed_to?(:edit_wiki_pages, @page.project) &&
|
||||
@content.current_version? &&
|
||||
Redmine::WikiFormatting.supports_section_edit?
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.api
|
||||
end
|
||||
end
|
||||
|
||||
# edit an existing page or a new one
|
||||
def edit
|
||||
return render_403 unless editable?
|
||||
if @page.new_record?
|
||||
@page.content = WikiContent.new(:page => @page)
|
||||
if params[:parent].present?
|
||||
@page.parent = @page.wiki.find_page(params[:parent].to_s)
|
||||
end
|
||||
end
|
||||
|
||||
@content = @page.content_for_version(params[:version])
|
||||
@content.text = initial_page_content(@page) if @content.text.blank?
|
||||
# don't keep previous comment
|
||||
@content.comments = nil
|
||||
|
||||
# To prevent StaleObjectError exception when reverting to a previous version
|
||||
@content.version = @page.content.version
|
||||
|
||||
@text = @content.text
|
||||
if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
|
||||
@section = params[:section].to_i
|
||||
@text, @section_hash = Redmine::WikiFormatting.formatter.new(@text).get_section(@section)
|
||||
render_404 if @text.blank?
|
||||
end
|
||||
end
|
||||
|
||||
# Creates a new page or updates an existing one
|
||||
def update
|
||||
return render_403 unless editable?
|
||||
was_new_page = @page.new_record?
|
||||
@page.content = WikiContent.new(:page => @page) if @page.new_record?
|
||||
@page.safe_attributes = params[:wiki_page]
|
||||
|
||||
@content = @page.content
|
||||
content_params = params[:content]
|
||||
if content_params.nil? && params[:wiki_page].is_a?(Hash)
|
||||
content_params = params[:wiki_page].slice(:text, :comments, :version)
|
||||
end
|
||||
content_params ||= {}
|
||||
|
||||
@content.comments = content_params[:comments]
|
||||
@text = content_params[:text]
|
||||
if params[:section].present? && Redmine::WikiFormatting.supports_section_edit?
|
||||
@section = params[:section].to_i
|
||||
@section_hash = params[:section_hash]
|
||||
@content.text = Redmine::WikiFormatting.formatter.new(@content.text).update_section(params[:section].to_i, @text, @section_hash)
|
||||
else
|
||||
@content.version = content_params[:version] if content_params[:version]
|
||||
@content.text = @text
|
||||
end
|
||||
@content.author = User.current
|
||||
|
||||
if @page.save_with_content
|
||||
attachments = Attachment.attach_files(@page, params[:attachments])
|
||||
render_attachment_warning_if_needed(@page)
|
||||
call_hook(:controller_wiki_edit_after_save, { :params => params, :page => @page})
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_wiki_page_url(@project, @page.title) }
|
||||
format.api {
|
||||
if was_new_page
|
||||
render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
|
||||
else
|
||||
render_api_ok
|
||||
end
|
||||
}
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@content) }
|
||||
end
|
||||
end
|
||||
|
||||
rescue ActiveRecord::StaleObjectError, Redmine::WikiFormatting::StaleSectionError
|
||||
# Optimistic locking exception
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
flash.now[:error] = l(:notice_locking_conflict)
|
||||
render :action => 'edit'
|
||||
}
|
||||
format.api { render_api_head :conflict }
|
||||
end
|
||||
rescue ActiveRecord::RecordNotSaved
|
||||
respond_to do |format|
|
||||
format.html { render :action => 'edit' }
|
||||
format.api { render_validation_errors(@content) }
|
||||
end
|
||||
end
|
||||
|
||||
# rename a page
|
||||
def rename
|
||||
return render_403 unless editable?
|
||||
@page.redirect_existing_links = true
|
||||
# used to display the *original* title if some AR validation errors occur
|
||||
@original_title = @page.pretty_title
|
||||
if request.post? && @page.update_attributes(params[:wiki_page])
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
def protect
|
||||
@page.update_attribute :protected, params[:protected]
|
||||
redirect_to project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
|
||||
# show page history
|
||||
def history
|
||||
@version_count = @page.content.versions.count
|
||||
@version_pages = Paginator.new @version_count, per_page_option, params['page']
|
||||
# don't load text
|
||||
@versions = @page.content.versions.
|
||||
select("id, author_id, comments, updated_on, version").
|
||||
reorder('version DESC').
|
||||
limit(@version_pages.per_page + 1).
|
||||
offset(@version_pages.offset).
|
||||
all
|
||||
|
||||
render :layout => false if request.xhr?
|
||||
end
|
||||
|
||||
def diff
|
||||
@diff = @page.diff(params[:version], params[:version_from])
|
||||
render_404 unless @diff
|
||||
end
|
||||
|
||||
def annotate
|
||||
@annotate = @page.annotate(params[:version])
|
||||
render_404 unless @annotate
|
||||
end
|
||||
|
||||
# Removes a wiki page and its history
|
||||
# Children can be either set as root pages, removed or reassigned to another parent page
|
||||
def destroy
|
||||
return render_403 unless editable?
|
||||
|
||||
@descendants_count = @page.descendants.size
|
||||
if @descendants_count > 0
|
||||
case params[:todo]
|
||||
when 'nullify'
|
||||
# Nothing to do
|
||||
when 'destroy'
|
||||
# Removes all its descendants
|
||||
@page.descendants.each(&:destroy)
|
||||
when 'reassign'
|
||||
# Reassign children to another parent page
|
||||
reassign_to = @wiki.pages.find_by_id(params[:reassign_to_id].to_i)
|
||||
return unless reassign_to
|
||||
@page.children.each do |child|
|
||||
child.update_attribute(:parent, reassign_to)
|
||||
end
|
||||
else
|
||||
@reassignable_to = @wiki.pages - @page.self_and_descendants
|
||||
# display the destroy form if it's a user request
|
||||
return unless api_request?
|
||||
end
|
||||
end
|
||||
@page.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to project_wiki_index_url(@project) }
|
||||
format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_version
|
||||
return render_403 unless editable?
|
||||
|
||||
@content = @page.content_for_version(params[:version])
|
||||
@content.destroy
|
||||
redirect_to_referer_or history_project_wiki_page_url(@project, @page.title)
|
||||
end
|
||||
|
||||
# Export wiki to a single pdf or html file
|
||||
def export
|
||||
@pages = @wiki.pages.all(:order => 'title', :include => [:content, {:attachments => :author}])
|
||||
respond_to do |format|
|
||||
format.html {
|
||||
export = render_to_string :action => 'export_multiple', :layout => false
|
||||
send_data(export, :type => 'text/html', :filename => "wiki.html")
|
||||
}
|
||||
format.pdf {
|
||||
send_data(wiki_pages_to_pdf(@pages, @project), :type => 'application/pdf', :filename => "#{@project.identifier}.pdf")
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def preview
|
||||
page = @wiki.find_page(params[:id])
|
||||
# page is nil when previewing a new page
|
||||
return render_403 unless page.nil? || editable?(page)
|
||||
if page
|
||||
@attachments += page.attachments
|
||||
@previewed = page.content
|
||||
end
|
||||
@text = params[:content][:text]
|
||||
render :partial => 'common/preview'
|
||||
end
|
||||
|
||||
def add_attachment
|
||||
return render_403 unless editable?
|
||||
attachments = Attachment.attach_files(@page, params[:attachments])
|
||||
render_attachment_warning_if_needed(@page)
|
||||
redirect_to :action => 'show', :id => @page.title, :project_id => @project
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_wiki
|
||||
@project = Project.find(params[:project_id])
|
||||
@wiki = @project.wiki
|
||||
render_404 unless @wiki
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
# Finds the requested page or a new page if it doesn't exist
|
||||
def find_existing_or_new_page
|
||||
@page = @wiki.find_or_new_page(params[:id])
|
||||
if @wiki.page_found_with_redirect?
|
||||
redirect_to params.update(:id => @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
# Finds the requested page and returns a 404 error if it doesn't exist
|
||||
def find_existing_page
|
||||
@page = @wiki.find_page(params[:id])
|
||||
if @page.nil?
|
||||
render_404
|
||||
return
|
||||
end
|
||||
if @wiki.page_found_with_redirect?
|
||||
redirect_to params.update(:id => @page.title)
|
||||
end
|
||||
end
|
||||
|
||||
# Returns true if the current user is allowed to edit the page, otherwise false
|
||||
def editable?(page = @page)
|
||||
page.editable_by?(User.current)
|
||||
end
|
||||
|
||||
# Returns the default content of a new wiki page
|
||||
def initial_page_content(page)
|
||||
helper = Redmine::WikiFormatting.helper_for(Setting.text_formatting)
|
||||
extend helper unless self.instance_of?(helper)
|
||||
helper.instance_method(:initial_page_content).bind(self).call(page)
|
||||
end
|
||||
|
||||
def load_pages_for_index
|
||||
@pages = @wiki.pages.with_updated_on.reorder("#{WikiPage.table_name}.title").includes(:wiki => :project).includes(:parent).all
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class WikisController < ApplicationController
|
||||
menu_item :settings
|
||||
before_filter :find_project, :authorize
|
||||
|
||||
# Create or update a project's wiki
|
||||
def edit
|
||||
@wiki = @project.wiki || Wiki.new(:project => @project)
|
||||
@wiki.safe_attributes = params[:wiki]
|
||||
@wiki.save if request.post?
|
||||
end
|
||||
|
||||
# Delete a project's wiki
|
||||
def destroy
|
||||
if request.post? && params[:confirm] && @project.wiki
|
||||
@project.wiki.destroy
|
||||
redirect_to settings_project_url(@project, :tab => 'wiki')
|
||||
end
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class WikisController < ApplicationController
|
||||
menu_item :settings
|
||||
before_filter :find_project, :authorize
|
||||
|
||||
# Create or update a project's wiki
|
||||
def edit
|
||||
@wiki = @project.wiki || Wiki.new(:project => @project)
|
||||
@wiki.safe_attributes = params[:wiki]
|
||||
@wiki.save if request.post?
|
||||
end
|
||||
|
||||
# Delete a project's wiki
|
||||
def destroy
|
||||
if request.post? && params[:confirm] && @project.wiki
|
||||
@project.wiki.destroy
|
||||
redirect_to settings_project_url(@project, :tab => 'wiki')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,283 +1,283 @@
|
|||
# encoding: utf-8
|
||||
#####leave message fq
|
||||
class WordsController < ApplicationController
|
||||
|
||||
before_filter :find_user, :only => [:new, :create, :destroy, :more, :back]
|
||||
def create
|
||||
if params[:new_form][:user_message].size>0
|
||||
unless params[:user_id].nil?
|
||||
if params[:reference_content]
|
||||
message = params[:new_form][:user_message] + "\n" + params[:reference_content]
|
||||
else
|
||||
message = params[:new_form][:user_message]
|
||||
end
|
||||
refer_user_id = params[:new_form][:reference_user_id].to_i
|
||||
|
||||
@user.add_jour(User.current, message, refer_user_id)
|
||||
unless refer_user_id == 0 || refer_user_id == User.current.id
|
||||
User.find(refer_user_id).add_jour(User.current, message, refer_user_id)
|
||||
end
|
||||
@user.count_new_jour
|
||||
# if a_message.size > 5
|
||||
# @message = a_message[-5, 5]
|
||||
# else
|
||||
# @message = a_message
|
||||
# end
|
||||
# @message_count = a_message.count
|
||||
end
|
||||
end
|
||||
@jours = @user.journals_for_messages.where('m_parent_id IS NULL').reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
|
||||
respond_to do |format|
|
||||
# format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def create_reply
|
||||
# 这里是创建回复所使用的方法,此方法只针对回复,每一个新的留言并不在此方法管理范围内。
|
||||
# 由于多个地方用到了留言,而之前的表设计也有jour_type/jour_id这类信息
|
||||
# 所以在方法 add_reply_adapter 中判断所有调用此方法的来源页面,
|
||||
# 为了保证兼容以往所有的代码,保证以往的方法可以调用,在返回页面中都做了各式各样的判断。
|
||||
# 页面保证 render new_respond/journal_reply
|
||||
# 修改 add_reply_adapter 中可以确保留言创建成功
|
||||
# 删除留言功能要调用destroy,也记得在destroy.js中修改
|
||||
|
||||
# deny api. api useless
|
||||
parent_id = params[:reference_id]
|
||||
author_id = User.current.id
|
||||
reply_user_id = params[:reference_user_id]
|
||||
reply_id = params[:reference_message_id] # 暂时不实现
|
||||
content = params[:user_notes]
|
||||
options = {:user_id => author_id,
|
||||
:status => true,
|
||||
:m_parent_id => parent_id,
|
||||
:m_reply_id => reply_id,
|
||||
:reply_id => reply_user_id,
|
||||
:notes => content,
|
||||
:is_readed => false}
|
||||
@jfm = add_reply_adapter options
|
||||
|
||||
respond_to do |format|
|
||||
# format.html {
|
||||
# if @jfm.errors.empty?
|
||||
# flash.now.notice = l(:label_feedback_success)
|
||||
# else
|
||||
# flash.now.errors = l(:label_feedback_fail)
|
||||
# end
|
||||
# render 'test/index'
|
||||
# }
|
||||
format.js{
|
||||
@save_succ = true if @jfm.errors.empty?
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@journal_destroyed = JournalsForMessage.delete_message(params[:object_id])
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def destroyJournal
|
||||
@journalP=JournalsForMessage.find(params[:object_id])
|
||||
@journalP.destroy
|
||||
|
||||
@page = params[:page]
|
||||
@page = @page.to_i
|
||||
@project = Project.find params[:project_id]
|
||||
# Find the page of the requested reply
|
||||
@jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
|
||||
@limit = 10
|
||||
|
||||
offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i])
|
||||
page = 1 + offset / @limit
|
||||
if params[:r] && @page.nil?
|
||||
@page = page
|
||||
end
|
||||
|
||||
if @page < 0
|
||||
@page = 1
|
||||
end
|
||||
if @page > page
|
||||
@page = page
|
||||
end
|
||||
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, @page
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
@base_courses_tag = @project.project_type
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id]
|
||||
if @jour
|
||||
user = @jour.user
|
||||
text = @jour.notes
|
||||
else
|
||||
user = @user
|
||||
text = []
|
||||
end
|
||||
# Replaces pre blocks with [...]
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
|
||||
# @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
# @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> "
|
||||
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def more
|
||||
@jours = @user.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = true
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def back
|
||||
@jours = @user.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def add_project_respond
|
||||
user = User.current
|
||||
message = params[:new_form][:project_message]
|
||||
Project.add_jour(user, message)
|
||||
|
||||
redirect_to project_feedback_url('trustie')
|
||||
# redirect_to signin_path
|
||||
end
|
||||
|
||||
def leave_project_message
|
||||
user = User.current
|
||||
message = params[:new_form][:project_message]
|
||||
feedback = Project.add_new_jour(user, message, params[:id])
|
||||
if(feedback.errors.empty?)
|
||||
redirect_to project_feedback_url(params[:id]), notice: l(:label_feedback_success)
|
||||
else
|
||||
flash[:error] = feedback.errors.full_messages[0]
|
||||
redirect_to project_feedback_url(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# add by nwb
|
||||
def leave_course_message
|
||||
user = User.current
|
||||
message = params[:new_form][:course_message]
|
||||
feedback = Course.add_new_jour(user, message, params[:id])
|
||||
if(feedback.errors.empty?)
|
||||
redirect_to course_feedback_url(params[:id]), notice: l(:label_feedback_success)
|
||||
else
|
||||
flash[:error] = feedback.errors.full_messages[0]
|
||||
redirect_to course_feedback_url(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def add_brief_introdution
|
||||
user = User.current
|
||||
message = params[:new_form][:user_introduction]
|
||||
UserExtensions.introduction(user, message)
|
||||
redirect_to user_url(user.id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_user
|
||||
if params[:user_id]
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
rescue
|
||||
render_404
|
||||
end
|
||||
|
||||
def obj_distinguish_url_origin
|
||||
#modify by nwb
|
||||
#添加对课程留言的支持
|
||||
referer = request.headers["Referer"]
|
||||
obj_id = referer.match(%r(/([0-9]{1,})(/|\?|$)))[1]
|
||||
if referer.match(/project/)
|
||||
obj = Project.find_by_id(obj_id)
|
||||
elsif referer.match(/course/)
|
||||
obj = Course.find_by_id(obj_id)
|
||||
elsif referer.match(/user/)
|
||||
obj = User.find_by_id(obj_id)
|
||||
elsif ( referer.match(/bids/) || referer.match(/calls/) )
|
||||
obj = Bid.find_by_id(obj_id)
|
||||
elsif ( referer.match(/contests/) || referer.match(/contests/) ) #new added
|
||||
obj = Contest.find_by_id(obj_id)
|
||||
elsif ( referer.match(/softapplications/) || referer.match(/softapplications/) ) #new added
|
||||
obj = Softapplication.find_by_id(obj_id)
|
||||
elsif ( referer.match(/homework_attach/) || referer.match(/homework_attach/) ) #new added
|
||||
obj = HomeworkAttach.find_by_id(obj_id)
|
||||
else
|
||||
raise "create reply obj unknow type.#{referer}"
|
||||
end
|
||||
obj
|
||||
end
|
||||
|
||||
def add_reply_adapter options
|
||||
#modify by nwb
|
||||
#添加对课程留言的支持
|
||||
obj = obj_distinguish_url_origin
|
||||
if obj.kind_of? User
|
||||
obj.add_jour(nil, nil, nil, options)
|
||||
elsif obj.kind_of? Project
|
||||
Project.add_new_jour(nil, nil, obj.id, options)
|
||||
elsif obj.kind_of? Course
|
||||
Course.add_new_jour(nil, nil, obj.id, options)
|
||||
elsif obj.kind_of? Bid
|
||||
obj.add_jour(nil, nil, nil, options)
|
||||
elsif obj.kind_of? Contest
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
elsif obj.kind_of? Softapplication
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
elsif obj.kind_of? HomeworkAttach
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
else
|
||||
raise "create reply obj unknow type.#{obj.class}"
|
||||
end
|
||||
end
|
||||
#######end of message
|
||||
end
|
||||
# encoding: utf-8
|
||||
#####leave message fq
|
||||
class WordsController < ApplicationController
|
||||
|
||||
before_filter :find_user, :only => [:new, :create, :destroy, :more, :back]
|
||||
def create
|
||||
if params[:new_form][:user_message].size>0
|
||||
unless params[:user_id].nil?
|
||||
if params[:reference_content]
|
||||
message = params[:new_form][:user_message] + "\n" + params[:reference_content]
|
||||
else
|
||||
message = params[:new_form][:user_message]
|
||||
end
|
||||
refer_user_id = params[:new_form][:reference_user_id].to_i
|
||||
|
||||
@user.add_jour(User.current, message, refer_user_id)
|
||||
unless refer_user_id == 0 || refer_user_id == User.current.id
|
||||
User.find(refer_user_id).add_jour(User.current, message, refer_user_id)
|
||||
end
|
||||
@user.count_new_jour
|
||||
# if a_message.size > 5
|
||||
# @message = a_message[-5, 5]
|
||||
# else
|
||||
# @message = a_message
|
||||
# end
|
||||
# @message_count = a_message.count
|
||||
end
|
||||
end
|
||||
@jours = @user.journals_for_messages.where('m_parent_id IS NULL').reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
|
||||
respond_to do |format|
|
||||
# format.html { redirect_to_referer_or {render :text => 'Watcher added.', :layout => true}}
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def create_reply
|
||||
# 这里是创建回复所使用的方法,此方法只针对回复,每一个新的留言并不在此方法管理范围内。
|
||||
# 由于多个地方用到了留言,而之前的表设计也有jour_type/jour_id这类信息
|
||||
# 所以在方法 add_reply_adapter 中判断所有调用此方法的来源页面,
|
||||
# 为了保证兼容以往所有的代码,保证以往的方法可以调用,在返回页面中都做了各式各样的判断。
|
||||
# 页面保证 render new_respond/journal_reply
|
||||
# 修改 add_reply_adapter 中可以确保留言创建成功
|
||||
# 删除留言功能要调用destroy,也记得在destroy.js中修改
|
||||
|
||||
# deny api. api useless
|
||||
parent_id = params[:reference_id]
|
||||
author_id = User.current.id
|
||||
reply_user_id = params[:reference_user_id]
|
||||
reply_id = params[:reference_message_id] # 暂时不实现
|
||||
content = params[:user_notes]
|
||||
options = {:user_id => author_id,
|
||||
:status => true,
|
||||
:m_parent_id => parent_id,
|
||||
:m_reply_id => reply_id,
|
||||
:reply_id => reply_user_id,
|
||||
:notes => content,
|
||||
:is_readed => false}
|
||||
@jfm = add_reply_adapter options
|
||||
|
||||
respond_to do |format|
|
||||
# format.html {
|
||||
# if @jfm.errors.empty?
|
||||
# flash.now.notice = l(:label_feedback_success)
|
||||
# else
|
||||
# flash.now.errors = l(:label_feedback_fail)
|
||||
# end
|
||||
# render 'test/index'
|
||||
# }
|
||||
format.js{
|
||||
@save_succ = true if @jfm.errors.empty?
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
@journal_destroyed = JournalsForMessage.delete_message(params[:object_id])
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def destroyJournal
|
||||
@journalP=JournalsForMessage.find(params[:object_id])
|
||||
@journalP.destroy
|
||||
|
||||
@page = params[:page]
|
||||
@page = @page.to_i
|
||||
@project = Project.find params[:project_id]
|
||||
# Find the page of the requested reply
|
||||
@jours = @project.journals_for_messages.where('m_parent_id IS NULL').order('created_on DESC')
|
||||
@limit = 10
|
||||
|
||||
offset = @jours.count(:conditions => ["#{JournalsForMessage.table_name}.id > ?", params[:r].to_i])
|
||||
page = 1 + offset / @limit
|
||||
if params[:r] && @page.nil?
|
||||
@page = page
|
||||
end
|
||||
|
||||
if @page < 0
|
||||
@page = 1
|
||||
end
|
||||
if @page > page
|
||||
@page = page
|
||||
end
|
||||
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, @page
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
@base_courses_tag = @project.project_type
|
||||
|
||||
respond_to do |format|
|
||||
format.js
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@jour = JournalsForMessage.find(params[:journal_id]) if params[:journal_id]
|
||||
if @jour
|
||||
user = @jour.user
|
||||
text = @jour.notes
|
||||
else
|
||||
user = @user
|
||||
text = []
|
||||
end
|
||||
# Replaces pre blocks with [...]
|
||||
text = text.to_s.strip.gsub(%r{<pre>((.|\s)*?)</pre>}m, '[...]')
|
||||
@content = "> #{ll(User.current.language, :text_user_wrote, user)}\n> "
|
||||
@content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
|
||||
# @content << text.gsub(/(\r?\n|\r\n?)/, "\n> ") + "\n\n"
|
||||
# @content = "> #{ll(Setting.default_language, :text_user_wrote, user)}\n> "
|
||||
|
||||
@id = user.id
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render_404
|
||||
end
|
||||
|
||||
def more
|
||||
@jours = @user.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = true
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def back
|
||||
@jours = @user.journals_for_messages.reverse
|
||||
@limit = 10
|
||||
@feedback_count = @jours.count
|
||||
@feedback_pages = Paginator.new @feedback_count, @limit, params['page']
|
||||
@offset ||= @feedback_pages.offset
|
||||
@jour = @jours[@offset, @limit]
|
||||
@state = false
|
||||
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.js
|
||||
#format.api { render_api_ok }
|
||||
end
|
||||
end
|
||||
|
||||
def add_project_respond
|
||||
user = User.current
|
||||
message = params[:new_form][:project_message]
|
||||
Project.add_jour(user, message)
|
||||
|
||||
redirect_to project_feedback_url('trustie')
|
||||
# redirect_to signin_path
|
||||
end
|
||||
|
||||
def leave_project_message
|
||||
user = User.current
|
||||
message = params[:new_form][:project_message]
|
||||
feedback = Project.add_new_jour(user, message, params[:id])
|
||||
if(feedback.errors.empty?)
|
||||
redirect_to project_feedback_url(params[:id]), notice: l(:label_feedback_success)
|
||||
else
|
||||
flash[:error] = feedback.errors.full_messages[0]
|
||||
redirect_to project_feedback_url(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# add by nwb
|
||||
def leave_course_message
|
||||
user = User.current
|
||||
message = params[:new_form][:course_message]
|
||||
feedback = Course.add_new_jour(user, message, params[:id])
|
||||
if(feedback.errors.empty?)
|
||||
redirect_to course_feedback_url(params[:id]), notice: l(:label_feedback_success)
|
||||
else
|
||||
flash[:error] = feedback.errors.full_messages[0]
|
||||
redirect_to course_feedback_url(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def add_brief_introdution
|
||||
user = User.current
|
||||
message = params[:new_form][:user_introduction]
|
||||
UserExtensions.introduction(user, message)
|
||||
redirect_to user_url(user.id)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_user
|
||||
if params[:user_id]
|
||||
@user = User.find(params[:user_id])
|
||||
end
|
||||
rescue
|
||||
render_404
|
||||
end
|
||||
|
||||
def obj_distinguish_url_origin
|
||||
#modify by nwb
|
||||
#添加对课程留言的支持
|
||||
referer = request.headers["Referer"]
|
||||
obj_id = referer.match(%r(/([0-9]{1,})(/|\?|$)))[1]
|
||||
if referer.match(/project/)
|
||||
obj = Project.find_by_id(obj_id)
|
||||
elsif referer.match(/course/)
|
||||
obj = Course.find_by_id(obj_id)
|
||||
elsif referer.match(/user/)
|
||||
obj = User.find_by_id(obj_id)
|
||||
elsif ( referer.match(/bids/) || referer.match(/calls/) )
|
||||
obj = Bid.find_by_id(obj_id)
|
||||
elsif ( referer.match(/contests/) || referer.match(/contests/) ) #new added
|
||||
obj = Contest.find_by_id(obj_id)
|
||||
elsif ( referer.match(/softapplications/) || referer.match(/softapplications/) ) #new added
|
||||
obj = Softapplication.find_by_id(obj_id)
|
||||
elsif ( referer.match(/homework_attach/) || referer.match(/homework_attach/) ) #new added
|
||||
obj = HomeworkAttach.find_by_id(obj_id)
|
||||
else
|
||||
raise "create reply obj unknow type.#{referer}"
|
||||
end
|
||||
obj
|
||||
end
|
||||
|
||||
def add_reply_adapter options
|
||||
#modify by nwb
|
||||
#添加对课程留言的支持
|
||||
obj = obj_distinguish_url_origin
|
||||
if obj.kind_of? User
|
||||
obj.add_jour(nil, nil, nil, options)
|
||||
elsif obj.kind_of? Project
|
||||
Project.add_new_jour(nil, nil, obj.id, options)
|
||||
elsif obj.kind_of? Course
|
||||
Course.add_new_jour(nil, nil, obj.id, options)
|
||||
elsif obj.kind_of? Bid
|
||||
obj.add_jour(nil, nil, nil, options)
|
||||
elsif obj.kind_of? Contest
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
elsif obj.kind_of? Softapplication
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
elsif obj.kind_of? HomeworkAttach
|
||||
obj.add_jour(nil, nil, obj.id, options) #new added
|
||||
else
|
||||
raise "create reply obj unknow type.#{obj.class}"
|
||||
end
|
||||
end
|
||||
#######end of message
|
||||
end
|
||||
|
|
|
@ -1,128 +1,128 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class WorkflowsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :find_roles, :find_trackers
|
||||
|
||||
def index
|
||||
@workflow_counts = WorkflowTransition.count_by_tracker_and_role
|
||||
end
|
||||
|
||||
def edit
|
||||
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
|
||||
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
|
||||
|
||||
if request.post?
|
||||
WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
|
||||
(params[:issue_status] || []).each { |status_id, transitions|
|
||||
transitions.each { |new_status_id, options|
|
||||
author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
|
||||
assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
|
||||
WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
|
||||
}
|
||||
}
|
||||
if @role.save
|
||||
redirect_to workflows_edit_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
|
||||
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
|
||||
@statuses = @tracker.issue_statuses
|
||||
end
|
||||
@statuses ||= IssueStatus.sorted.all
|
||||
|
||||
if @tracker && @role && @statuses.any?
|
||||
workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all
|
||||
@workflows = {}
|
||||
@workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
|
||||
@workflows['author'] = workflows.select {|w| w.author}
|
||||
@workflows['assignee'] = workflows.select {|w| w.assignee}
|
||||
end
|
||||
end
|
||||
|
||||
def permissions
|
||||
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
|
||||
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
|
||||
|
||||
if request.post? && @role && @tracker
|
||||
WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
|
||||
redirect_to workflows_permissions_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
|
||||
return
|
||||
end
|
||||
|
||||
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
|
||||
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
|
||||
@statuses = @tracker.issue_statuses
|
||||
end
|
||||
@statuses ||= IssueStatus.sorted.all
|
||||
|
||||
if @role && @tracker
|
||||
@fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
|
||||
@custom_fields = @tracker.custom_fields
|
||||
|
||||
@permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w|
|
||||
h[w.old_status_id] ||= {}
|
||||
h[w.old_status_id][w.field_name] = w.rule
|
||||
h
|
||||
end
|
||||
@statuses.each {|status| @permissions[status.id] ||= {}}
|
||||
end
|
||||
end
|
||||
|
||||
def copy
|
||||
|
||||
if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
|
||||
@source_tracker = nil
|
||||
else
|
||||
@source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i)
|
||||
end
|
||||
if params[:source_role_id].blank? || params[:source_role_id] == 'any'
|
||||
@source_role = nil
|
||||
else
|
||||
@source_role = Role.find_by_id(params[:source_role_id].to_i)
|
||||
end
|
||||
|
||||
@target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids])
|
||||
@target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids])
|
||||
|
||||
if request.post?
|
||||
if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
|
||||
flash.now[:error] = l(:error_workflow_copy_source)
|
||||
elsif @target_trackers.blank? || @target_roles.blank?
|
||||
flash.now[:error] = l(:error_workflow_copy_target)
|
||||
else
|
||||
WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to workflows_copy_url(:source_tracker_id => @source_tracker, :source_role_id => @source_role)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_roles
|
||||
@roles = Role.sorted.all
|
||||
end
|
||||
|
||||
def find_trackers
|
||||
@trackers = Tracker.sorted.all
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class WorkflowsController < ApplicationController
|
||||
layout 'admin'
|
||||
|
||||
before_filter :require_admin, :find_roles, :find_trackers
|
||||
|
||||
def index
|
||||
@workflow_counts = WorkflowTransition.count_by_tracker_and_role
|
||||
end
|
||||
|
||||
def edit
|
||||
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
|
||||
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
|
||||
|
||||
if request.post?
|
||||
WorkflowTransition.destroy_all( ["role_id=? and tracker_id=?", @role.id, @tracker.id])
|
||||
(params[:issue_status] || []).each { |status_id, transitions|
|
||||
transitions.each { |new_status_id, options|
|
||||
author = options.is_a?(Array) && options.include?('author') && !options.include?('always')
|
||||
assignee = options.is_a?(Array) && options.include?('assignee') && !options.include?('always')
|
||||
WorkflowTransition.create(:role_id => @role.id, :tracker_id => @tracker.id, :old_status_id => status_id, :new_status_id => new_status_id, :author => author, :assignee => assignee)
|
||||
}
|
||||
}
|
||||
if @role.save
|
||||
redirect_to workflows_edit_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
|
||||
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
|
||||
@statuses = @tracker.issue_statuses
|
||||
end
|
||||
@statuses ||= IssueStatus.sorted.all
|
||||
|
||||
if @tracker && @role && @statuses.any?
|
||||
workflows = WorkflowTransition.where(:role_id => @role.id, :tracker_id => @tracker.id).all
|
||||
@workflows = {}
|
||||
@workflows['always'] = workflows.select {|w| !w.author && !w.assignee}
|
||||
@workflows['author'] = workflows.select {|w| w.author}
|
||||
@workflows['assignee'] = workflows.select {|w| w.assignee}
|
||||
end
|
||||
end
|
||||
|
||||
def permissions
|
||||
@role = Role.find_by_id(params[:role_id]) if params[:role_id]
|
||||
@tracker = Tracker.find_by_id(params[:tracker_id]) if params[:tracker_id]
|
||||
|
||||
if request.post? && @role && @tracker
|
||||
WorkflowPermission.replace_permissions(@tracker, @role, params[:permissions] || {})
|
||||
redirect_to workflows_permissions_url(:role_id => @role, :tracker_id => @tracker, :used_statuses_only => params[:used_statuses_only])
|
||||
return
|
||||
end
|
||||
|
||||
@used_statuses_only = (params[:used_statuses_only] == '0' ? false : true)
|
||||
if @tracker && @used_statuses_only && @tracker.issue_statuses.any?
|
||||
@statuses = @tracker.issue_statuses
|
||||
end
|
||||
@statuses ||= IssueStatus.sorted.all
|
||||
|
||||
if @role && @tracker
|
||||
@fields = (Tracker::CORE_FIELDS_ALL - @tracker.disabled_core_fields).map {|field| [field, l("field_"+field.sub(/_id$/, ''))]}
|
||||
@custom_fields = @tracker.custom_fields
|
||||
|
||||
@permissions = WorkflowPermission.where(:tracker_id => @tracker.id, :role_id => @role.id).all.inject({}) do |h, w|
|
||||
h[w.old_status_id] ||= {}
|
||||
h[w.old_status_id][w.field_name] = w.rule
|
||||
h
|
||||
end
|
||||
@statuses.each {|status| @permissions[status.id] ||= {}}
|
||||
end
|
||||
end
|
||||
|
||||
def copy
|
||||
|
||||
if params[:source_tracker_id].blank? || params[:source_tracker_id] == 'any'
|
||||
@source_tracker = nil
|
||||
else
|
||||
@source_tracker = Tracker.find_by_id(params[:source_tracker_id].to_i)
|
||||
end
|
||||
if params[:source_role_id].blank? || params[:source_role_id] == 'any'
|
||||
@source_role = nil
|
||||
else
|
||||
@source_role = Role.find_by_id(params[:source_role_id].to_i)
|
||||
end
|
||||
|
||||
@target_trackers = params[:target_tracker_ids].blank? ? nil : Tracker.find_all_by_id(params[:target_tracker_ids])
|
||||
@target_roles = params[:target_role_ids].blank? ? nil : Role.find_all_by_id(params[:target_role_ids])
|
||||
|
||||
if request.post?
|
||||
if params[:source_tracker_id].blank? || params[:source_role_id].blank? || (@source_tracker.nil? && @source_role.nil?)
|
||||
flash.now[:error] = l(:error_workflow_copy_source)
|
||||
elsif @target_trackers.blank? || @target_roles.blank?
|
||||
flash.now[:error] = l(:error_workflow_copy_target)
|
||||
else
|
||||
WorkflowRule.copy(@source_tracker, @source_role, @target_trackers, @target_roles)
|
||||
flash[:notice] = l(:notice_successful_update)
|
||||
redirect_to workflows_copy_url(:source_tracker_id => @source_tracker, :source_role_id => @source_role)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_roles
|
||||
@roles = Role.sorted.all
|
||||
end
|
||||
|
||||
def find_trackers
|
||||
@trackers = Tracker.sorted.all
|
||||
end
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,219 +1,219 @@
|
|||
# encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module AttachmentsHelper
|
||||
# Displays view/delete links to the attachments of the given object
|
||||
# Options:
|
||||
# :author -- author names are not displayed if set to false
|
||||
# :thumbails -- display thumbnails if enabled in settings
|
||||
|
||||
include Redmine::Pagination
|
||||
|
||||
def link_to_attachments(container, options = {})
|
||||
options.assert_valid_keys(:author, :thumbnails)
|
||||
|
||||
if container.attachments.any?
|
||||
options = {:deletable => container.attachments_deletable?, :author => true}.merge(options)
|
||||
render :partial => 'attachments/links',
|
||||
:locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)}
|
||||
end
|
||||
end
|
||||
|
||||
def attach_delete(project)
|
||||
if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.roles&Role.where('id = ? or id = ?', 3, 7)).size >0) || project.user_id == User.current.id)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def render_api_attachment(attachment, api)
|
||||
api.attachment do
|
||||
api.id attachment.id
|
||||
api.filename attachment.filename
|
||||
api.filesize attachment.filesize
|
||||
api.content_type attachment.content_type
|
||||
api.description attachment.description
|
||||
api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false)
|
||||
api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author
|
||||
api.created_on attachment.created_on
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_memo_attachments(container, options = {})
|
||||
options.assert_valid_keys(:author, :thumbnails)
|
||||
|
||||
if container.attachments.any?
|
||||
options = {:deletable => deletable?(container), :author => true}.merge(options)
|
||||
render :partial => 'attachments/links',
|
||||
:locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deletable? container, user=User.current
|
||||
User.current.logged? && (container.author == user || user.admin?)
|
||||
end
|
||||
|
||||
# this method is used to get all projects that tagged one tag
|
||||
# added by william
|
||||
def get_attachments_by_tag(tag_name)
|
||||
Attachment.tagged_with(tag_name).order('created_on desc')
|
||||
end
|
||||
|
||||
# this method is used to get all attachments that from one project and tagged one tag
|
||||
# added by Long Jun
|
||||
def get_attachments_by_project_tag(tag_name, obj)
|
||||
@project_id =nil
|
||||
if obj.container_type == 'Version'
|
||||
@project_id = Version.find(obj.container_id).project_id
|
||||
|
||||
elsif obj.container_type == 'Project'
|
||||
@project_id = obj.container_id
|
||||
|
||||
end
|
||||
attachments = Attachment.tagged_with(tag_name).order('created_on desc').where("(container_id = :project_id and container_type = 'Project') or
|
||||
(container_id in (select id from versions where project_id =:project_id) and container_type = 'Version')", {:project_id => @project_id})
|
||||
return attachments
|
||||
end
|
||||
|
||||
|
||||
def render_attachments_for_new_project(project, limit=nil)
|
||||
# 查询条件
|
||||
params[:q] ||= ""
|
||||
filename_condition = params[:q].strip
|
||||
|
||||
attachAll = Attachment.scoped
|
||||
# 当前项目所有资源
|
||||
# attachments = Attachment.find_all_by_container_type_and_container_id(project.class, project.id)
|
||||
# attachments = Attachment.where("container_type = '#{project.class}' and container_id = #{project.id}")
|
||||
|
||||
# 除去当前项目的所有资源
|
||||
nobelong_attach = Attachment.where("!(container_type = '#{project.class}' and container_id = #{project.id})") unless project.blank?
|
||||
|
||||
# 搜索域确定
|
||||
domain = project.nil? ? attachAll : nobelong_attach
|
||||
|
||||
# 搜索到的资源
|
||||
searched_attach = domain.where("is_public=1 and filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc')
|
||||
#searched_attach = private_filter searched_attach
|
||||
searched_attach = paginateHelper(searched_attach, 10)
|
||||
|
||||
s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments')
|
||||
links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options|
|
||||
link_to text, attachments_autocomplete_path( parameters.merge(:project_id=>project.id,:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
|
||||
# ================================================================================================
|
||||
|
||||
# attach_count = searched_attach.count
|
||||
# attach_pages = Redmine::Pagination::Paginator.new attach_count, 10, params['page'] #by young
|
||||
# attachs = searched_attach.offset(attach_pages.offset).limit(attach_pages.per_page).all
|
||||
|
||||
# s = content_tag('div', attachments_check_box_tags('attachment[attach][]', attachs), :id => 'attachments')
|
||||
# links = pagination_links_full(attach_pages, attach_count, :per_page_links => false) {|text, parameters, options|
|
||||
# link_to text, attachments_autocomplete_path( parameters.merge(:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
# return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
# return searched_attach.to_json
|
||||
end
|
||||
|
||||
# add by nwb
|
||||
def render_attachments_for_new_course(course, limit=nil)
|
||||
# 查询条件
|
||||
params[:q] ||= ""
|
||||
filename_condition = params[:q].strip
|
||||
|
||||
#attachAll = Attachment.where("author_id = #{User.current.id}")
|
||||
#
|
||||
## 除去当前课程的所有资源
|
||||
#nobelong_attach =
|
||||
|
||||
# 搜索域确定
|
||||
course.nil? ?
|
||||
domain=Attachment.where("author_id = #{User.current.id}")
|
||||
:
|
||||
domain=Attachment.where("author_id = #{User.current.id} and container_type = 'Course' and container_id <> #{course.id}") unless course.blank?
|
||||
|
||||
# 搜索到的资源
|
||||
searched_attach = domain.where("filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc')
|
||||
#searched_attach = private_filter searched_attach
|
||||
searched_attach = paginateHelper(searched_attach, 10)
|
||||
|
||||
#testattach = Attachment.public_attachments
|
||||
|
||||
s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments')
|
||||
links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options|
|
||||
link_to text, attachments_autocomplete_path( parameters.merge(:course_id=>course.id,:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
|
||||
end
|
||||
|
||||
def attachments_check_box_tags(name, attachs)
|
||||
s = ''
|
||||
attachs.each do |attach|
|
||||
s << "<label>#{ check_box_tag name, attach.id, false, :id => nil } #{h attach.filename}</label><br/>"
|
||||
end
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
# Modified by Longjun
|
||||
# 有参数的方法要加()
|
||||
def private_filter(resultSet)
|
||||
result = resultSet.to_a.dup
|
||||
|
||||
# modify by nwb
|
||||
#添加对课程资源文件的判断
|
||||
resultSet.map { |res|
|
||||
if(res.container.nil? ||
|
||||
(res.container.class.to_s=="Project" && res.container.is_public == false) ||
|
||||
(res.container.has_attribute?(:project) && res.container.project && res.container.project.is_public == false) ||
|
||||
(res.container.class.to_s=="HomeworkAttach" && res.container.bid.reward_type == 3) ||
|
||||
(res.container.class.to_s=="Course" && res.container.is_public == false) ||
|
||||
(res.container.has_attribute?(:course) && res.container.course && res.container.course.is_public == false)
|
||||
)
|
||||
result.delete(res)
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
# Modified by Longjun
|
||||
# include 应放在class/model 的开始处
|
||||
# include Redmine::Pagination
|
||||
# end
|
||||
|
||||
def paginateHelper (obj, pre_size=10)
|
||||
@obj_count = obj.count
|
||||
@obj_pages = Paginator.new @obj_count, pre_size, params['page']
|
||||
if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation
|
||||
obj.limit(@obj_pages.per_page).offset(@obj_pages.offset)
|
||||
elsif obj.kind_of? Array
|
||||
obj[@obj_pages.offset, @obj_pages.per_page]
|
||||
else
|
||||
logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}"
|
||||
raise RuntimeError, 'unknow type, Please input you type into this helper.'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
module AttachmentsHelper
|
||||
# Displays view/delete links to the attachments of the given object
|
||||
# Options:
|
||||
# :author -- author names are not displayed if set to false
|
||||
# :thumbails -- display thumbnails if enabled in settings
|
||||
|
||||
include Redmine::Pagination
|
||||
|
||||
def link_to_attachments(container, options = {})
|
||||
options.assert_valid_keys(:author, :thumbnails)
|
||||
|
||||
if container.attachments.any?
|
||||
options = {:deletable => container.attachments_deletable?, :author => true}.merge(options)
|
||||
render :partial => 'attachments/links',
|
||||
:locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)}
|
||||
end
|
||||
end
|
||||
|
||||
def attach_delete(project)
|
||||
if User.current.logged? && (User.current.admin? || (!Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.nil? && (Member.where('user_id = ? and project_id = ?', User.current.id, project.bid.courses.first.id).first.roles&Role.where('id = ? or id = ?', 3, 7)).size >0) || project.user_id == User.current.id)
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def render_api_attachment(attachment, api)
|
||||
api.attachment do
|
||||
api.id attachment.id
|
||||
api.filename attachment.filename
|
||||
api.filesize attachment.filesize
|
||||
api.content_type attachment.content_type
|
||||
api.description attachment.description
|
||||
api.content_url url_for(:controller => 'attachments', :action => 'download', :id => attachment, :filename => attachment.filename, :only_path => false)
|
||||
api.author(:id => attachment.author.id, :name => attachment.author.name) if attachment.author
|
||||
api.created_on attachment.created_on
|
||||
end
|
||||
end
|
||||
|
||||
def link_to_memo_attachments(container, options = {})
|
||||
options.assert_valid_keys(:author, :thumbnails)
|
||||
|
||||
if container.attachments.any?
|
||||
options = {:deletable => deletable?(container), :author => true}.merge(options)
|
||||
render :partial => 'attachments/links',
|
||||
:locals => {:attachments => container.attachments, :options => options, :thumbnails => (options[:thumbnails] && Setting.thumbnails_enabled?)}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def deletable? container, user=User.current
|
||||
User.current.logged? && (container.author == user || user.admin?)
|
||||
end
|
||||
|
||||
# this method is used to get all projects that tagged one tag
|
||||
# added by william
|
||||
def get_attachments_by_tag(tag_name)
|
||||
Attachment.tagged_with(tag_name).order('created_on desc')
|
||||
end
|
||||
|
||||
# this method is used to get all attachments that from one project and tagged one tag
|
||||
# added by Long Jun
|
||||
def get_attachments_by_project_tag(tag_name, obj)
|
||||
@project_id =nil
|
||||
if obj.container_type == 'Version'
|
||||
@project_id = Version.find(obj.container_id).project_id
|
||||
|
||||
elsif obj.container_type == 'Project'
|
||||
@project_id = obj.container_id
|
||||
|
||||
end
|
||||
attachments = Attachment.tagged_with(tag_name).order('created_on desc').where("(container_id = :project_id and container_type = 'Project') or
|
||||
(container_id in (select id from versions where project_id =:project_id) and container_type = 'Version')", {:project_id => @project_id})
|
||||
return attachments
|
||||
end
|
||||
|
||||
|
||||
def render_attachments_for_new_project(project, limit=nil)
|
||||
# 查询条件
|
||||
params[:q] ||= ""
|
||||
filename_condition = params[:q].strip
|
||||
|
||||
attachAll = Attachment.scoped
|
||||
# 当前项目所有资源
|
||||
# attachments = Attachment.find_all_by_container_type_and_container_id(project.class, project.id)
|
||||
# attachments = Attachment.where("container_type = '#{project.class}' and container_id = #{project.id}")
|
||||
|
||||
# 除去当前项目的所有资源
|
||||
nobelong_attach = Attachment.where("!(container_type = '#{project.class}' and container_id = #{project.id})") unless project.blank?
|
||||
|
||||
# 搜索域确定
|
||||
domain = project.nil? ? attachAll : nobelong_attach
|
||||
|
||||
# 搜索到的资源
|
||||
searched_attach = domain.where("is_public=1 and filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc')
|
||||
#searched_attach = private_filter searched_attach
|
||||
searched_attach = paginateHelper(searched_attach, 10)
|
||||
|
||||
s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments')
|
||||
links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options|
|
||||
link_to text, attachments_autocomplete_path( parameters.merge(:project_id=>project.id,:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
|
||||
# ================================================================================================
|
||||
|
||||
# attach_count = searched_attach.count
|
||||
# attach_pages = Redmine::Pagination::Paginator.new attach_count, 10, params['page'] #by young
|
||||
# attachs = searched_attach.offset(attach_pages.offset).limit(attach_pages.per_page).all
|
||||
|
||||
# s = content_tag('div', attachments_check_box_tags('attachment[attach][]', attachs), :id => 'attachments')
|
||||
# links = pagination_links_full(attach_pages, attach_count, :per_page_links => false) {|text, parameters, options|
|
||||
# link_to text, attachments_autocomplete_path( parameters.merge(:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
# return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
# return searched_attach.to_json
|
||||
end
|
||||
|
||||
# add by nwb
|
||||
def render_attachments_for_new_course(course, limit=nil)
|
||||
# 查询条件
|
||||
params[:q] ||= ""
|
||||
filename_condition = params[:q].strip
|
||||
|
||||
#attachAll = Attachment.where("author_id = #{User.current.id}")
|
||||
#
|
||||
## 除去当前课程的所有资源
|
||||
#nobelong_attach =
|
||||
|
||||
# 搜索域确定
|
||||
course.nil? ?
|
||||
domain=Attachment.where("author_id = #{User.current.id}")
|
||||
:
|
||||
domain=Attachment.where("author_id = #{User.current.id} and container_type = 'Course' and container_id <> #{course.id}") unless course.blank?
|
||||
|
||||
# 搜索到的资源
|
||||
searched_attach = domain.where("filename LIKE :like ", like:"%#{filename_condition}%").limit(limit).order('created_on desc')
|
||||
#searched_attach = private_filter searched_attach
|
||||
searched_attach = paginateHelper(searched_attach, 10)
|
||||
|
||||
#testattach = Attachment.public_attachments
|
||||
|
||||
s = content_tag('div', attachments_check_box_tags('attachment[attach][]', searched_attach), :id => 'attachments')
|
||||
links = pagination_links_full(@obj_pages, @obj_count, :per_page_links => false) {|text, parameters, options|
|
||||
link_to text, attachments_autocomplete_path( parameters.merge(:course_id=>course.id,:q => params[:q], :format => 'js')), :remote => true }
|
||||
|
||||
return s + content_tag('div', content_tag('ul', links), :class => 'pagination')
|
||||
|
||||
end
|
||||
|
||||
def attachments_check_box_tags(name, attachs)
|
||||
s = ''
|
||||
attachs.each do |attach|
|
||||
s << "<label>#{ check_box_tag name, attach.id, false, :id => nil } #{h attach.filename}</label><br/>"
|
||||
end
|
||||
s.html_safe
|
||||
end
|
||||
|
||||
# Modified by Longjun
|
||||
# 有参数的方法要加()
|
||||
def private_filter(resultSet)
|
||||
result = resultSet.to_a.dup
|
||||
|
||||
# modify by nwb
|
||||
#添加对课程资源文件的判断
|
||||
resultSet.map { |res|
|
||||
if(res.container.nil? ||
|
||||
(res.container.class.to_s=="Project" && res.container.is_public == false) ||
|
||||
(res.container.has_attribute?(:project) && res.container.project && res.container.project.is_public == false) ||
|
||||
(res.container.class.to_s=="HomeworkAttach" && res.container.bid.reward_type == 3) ||
|
||||
(res.container.class.to_s=="Course" && res.container.is_public == false) ||
|
||||
(res.container.has_attribute?(:course) && res.container.course && res.container.course.is_public == false)
|
||||
)
|
||||
result.delete(res)
|
||||
end
|
||||
}
|
||||
result
|
||||
end
|
||||
|
||||
# Modified by Longjun
|
||||
# include 应放在class/model 的开始处
|
||||
# include Redmine::Pagination
|
||||
# end
|
||||
|
||||
def paginateHelper (obj, pre_size=10)
|
||||
@obj_count = obj.count
|
||||
@obj_pages = Paginator.new @obj_count, pre_size, params['page']
|
||||
if obj.kind_of? ActiveRecord::Base or obj.kind_of? ActiveRecord::Relation
|
||||
obj.limit(@obj_pages.per_page).offset(@obj_pages.offset)
|
||||
elsif obj.kind_of? Array
|
||||
obj[@obj_pages.offset, @obj_pages.per_page]
|
||||
else
|
||||
logger.error "[ApplicationController] Error : application_controller#paginateHelper ===> unknow category: #{obj.class}"
|
||||
raise RuntimeError, 'unknow type, Please input you type into this helper.'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,27 +1,27 @@
|
|||
module LoggerHelper
|
||||
|
||||
#输出日志
|
||||
def OutLogger
|
||||
#日志输出级别
|
||||
#Rails.logger.level = Logger::INFO
|
||||
|
||||
if(!File.exist?("database"))
|
||||
Dir.mkdir("database")
|
||||
end
|
||||
if(!File.exist?("database/get"))
|
||||
Dir.mkdir("database/get")
|
||||
end
|
||||
if(!File.exist?("database/sql"))
|
||||
Dir.mkdir("database/sql")
|
||||
end
|
||||
if(!File.exist?("database/controller"))
|
||||
Dir.mkdir("database/controller")
|
||||
end
|
||||
|
||||
Rails.logger = Logger.new("database/get/#{Date.today.to_s}.log", "daily")
|
||||
ActiveRecord::Base.logger = Logger.new("database/sql/#{Date.today.to_s}.log", "daily")
|
||||
ActionController::Base.logger = Logger.new("database/controller/#{Date.today.to_s}.log", "daily")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module LoggerHelper
|
||||
|
||||
#输出日志
|
||||
def OutLogger
|
||||
#日志输出级别
|
||||
#Rails.logger.level = Logger::INFO
|
||||
|
||||
if(!File.exist?("database"))
|
||||
Dir.mkdir("database")
|
||||
end
|
||||
if(!File.exist?("database/get"))
|
||||
Dir.mkdir("database/get")
|
||||
end
|
||||
if(!File.exist?("database/sql"))
|
||||
Dir.mkdir("database/sql")
|
||||
end
|
||||
if(!File.exist?("database/controller"))
|
||||
Dir.mkdir("database/controller")
|
||||
end
|
||||
|
||||
Rails.logger = Logger.new("database/get/#{Date.today.to_s}.log", "daily")
|
||||
ActiveRecord::Base.logger = Logger.new("database/sql/#{Date.today.to_s}.log", "daily")
|
||||
ActionController::Base.logger = Logger.new("database/controller/#{Date.today.to_s}.log", "daily")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -1,378 +1,378 @@
|
|||
# encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
include AvatarHelper
|
||||
module ProjectsHelper
|
||||
def link_to_version(version, options = {})
|
||||
return '' unless version && version.is_a?(Version)
|
||||
link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options
|
||||
end
|
||||
|
||||
def project_settings_tabs
|
||||
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
|
||||
{:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
|
||||
{:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
|
||||
{:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
|
||||
{:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
|
||||
# {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
|
||||
{:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
|
||||
#{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural},
|
||||
{:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}
|
||||
]
|
||||
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
||||
|
||||
end
|
||||
|
||||
# added bu huang
|
||||
def sort_project_enterprise(state, project_type)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
when 1
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
end
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs_enterprise")
|
||||
end
|
||||
|
||||
def sort_course(state, project_type, school_id)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :school_id => school_id, :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
when 1
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
#gcm
|
||||
when 3
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected")
|
||||
end
|
||||
#gcmend
|
||||
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs")
|
||||
end
|
||||
# end
|
||||
|
||||
def sort_project(state, project_type)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
when 1
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
end
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs")
|
||||
end
|
||||
|
||||
# def sort_course(state, project_type)
|
||||
# content = ''.html_safe
|
||||
# case state
|
||||
# when 0
|
||||
#
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# when 1
|
||||
#
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
# when 2
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
# end
|
||||
# content = content_tag('ul', content)
|
||||
# content_tag('div', content, :class => "tabs")
|
||||
# end
|
||||
|
||||
|
||||
# Added by young
|
||||
def course_settings_tabs
|
||||
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural, :course=>'1'},
|
||||
#{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural, :project_type => 1},
|
||||
# {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
|
||||
{:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural}
|
||||
]
|
||||
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
||||
end
|
||||
# Ended by young
|
||||
|
||||
|
||||
|
||||
|
||||
def parent_project_select_tag(project)
|
||||
selected = project.parent
|
||||
# retrieve the requested parent project
|
||||
parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id]
|
||||
if parent_id
|
||||
selected = (parent_id.blank? ? nil : Project.find(parent_id))
|
||||
end
|
||||
|
||||
options = ''
|
||||
options << "<option value=''></option>" if project.allowed_parents.include?(nil)
|
||||
options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected)
|
||||
content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
|
||||
end
|
||||
|
||||
# Renders the projects index
|
||||
def render_project_hierarchy(projects)
|
||||
render_project_nested_lists(projects) do |project|
|
||||
#Modified by young
|
||||
if project.try(:project_type) == Project::ProjectType_course
|
||||
# modified by longjun
|
||||
# never use unless and else
|
||||
# unless project.is_public == 1
|
||||
if project.is_public != 1
|
||||
s = "<span class='private_project'>#{l(:label_private)}</span>".html_safe
|
||||
else
|
||||
s = "".html_safe
|
||||
end
|
||||
# end longjun
|
||||
# modified by Longjun
|
||||
s += link_to_project(project, {},
|
||||
:class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}").html_safe
|
||||
# end longjun
|
||||
else
|
||||
# modified by longjun
|
||||
# unless project.is_public
|
||||
if !project.is_public
|
||||
# end longjun
|
||||
s = "<span class='private_project'>#{l(:label_private)}</span>".html_safe
|
||||
else
|
||||
s = "".html_safe
|
||||
end
|
||||
# modified by longjun
|
||||
s += link_to_project(project, {},
|
||||
:class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}")
|
||||
# end longjun
|
||||
end
|
||||
#Ended by young
|
||||
if project.description.present?
|
||||
#Delete by nie.
|
||||
# s << content_tag('td', textilizable(project.short_description, :project => project), :class => 'wiki description')
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a set of options for a select field, grouped by project.
|
||||
def version_options_for_select(versions, selected=nil)
|
||||
grouped = Hash.new {|h,k| h[k] = []}
|
||||
versions.each do |version|
|
||||
grouped[version.project.name] << [version.name, version.id]
|
||||
end
|
||||
|
||||
if grouped.keys.size > 1
|
||||
grouped_options_for_select(grouped, selected && selected.id)
|
||||
else
|
||||
options_for_select((grouped.values.first || []), selected && selected.id)
|
||||
end
|
||||
end
|
||||
|
||||
def format_version_sharing(sharing)
|
||||
sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
|
||||
l("label_version_sharing_#{sharing}")
|
||||
end
|
||||
|
||||
# this method is used to get all projects that tagged one tag
|
||||
# added by william
|
||||
def get_projects_by_tag(tag_name)
|
||||
Project.tagged_with(tag_name).order('updated_on desc')
|
||||
end
|
||||
|
||||
# added by fq
|
||||
def homework_type_option
|
||||
type = []
|
||||
option1 = []
|
||||
option2 = []
|
||||
option1 << l(:label_task_submit_form_accessory)
|
||||
option1 << 1
|
||||
option2 << l(:label_task_submit_form_project)
|
||||
option2 << 2
|
||||
type << option1
|
||||
type << option2
|
||||
end
|
||||
|
||||
#是否启动互评下拉框
|
||||
def is_evaluation_option
|
||||
type = []
|
||||
option1 = []
|
||||
option2 = []
|
||||
option1 << l(:lable_start_mutual_evaluation)
|
||||
option1 << 1
|
||||
option2 << l(:lable_close_mutual_evaluation)
|
||||
option2 << 2
|
||||
type << option1
|
||||
type << option2
|
||||
end
|
||||
|
||||
# 用来判断用户是否是项目的管理员
|
||||
# added by william
|
||||
def is_manager?(user_id,project_id)
|
||||
@result = false
|
||||
@user_id = ProjectInfo.find_by_project_id(project_id)
|
||||
|
||||
# modified by longjun
|
||||
# if @user_id == user.id
|
||||
# @result = true
|
||||
# end
|
||||
|
||||
@result = true if @user_id = user.id
|
||||
# end longjun
|
||||
return @result
|
||||
end
|
||||
|
||||
# 将动态中类型转换为可读的字符串
|
||||
def eventToLanguage event_type
|
||||
case event_type
|
||||
when "issue-note"
|
||||
l :label_issue
|
||||
when "issue"
|
||||
l :label_issue
|
||||
when "attachment"
|
||||
l :label_attachment
|
||||
when "news"
|
||||
l :label_news
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def eventToLanguageCourse event_type, project
|
||||
case event_type
|
||||
when "issue-note"
|
||||
l :label_issue
|
||||
when "issue"
|
||||
l :label_issue
|
||||
when "attachment"
|
||||
l :label_attachment
|
||||
when "news"
|
||||
project.project_type == 1 ? (l :label_notification) : (l :label_news)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def rolesToLanguage rolesArray
|
||||
rolesArray = ([] << rolesArray) unless rolesArray.is_a?(Array)
|
||||
rolesArray.map{ |roleName|
|
||||
case roleName.to_sym
|
||||
when :Manager
|
||||
l :default_role_manager
|
||||
when :Developer
|
||||
l :default_role_developer
|
||||
when :Reporter
|
||||
l :default_role_reporter
|
||||
else
|
||||
'Unkown'
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def sort_project_by_hot
|
||||
return sort_project_by_hot_rails
|
||||
@projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1)
|
||||
@projects_status = @projects_status.reorder('grade').all.reverse
|
||||
@projects = []
|
||||
@projects_status.each do |obj|
|
||||
break if(@projects_status[10] == obj)
|
||||
@projects << Project.visible.find_by_id("#{obj.project_id}")#where('id=:id', id: obj.project_id)
|
||||
end
|
||||
@projects
|
||||
rescue NoMethodError => e
|
||||
logger.error "Logger.Error [ProjectsHelper] ===> #sort_project_by_hot, NoMethodError: #{e}"
|
||||
[]
|
||||
end
|
||||
|
||||
def sort_project_by_hot_rails
|
||||
# @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1)
|
||||
# @projects_status = @projects_status.reorder('grade').all.reverse
|
||||
# Project.joins(@projects_status).limit(10)
|
||||
limit = 10
|
||||
#Project.find_by_sql("SELECT * FROM projects RIGHT OUTER JOIN (SELECT * FROM project_statuses ORDER BY grade DESC LIMIT #{limit} ) AS t ON projects.id = t.project_id ")
|
||||
Project.find_by_sql("
|
||||
SELECT p.id, p.name, p.description, p.identifier, t.project_id
|
||||
FROM projects AS p RIGHT OUTER JOIN (
|
||||
SELECT project_id,grade FROM project_statuses
|
||||
WHERE project_type = 0 ORDER BY grade DESC LIMIT #{limit} ) AS t ON p.id = t.project_id ")
|
||||
end
|
||||
|
||||
|
||||
# 判断课程是否结束,快别用,这个定日子的方法有问题
|
||||
def course_timeout? project
|
||||
return true if (project.nil? && project.course_extra.nil?)
|
||||
courses_year = project.course_extra.time
|
||||
current_year = Time.now.year
|
||||
if courses_year >= current_year
|
||||
return false
|
||||
elsif (courses_year < current_year) && (Time.now.month < 3)
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
def find_project_repository project
|
||||
unless project.repositories.nil?
|
||||
project.repositories.each do |repository|
|
||||
repository.fetch_changesets if Setting.autofetch_changesets?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
include AvatarHelper
|
||||
module ProjectsHelper
|
||||
def link_to_version(version, options = {})
|
||||
return '' unless version && version.is_a?(Version)
|
||||
link_to_if version.visible?, format_version_name(version), { :controller => 'versions', :action => 'show', :id => version }, options
|
||||
end
|
||||
|
||||
def project_settings_tabs
|
||||
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural},
|
||||
{:name => 'modules', :action => :select_project_modules, :partial => 'projects/settings/modules', :label => :label_module_plural},
|
||||
{:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural},
|
||||
{:name => 'versions', :action => :manage_versions, :partial => 'projects/settings/versions', :label => :label_version_plural},
|
||||
{:name => 'categories', :action => :manage_categories, :partial => 'projects/settings/issue_categories', :label => :label_issue_category_plural},
|
||||
# {:name => 'wiki', :action => :manage_wiki, :partial => 'projects/settings/wiki', :label => :label_wiki},
|
||||
{:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
|
||||
#{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural},
|
||||
{:name => 'activities', :action => :manage_project_activities, :partial => 'projects/settings/activities', :label => :enumeration_activities}
|
||||
]
|
||||
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
||||
|
||||
end
|
||||
|
||||
# added bu huang
|
||||
def sort_project_enterprise(state, project_type)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
when 1
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
end
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs_enterprise")
|
||||
end
|
||||
|
||||
def sort_course(state, project_type, school_id)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :school_id => school_id, :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
when 1
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id)))
|
||||
|
||||
#gcm
|
||||
when 3
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type, :school_id => school_id)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type, :school_id => school_id)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_activity), course_path(:project_sort_type => '3', :project_type => project_type, :school_id => school_id), :class=>"selected"), :class=>"selected")
|
||||
end
|
||||
#gcmend
|
||||
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs")
|
||||
end
|
||||
# end
|
||||
|
||||
def sort_project(state, project_type)
|
||||
content = ''.html_safe
|
||||
case state
|
||||
when 0
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
when 1
|
||||
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
when 2
|
||||
content << content_tag('li', link_to(l(:label_sort_by_active), projects_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
content << content_tag('li', link_to(l(:label_sort_by_influence), projects_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
content << content_tag('li', link_to(l(:label_sort_by_time), projects_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
end
|
||||
content = content_tag('ul', content)
|
||||
content_tag('div', content, :class => "tabs")
|
||||
end
|
||||
|
||||
# def sort_course(state, project_type)
|
||||
# content = ''.html_safe
|
||||
# case state
|
||||
# when 0
|
||||
#
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# when 1
|
||||
#
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
# when 2
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_active), course_path(:project_sort_type => '1', :project_type => project_type)))
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_influence), course_path(:project_sort_type => '2', :project_type => project_type), :class=>"selected"), :class=>"selected")
|
||||
# content << content_tag('li', link_to(l(:label_sort_by_time), course_path(:project_sort_type => '0', :project_type => project_type)))
|
||||
# end
|
||||
# content = content_tag('ul', content)
|
||||
# content_tag('div', content, :class => "tabs")
|
||||
# end
|
||||
|
||||
|
||||
# Added by young
|
||||
def course_settings_tabs
|
||||
tabs = [{:name => 'info', :action => :edit_project, :partial => 'projects/edit', :label => :label_information_plural, :course=>'1'},
|
||||
#{:name => 'boards', :action => :manage_boards, :partial => 'projects/settings/boards', :label => :label_board_plural, :project_type => 1},
|
||||
# {:name => 'repositories', :action => :manage_repository, :partial => 'projects/settings/repositories', :label => :label_repository_plural},
|
||||
{:name => 'members', :action => :manage_members, :partial => 'projects/settings/members', :label => :label_member_plural}
|
||||
]
|
||||
tabs.select {|tab| User.current.allowed_to?(tab[:action], @project)}
|
||||
end
|
||||
# Ended by young
|
||||
|
||||
|
||||
|
||||
|
||||
def parent_project_select_tag(project)
|
||||
selected = project.parent
|
||||
# retrieve the requested parent project
|
||||
parent_id = (params[:project] && params[:project][:parent_id]) || params[:parent_id]
|
||||
if parent_id
|
||||
selected = (parent_id.blank? ? nil : Project.find(parent_id))
|
||||
end
|
||||
|
||||
options = ''
|
||||
options << "<option value=''></option>" if project.allowed_parents.include?(nil)
|
||||
options << project_tree_options_for_select(project.allowed_parents.compact, :selected => selected)
|
||||
content_tag('select', options.html_safe, :name => 'project[parent_id]', :id => 'project_parent_id')
|
||||
end
|
||||
|
||||
# Renders the projects index
|
||||
def render_project_hierarchy(projects)
|
||||
render_project_nested_lists(projects) do |project|
|
||||
#Modified by young
|
||||
if project.try(:project_type) == Project::ProjectType_course
|
||||
# modified by longjun
|
||||
# never use unless and else
|
||||
# unless project.is_public == 1
|
||||
if project.is_public != 1
|
||||
s = "<span class='private_project'>#{l(:label_private)}</span>".html_safe
|
||||
else
|
||||
s = "".html_safe
|
||||
end
|
||||
# end longjun
|
||||
# modified by Longjun
|
||||
s += link_to_project(project, {},
|
||||
:class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}").html_safe
|
||||
# end longjun
|
||||
else
|
||||
# modified by longjun
|
||||
# unless project.is_public
|
||||
if !project.is_public
|
||||
# end longjun
|
||||
s = "<span class='private_project'>#{l(:label_private)}</span>".html_safe
|
||||
else
|
||||
s = "".html_safe
|
||||
end
|
||||
# modified by longjun
|
||||
s += link_to_project(project, {},
|
||||
:class => "#{project.css_classes} #{User.current.member_of?(project) ? 'my-project' : nil}")
|
||||
# end longjun
|
||||
end
|
||||
#Ended by young
|
||||
if project.description.present?
|
||||
#Delete by nie.
|
||||
# s << content_tag('td', textilizable(project.short_description, :project => project), :class => 'wiki description')
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
|
||||
# Returns a set of options for a select field, grouped by project.
|
||||
def version_options_for_select(versions, selected=nil)
|
||||
grouped = Hash.new {|h,k| h[k] = []}
|
||||
versions.each do |version|
|
||||
grouped[version.project.name] << [version.name, version.id]
|
||||
end
|
||||
|
||||
if grouped.keys.size > 1
|
||||
grouped_options_for_select(grouped, selected && selected.id)
|
||||
else
|
||||
options_for_select((grouped.values.first || []), selected && selected.id)
|
||||
end
|
||||
end
|
||||
|
||||
def format_version_sharing(sharing)
|
||||
sharing = 'none' unless Version::VERSION_SHARINGS.include?(sharing)
|
||||
l("label_version_sharing_#{sharing}")
|
||||
end
|
||||
|
||||
# this method is used to get all projects that tagged one tag
|
||||
# added by william
|
||||
def get_projects_by_tag(tag_name)
|
||||
Project.tagged_with(tag_name).order('updated_on desc')
|
||||
end
|
||||
|
||||
# added by fq
|
||||
def homework_type_option
|
||||
type = []
|
||||
option1 = []
|
||||
option2 = []
|
||||
option1 << l(:label_task_submit_form_accessory)
|
||||
option1 << 1
|
||||
option2 << l(:label_task_submit_form_project)
|
||||
option2 << 2
|
||||
type << option1
|
||||
type << option2
|
||||
end
|
||||
|
||||
#是否启动互评下拉框
|
||||
def is_evaluation_option
|
||||
type = []
|
||||
option1 = []
|
||||
option2 = []
|
||||
option1 << l(:lable_start_mutual_evaluation)
|
||||
option1 << 1
|
||||
option2 << l(:lable_close_mutual_evaluation)
|
||||
option2 << 2
|
||||
type << option1
|
||||
type << option2
|
||||
end
|
||||
|
||||
# 用来判断用户是否是项目的管理员
|
||||
# added by william
|
||||
def is_manager?(user_id,project_id)
|
||||
@result = false
|
||||
@user_id = ProjectInfo.find_by_project_id(project_id)
|
||||
|
||||
# modified by longjun
|
||||
# if @user_id == user.id
|
||||
# @result = true
|
||||
# end
|
||||
|
||||
@result = true if @user_id = user.id
|
||||
# end longjun
|
||||
return @result
|
||||
end
|
||||
|
||||
# 将动态中类型转换为可读的字符串
|
||||
def eventToLanguage event_type
|
||||
case event_type
|
||||
when "issue-note"
|
||||
l :label_issue
|
||||
when "issue"
|
||||
l :label_issue
|
||||
when "attachment"
|
||||
l :label_attachment
|
||||
when "news"
|
||||
l :label_news
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def eventToLanguageCourse event_type, project
|
||||
case event_type
|
||||
when "issue-note"
|
||||
l :label_issue
|
||||
when "issue"
|
||||
l :label_issue
|
||||
when "attachment"
|
||||
l :label_attachment
|
||||
when "news"
|
||||
project.project_type == 1 ? (l :label_notification) : (l :label_news)
|
||||
else
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
def rolesToLanguage rolesArray
|
||||
rolesArray = ([] << rolesArray) unless rolesArray.is_a?(Array)
|
||||
rolesArray.map{ |roleName|
|
||||
case roleName.to_sym
|
||||
when :Manager
|
||||
l :default_role_manager
|
||||
when :Developer
|
||||
l :default_role_developer
|
||||
when :Reporter
|
||||
l :default_role_reporter
|
||||
else
|
||||
'Unkown'
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
def sort_project_by_hot
|
||||
return sort_project_by_hot_rails
|
||||
@projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1)
|
||||
@projects_status = @projects_status.reorder('grade').all.reverse
|
||||
@projects = []
|
||||
@projects_status.each do |obj|
|
||||
break if(@projects_status[10] == obj)
|
||||
@projects << Project.visible.find_by_id("#{obj.project_id}")#where('id=:id', id: obj.project_id)
|
||||
end
|
||||
@projects
|
||||
rescue NoMethodError => e
|
||||
logger.error "Logger.Error [ProjectsHelper] ===> #sort_project_by_hot, NoMethodError: #{e}"
|
||||
[]
|
||||
end
|
||||
|
||||
def sort_project_by_hot_rails
|
||||
# @projects_status = ProjectStatus.visible.where("project_statuses.project_type <> ? or project_statuses.project_type is null", 1)
|
||||
# @projects_status = @projects_status.reorder('grade').all.reverse
|
||||
# Project.joins(@projects_status).limit(10)
|
||||
limit = 10
|
||||
#Project.find_by_sql("SELECT * FROM projects RIGHT OUTER JOIN (SELECT * FROM project_statuses ORDER BY grade DESC LIMIT #{limit} ) AS t ON projects.id = t.project_id ")
|
||||
Project.find_by_sql("
|
||||
SELECT p.id, p.name, p.description, p.identifier, t.project_id
|
||||
FROM projects AS p RIGHT OUTER JOIN (
|
||||
SELECT project_id,grade FROM project_statuses
|
||||
WHERE project_type = 0 ORDER BY grade DESC LIMIT #{limit} ) AS t ON p.id = t.project_id ")
|
||||
end
|
||||
|
||||
|
||||
# 判断课程是否结束,快别用,这个定日子的方法有问题
|
||||
def course_timeout? project
|
||||
return true if (project.nil? && project.course_extra.nil?)
|
||||
courses_year = project.course_extra.time
|
||||
current_year = Time.now.year
|
||||
if courses_year >= current_year
|
||||
return false
|
||||
elsif (courses_year < current_year) && (Time.now.month < 3)
|
||||
return false
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
def find_project_repository project
|
||||
unless project.repositories.nil?
|
||||
project.repositories.each do |repository|
|
||||
repository.fetch_changesets if Setting.autofetch_changesets?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -64,8 +64,8 @@ module WatchersHelper
|
|||
:object_id => (objects.size == 1 ? objects.first.id : objects.map(&:id).sort)
|
||||
)
|
||||
method = watched ? 'delete' : 'post'
|
||||
|
||||
link_to text, url, :remote => true, :method => method, :class => css
|
||||
|
||||
link_to text, url, :remote => true, :method => method, :class => css, :onclick => "location.reload()"
|
||||
end
|
||||
|
||||
# add by nwb
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,8 @@
|
|||
class Activity < ActiveRecord::Base
|
||||
attr_accessible :act_id, :act_type, :user_id
|
||||
belongs_to :act, :polymorphic => true
|
||||
belongs_to :user
|
||||
validates :act_id, presence: true
|
||||
validates :act_type, presence: true
|
||||
validates :user_id, presence: true
|
||||
end
|
||||
class Activity < ActiveRecord::Base
|
||||
attr_accessible :act_id, :act_type, :user_id
|
||||
belongs_to :act, :polymorphic => true
|
||||
belongs_to :user
|
||||
validates :act_id, presence: true
|
||||
validates :act_type, presence: true
|
||||
validates :user_id, presence: true
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,90 +1,90 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Generic exception for when the AuthSource can not be reached
|
||||
# (eg. can not connect to the LDAP)
|
||||
class AuthSourceException < Exception; end
|
||||
class AuthSourceTimeoutException < AuthSourceException; end
|
||||
|
||||
class AuthSource < ActiveRecord::Base
|
||||
include Redmine::SubclassFactory
|
||||
include Redmine::Ciphering
|
||||
|
||||
has_many :users
|
||||
|
||||
validates :name, presence: true, uniqueness: true, length: {maximum: 60}
|
||||
|
||||
def authenticate(login, password)
|
||||
end
|
||||
|
||||
def test_connection
|
||||
end
|
||||
|
||||
def auth_method_name
|
||||
"Abstract"
|
||||
end
|
||||
|
||||
def account_password
|
||||
read_ciphered_attribute(:account_password)
|
||||
end
|
||||
|
||||
def account_password=(arg)
|
||||
write_ciphered_attribute(:account_password, arg)
|
||||
end
|
||||
|
||||
def searchable?
|
||||
false
|
||||
end
|
||||
|
||||
def self.search(q)
|
||||
results = []
|
||||
AuthSource.all.each do |source|
|
||||
begin
|
||||
if source.searchable?
|
||||
results += source.search(q)
|
||||
end
|
||||
rescue AuthSourceException => e
|
||||
logger.error "Error while searching users in #{source.name}: #{e.message}"
|
||||
end
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
def allow_password_changes?
|
||||
self.class.allow_password_changes?
|
||||
end
|
||||
|
||||
# Does this auth source backend allow password changes?
|
||||
def self.allow_password_changes?
|
||||
false
|
||||
end
|
||||
|
||||
# Try to authenticate a user not yet registered against available sources
|
||||
def self.authenticate(login, password)
|
||||
AuthSource.where(:onthefly_register => true).all.each do |source|
|
||||
begin
|
||||
logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
|
||||
attrs = source.authenticate(login, password)
|
||||
rescue => e
|
||||
logger.error "Error during authentication: #{e.message}"
|
||||
attrs = nil
|
||||
end
|
||||
return attrs if attrs
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
# Generic exception for when the AuthSource can not be reached
|
||||
# (eg. can not connect to the LDAP)
|
||||
class AuthSourceException < Exception; end
|
||||
class AuthSourceTimeoutException < AuthSourceException; end
|
||||
|
||||
class AuthSource < ActiveRecord::Base
|
||||
include Redmine::SubclassFactory
|
||||
include Redmine::Ciphering
|
||||
|
||||
has_many :users
|
||||
|
||||
validates :name, presence: true, uniqueness: true, length: {maximum: 60}
|
||||
|
||||
def authenticate(login, password)
|
||||
end
|
||||
|
||||
def test_connection
|
||||
end
|
||||
|
||||
def auth_method_name
|
||||
"Abstract"
|
||||
end
|
||||
|
||||
def account_password
|
||||
read_ciphered_attribute(:account_password)
|
||||
end
|
||||
|
||||
def account_password=(arg)
|
||||
write_ciphered_attribute(:account_password, arg)
|
||||
end
|
||||
|
||||
def searchable?
|
||||
false
|
||||
end
|
||||
|
||||
def self.search(q)
|
||||
results = []
|
||||
AuthSource.all.each do |source|
|
||||
begin
|
||||
if source.searchable?
|
||||
results += source.search(q)
|
||||
end
|
||||
rescue AuthSourceException => e
|
||||
logger.error "Error while searching users in #{source.name}: #{e.message}"
|
||||
end
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
def allow_password_changes?
|
||||
self.class.allow_password_changes?
|
||||
end
|
||||
|
||||
# Does this auth source backend allow password changes?
|
||||
def self.allow_password_changes?
|
||||
false
|
||||
end
|
||||
|
||||
# Try to authenticate a user not yet registered against available sources
|
||||
def self.authenticate(login, password)
|
||||
AuthSource.where(:onthefly_register => true).all.each do |source|
|
||||
begin
|
||||
logger.debug "Authenticating '#{login}' against '#{source.name}'" if logger && logger.debug?
|
||||
attrs = source.authenticate(login, password)
|
||||
rescue => e
|
||||
logger.error "Error during authentication: #{e.message}"
|
||||
attrs = nil
|
||||
end
|
||||
return attrs if attrs
|
||||
end
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,206 +1,206 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'net/ldap'
|
||||
require 'net/ldap/dn'
|
||||
require 'timeout'
|
||||
|
||||
class AuthSourceLdap < AuthSource
|
||||
validates :host, presence: true, length: {maximum: 60, allow_nil: true}
|
||||
validates :port, presence: true, numericality: {only_integer: true}
|
||||
validates :attr_login, presence: true
|
||||
validates :name, length: {maximum: 60, allow_nil: true}
|
||||
validates :account, length: {maximum: 255, allow_blank: true}
|
||||
validates :account_password, length: {maximum: 255, allow_blank: true}
|
||||
validates :base_dn, length: {maximum: 255, allow_blank: true}
|
||||
validates :filter, length: {maximum: 255, allow_blank: true}
|
||||
validates :attr_login, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_firstname, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_lastname, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_mail, length: {maximum: 30, allow_nil: true}
|
||||
validates :timeout, numericality: { only_integer: true, allow_blank: true}
|
||||
validate :validate_filter
|
||||
before_validation :strip_ldap_attributes
|
||||
|
||||
def initialize(attributes=nil, *args)
|
||||
super
|
||||
self.port = 389 if self.port == 0
|
||||
end
|
||||
|
||||
def authenticate(login, password)
|
||||
return nil if login.blank? || password.blank?
|
||||
|
||||
with_timeout do
|
||||
attrs = get_user_dn(login, password)
|
||||
if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
|
||||
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
|
||||
return attrs.except(:dn)
|
||||
end
|
||||
end
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
# test the connection to the LDAP
|
||||
def test_connection
|
||||
with_timeout do
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
ldap_con.open { }
|
||||
end
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
def auth_method_name
|
||||
"LDAP"
|
||||
end
|
||||
|
||||
# Returns true if this source can be searched for users
|
||||
def searchable?
|
||||
!account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
|
||||
end
|
||||
|
||||
# Searches the source for users and returns an array of results
|
||||
def search(q)
|
||||
q = q.to_s.strip
|
||||
return [] unless searchable? && q.present?
|
||||
|
||||
results = []
|
||||
search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
ldap_con.search(:base => self.base_dn,
|
||||
:filter => search_filter,
|
||||
:attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
|
||||
:size => 10) do |entry|
|
||||
attrs = get_user_attributes_from_ldap_entry(entry)
|
||||
attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
|
||||
results << attrs
|
||||
end
|
||||
results
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_timeout(&block)
|
||||
timeout = self.timeout
|
||||
timeout = 20 unless timeout && timeout > 0
|
||||
Timeout.timeout(timeout) do
|
||||
return yield
|
||||
end
|
||||
rescue Timeout::Error => e
|
||||
raise AuthSourceTimeoutException.new(e.message)
|
||||
end
|
||||
|
||||
def ldap_filter
|
||||
if filter.present?
|
||||
Net::LDAP::Filter.construct(filter)
|
||||
end
|
||||
rescue Net::LDAP::LdapError
|
||||
nil
|
||||
end
|
||||
|
||||
def base_filter
|
||||
filter = Net::LDAP::Filter.eq("objectClass", "*")
|
||||
if f = ldap_filter
|
||||
filter = filter & f
|
||||
end
|
||||
filter
|
||||
end
|
||||
|
||||
def validate_filter
|
||||
if filter.present? && ldap_filter.nil?
|
||||
errors.add(:filter, :invalid)
|
||||
end
|
||||
end
|
||||
|
||||
def strip_ldap_attributes
|
||||
[:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
|
||||
write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_ldap_con(ldap_user, ldap_password)
|
||||
options = { :host => self.host,
|
||||
:port => self.port,
|
||||
:encryption => (self.tls ? :simple_tls : nil)
|
||||
}
|
||||
options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
|
||||
Net::LDAP.new options
|
||||
end
|
||||
|
||||
def get_user_attributes_from_ldap_entry(entry)
|
||||
{
|
||||
:dn => entry.dn,
|
||||
:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
|
||||
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
|
||||
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
|
||||
:auth_source_id => self.id
|
||||
}
|
||||
end
|
||||
|
||||
# Return the attributes needed for the LDAP search. It will only
|
||||
# include the user attributes if on-the-fly registration is enabled
|
||||
def search_attributes
|
||||
if onthefly_register?
|
||||
['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
|
||||
else
|
||||
['dn']
|
||||
end
|
||||
end
|
||||
|
||||
# Check if a DN (user record) authenticates with the password
|
||||
def authenticate_dn(dn, password)
|
||||
if dn.present? && password.present?
|
||||
initialize_ldap_con(dn, password).bind
|
||||
end
|
||||
end
|
||||
|
||||
# Get the user's dn and any attributes for them, given their login
|
||||
def get_user_dn(login, password)
|
||||
ldap_con = nil
|
||||
if self.account && self.account.include?("$login")
|
||||
ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
|
||||
else
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
end
|
||||
attrs = {}
|
||||
search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
|
||||
|
||||
ldap_con.search( :base => self.base_dn,
|
||||
:filter => search_filter,
|
||||
:attributes=> search_attributes) do |entry|
|
||||
|
||||
if onthefly_register?
|
||||
attrs = get_user_attributes_from_ldap_entry(entry)
|
||||
else
|
||||
attrs = {:dn => entry.dn}
|
||||
end
|
||||
|
||||
logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
def self.get_attr(entry, attr_name)
|
||||
if !attr_name.blank?
|
||||
entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
require 'net/ldap'
|
||||
require 'net/ldap/dn'
|
||||
require 'timeout'
|
||||
|
||||
class AuthSourceLdap < AuthSource
|
||||
validates :host, presence: true, length: {maximum: 60, allow_nil: true}
|
||||
validates :port, presence: true, numericality: {only_integer: true}
|
||||
validates :attr_login, presence: true
|
||||
validates :name, length: {maximum: 60, allow_nil: true}
|
||||
validates :account, length: {maximum: 255, allow_blank: true}
|
||||
validates :account_password, length: {maximum: 255, allow_blank: true}
|
||||
validates :base_dn, length: {maximum: 255, allow_blank: true}
|
||||
validates :filter, length: {maximum: 255, allow_blank: true}
|
||||
validates :attr_login, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_firstname, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_lastname, length: {maximum: 30, allow_nil: true}
|
||||
validates :attr_mail, length: {maximum: 30, allow_nil: true}
|
||||
validates :timeout, numericality: { only_integer: true, allow_blank: true}
|
||||
validate :validate_filter
|
||||
before_validation :strip_ldap_attributes
|
||||
|
||||
def initialize(attributes=nil, *args)
|
||||
super
|
||||
self.port = 389 if self.port == 0
|
||||
end
|
||||
|
||||
def authenticate(login, password)
|
||||
return nil if login.blank? || password.blank?
|
||||
|
||||
with_timeout do
|
||||
attrs = get_user_dn(login, password)
|
||||
if attrs && attrs[:dn] && authenticate_dn(attrs[:dn], password)
|
||||
logger.debug "Authentication successful for '#{login}'" if logger && logger.debug?
|
||||
return attrs.except(:dn)
|
||||
end
|
||||
end
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
# test the connection to the LDAP
|
||||
def test_connection
|
||||
with_timeout do
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
ldap_con.open { }
|
||||
end
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
def auth_method_name
|
||||
"LDAP"
|
||||
end
|
||||
|
||||
# Returns true if this source can be searched for users
|
||||
def searchable?
|
||||
!account.to_s.include?("$login") && %w(login firstname lastname mail).all? {|a| send("attr_#{a}?")}
|
||||
end
|
||||
|
||||
# Searches the source for users and returns an array of results
|
||||
def search(q)
|
||||
q = q.to_s.strip
|
||||
return [] unless searchable? && q.present?
|
||||
|
||||
results = []
|
||||
search_filter = base_filter & Net::LDAP::Filter.begins(self.attr_login, q)
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
ldap_con.search(:base => self.base_dn,
|
||||
:filter => search_filter,
|
||||
:attributes => ['dn', self.attr_login, self.attr_firstname, self.attr_lastname, self.attr_mail],
|
||||
:size => 10) do |entry|
|
||||
attrs = get_user_attributes_from_ldap_entry(entry)
|
||||
attrs[:login] = AuthSourceLdap.get_attr(entry, self.attr_login)
|
||||
results << attrs
|
||||
end
|
||||
results
|
||||
rescue Net::LDAP::LdapError => e
|
||||
raise AuthSourceException.new(e.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def with_timeout(&block)
|
||||
timeout = self.timeout
|
||||
timeout = 20 unless timeout && timeout > 0
|
||||
Timeout.timeout(timeout) do
|
||||
return yield
|
||||
end
|
||||
rescue Timeout::Error => e
|
||||
raise AuthSourceTimeoutException.new(e.message)
|
||||
end
|
||||
|
||||
def ldap_filter
|
||||
if filter.present?
|
||||
Net::LDAP::Filter.construct(filter)
|
||||
end
|
||||
rescue Net::LDAP::LdapError
|
||||
nil
|
||||
end
|
||||
|
||||
def base_filter
|
||||
filter = Net::LDAP::Filter.eq("objectClass", "*")
|
||||
if f = ldap_filter
|
||||
filter = filter & f
|
||||
end
|
||||
filter
|
||||
end
|
||||
|
||||
def validate_filter
|
||||
if filter.present? && ldap_filter.nil?
|
||||
errors.add(:filter, :invalid)
|
||||
end
|
||||
end
|
||||
|
||||
def strip_ldap_attributes
|
||||
[:attr_login, :attr_firstname, :attr_lastname, :attr_mail].each do |attr|
|
||||
write_attribute(attr, read_attribute(attr).strip) unless read_attribute(attr).nil?
|
||||
end
|
||||
end
|
||||
|
||||
def initialize_ldap_con(ldap_user, ldap_password)
|
||||
options = { :host => self.host,
|
||||
:port => self.port,
|
||||
:encryption => (self.tls ? :simple_tls : nil)
|
||||
}
|
||||
options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
|
||||
Net::LDAP.new options
|
||||
end
|
||||
|
||||
def get_user_attributes_from_ldap_entry(entry)
|
||||
{
|
||||
:dn => entry.dn,
|
||||
:firstname => AuthSourceLdap.get_attr(entry, self.attr_firstname),
|
||||
:lastname => AuthSourceLdap.get_attr(entry, self.attr_lastname),
|
||||
:mail => AuthSourceLdap.get_attr(entry, self.attr_mail),
|
||||
:auth_source_id => self.id
|
||||
}
|
||||
end
|
||||
|
||||
# Return the attributes needed for the LDAP search. It will only
|
||||
# include the user attributes if on-the-fly registration is enabled
|
||||
def search_attributes
|
||||
if onthefly_register?
|
||||
['dn', self.attr_firstname, self.attr_lastname, self.attr_mail]
|
||||
else
|
||||
['dn']
|
||||
end
|
||||
end
|
||||
|
||||
# Check if a DN (user record) authenticates with the password
|
||||
def authenticate_dn(dn, password)
|
||||
if dn.present? && password.present?
|
||||
initialize_ldap_con(dn, password).bind
|
||||
end
|
||||
end
|
||||
|
||||
# Get the user's dn and any attributes for them, given their login
|
||||
def get_user_dn(login, password)
|
||||
ldap_con = nil
|
||||
if self.account && self.account.include?("$login")
|
||||
ldap_con = initialize_ldap_con(self.account.sub("$login", Net::LDAP::DN.escape(login)), password)
|
||||
else
|
||||
ldap_con = initialize_ldap_con(self.account, self.account_password)
|
||||
end
|
||||
attrs = {}
|
||||
search_filter = base_filter & Net::LDAP::Filter.eq(self.attr_login, login)
|
||||
|
||||
ldap_con.search( :base => self.base_dn,
|
||||
:filter => search_filter,
|
||||
:attributes=> search_attributes) do |entry|
|
||||
|
||||
if onthefly_register?
|
||||
attrs = get_user_attributes_from_ldap_entry(entry)
|
||||
else
|
||||
attrs = {:dn => entry.dn}
|
||||
end
|
||||
|
||||
logger.debug "DN found for #{login}: #{attrs[:dn]}" if logger && logger.debug?
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
def self.get_attr(entry, attr_name)
|
||||
if !attr_name.blank?
|
||||
entry[attr_name].is_a?(Array) ? entry[attr_name].first : entry[attr_name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
## fq
|
||||
class BidingProject < ActiveRecord::Base
|
||||
attr_accessible :bid_id, :project_id, :user_id, :description,:reward
|
||||
|
||||
belongs_to :bid
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
|
||||
DESCRIPTION_LENGTH_LIMIT = 500
|
||||
validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT}
|
||||
validates :user_id, presence: true
|
||||
validates :bid_id, presence: true, :uniqueness => { :scope => :project_id}
|
||||
validates :project_id, presence: true
|
||||
validate :validate_user
|
||||
validate :validate_bid
|
||||
validate :validate_project
|
||||
|
||||
def self.cerate_bidding(bid_id, project_id, description = nil)
|
||||
self.create(:user_id => User.current.id, :bid_id => bid_id,
|
||||
:project_id => project_id, :description => description)
|
||||
end
|
||||
|
||||
# used to update the reward ,the value varies from 0,1,2,3,4,5
|
||||
# added by william
|
||||
def update_reward(which)
|
||||
self.update_attribute(:reward,which)
|
||||
end
|
||||
|
||||
# return the reward,the value is a type of string
|
||||
# added by william
|
||||
def get_reward
|
||||
self.reward
|
||||
end
|
||||
|
||||
def cancel_bidding
|
||||
unless self.nil?
|
||||
if User.current.id == self.user_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :user_id, :invalid if user.nil? || !user.active?
|
||||
end
|
||||
|
||||
def validate_bid
|
||||
errors.add :bid_id, :invalid if bid.nil?
|
||||
end
|
||||
|
||||
def validate_project
|
||||
errors.add :project_id, :invalid if project.nil?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
## fq
|
||||
class BidingProject < ActiveRecord::Base
|
||||
attr_accessible :bid_id, :project_id, :user_id, :description,:reward
|
||||
|
||||
belongs_to :bid
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
|
||||
DESCRIPTION_LENGTH_LIMIT = 500
|
||||
validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT}
|
||||
validates :user_id, presence: true
|
||||
validates :bid_id, presence: true, :uniqueness => { :scope => :project_id}
|
||||
validates :project_id, presence: true
|
||||
validate :validate_user
|
||||
validate :validate_bid
|
||||
validate :validate_project
|
||||
|
||||
def self.cerate_bidding(bid_id, project_id, description = nil)
|
||||
self.create(:user_id => User.current.id, :bid_id => bid_id,
|
||||
:project_id => project_id, :description => description)
|
||||
end
|
||||
|
||||
# used to update the reward ,the value varies from 0,1,2,3,4,5
|
||||
# added by william
|
||||
def update_reward(which)
|
||||
self.update_attribute(:reward,which)
|
||||
end
|
||||
|
||||
# return the reward,the value is a type of string
|
||||
# added by william
|
||||
def get_reward
|
||||
self.reward
|
||||
end
|
||||
|
||||
def cancel_bidding
|
||||
unless self.nil?
|
||||
if User.current.id == self.user_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :user_id, :invalid if user.nil? || !user.active?
|
||||
end
|
||||
|
||||
def validate_bid
|
||||
errors.add :bid_id, :invalid if bid.nil?
|
||||
end
|
||||
|
||||
def validate_project
|
||||
errors.add :project_id, :invalid if project.nil?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,90 +1,90 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Board < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
belongs_to :project
|
||||
belongs_to :course
|
||||
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
|
||||
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
|
||||
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
|
||||
acts_as_tree :dependent => :nullify
|
||||
acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})'
|
||||
acts_as_watchable
|
||||
|
||||
validates :name, presence: true, length: {maximum: 30}
|
||||
validates :description, presence: true, length: {maximum: 255}
|
||||
validate :validate_board
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
|
||||
}
|
||||
|
||||
safe_attributes 'name', 'description', 'parent_id', 'move_to'
|
||||
|
||||
def visible?(user=User.current)
|
||||
!user.nil? && user.allowed_to?(:view_messages, project)
|
||||
end
|
||||
|
||||
def reload(*args)
|
||||
@valid_parents = nil
|
||||
super
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def valid_parents
|
||||
@valid_parents ||= project.boards - self_and_descendants
|
||||
end
|
||||
|
||||
def reset_counters!
|
||||
self.class.reset_counters!(id)
|
||||
end
|
||||
|
||||
# Updates topics_count, messages_count and last_message_id attributes for +board_id+
|
||||
def self.reset_counters!(board_id)
|
||||
board_id = board_id.to_i
|
||||
update_all("topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id} AND parent_id IS NULL)," +
|
||||
" messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id})," +
|
||||
" last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=#{board_id})",
|
||||
["id = ?", board_id])
|
||||
end
|
||||
|
||||
def self.board_tree(boards, parent_id=nil, level=0)
|
||||
tree = []
|
||||
boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board|
|
||||
tree << [board, level]
|
||||
tree += board_tree(boards, board.id, level+1)
|
||||
end
|
||||
if block_given?
|
||||
tree.each do |board, level|
|
||||
yield board, level
|
||||
end
|
||||
end
|
||||
tree
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def validate_board
|
||||
if parent_id && parent_id_changed?
|
||||
errors.add(:parent_id, :invalid) unless valid_parents.include?(parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Board < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
belongs_to :project
|
||||
belongs_to :course
|
||||
has_many :topics, :class_name => 'Message', :conditions => "#{Message.table_name}.parent_id IS NULL", :order => "#{Message.table_name}.created_on DESC"
|
||||
has_many :messages, :dependent => :destroy, :order => "#{Message.table_name}.created_on DESC"
|
||||
belongs_to :last_message, :class_name => 'Message', :foreign_key => :last_message_id
|
||||
acts_as_tree :dependent => :nullify
|
||||
acts_as_list :scope => '(project_id = #{project_id} AND parent_id #{parent_id ? "= #{parent_id}" : "IS NULL"})'
|
||||
acts_as_watchable
|
||||
|
||||
validates :name, presence: true, length: {maximum: 30}
|
||||
validates :description, presence: true, length: {maximum: 255}
|
||||
validate :validate_board
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
includes(:project).where(Project.allowed_to_condition(args.shift || User.current, :view_messages, *args))
|
||||
}
|
||||
|
||||
safe_attributes 'name', 'description', 'parent_id', 'move_to'
|
||||
|
||||
def visible?(user=User.current)
|
||||
!user.nil? && user.allowed_to?(:view_messages, project)
|
||||
end
|
||||
|
||||
def reload(*args)
|
||||
@valid_parents = nil
|
||||
super
|
||||
end
|
||||
|
||||
def to_s
|
||||
name
|
||||
end
|
||||
|
||||
def valid_parents
|
||||
@valid_parents ||= project.boards - self_and_descendants
|
||||
end
|
||||
|
||||
def reset_counters!
|
||||
self.class.reset_counters!(id)
|
||||
end
|
||||
|
||||
# Updates topics_count, messages_count and last_message_id attributes for +board_id+
|
||||
def self.reset_counters!(board_id)
|
||||
board_id = board_id.to_i
|
||||
update_all("topics_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id} AND parent_id IS NULL)," +
|
||||
" messages_count = (SELECT COUNT(*) FROM #{Message.table_name} WHERE board_id=#{board_id})," +
|
||||
" last_message_id = (SELECT MAX(id) FROM #{Message.table_name} WHERE board_id=#{board_id})",
|
||||
["id = ?", board_id])
|
||||
end
|
||||
|
||||
def self.board_tree(boards, parent_id=nil, level=0)
|
||||
tree = []
|
||||
boards.select {|board| board.parent_id == parent_id}.sort_by(&:position).each do |board|
|
||||
tree << [board, level]
|
||||
tree += board_tree(boards, board.id, level+1)
|
||||
end
|
||||
if block_given?
|
||||
tree.each do |board, level|
|
||||
yield board, level
|
||||
end
|
||||
end
|
||||
tree
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def validate_board
|
||||
if parent_id && parent_id_changed?
|
||||
errors.add(:parent_id, :invalid) unless valid_parents.include?(parent)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
class BugToOsp < ActiveRecord::Base
|
||||
# attr_accessible :title, :body
|
||||
belongs_to :open_source_project, :foreign_key => "osp_id"
|
||||
belongs_to :bug, :class_name => 'RelativeMemo', :foreign_key => "relative_memo_id"
|
||||
validates :osp_id, presence: true
|
||||
validates :relative_memo_id, presence: true
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
nil
|
||||
}
|
||||
end
|
||||
class BugToOsp < ActiveRecord::Base
|
||||
# attr_accessible :title, :body
|
||||
belongs_to :open_source_project, :foreign_key => "osp_id"
|
||||
belongs_to :bug, :class_name => 'RelativeMemo', :foreign_key => "relative_memo_id"
|
||||
validates :osp_id, presence: true
|
||||
validates :relative_memo_id, presence: true
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
nil
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Change < ActiveRecord::Base
|
||||
belongs_to :changeset
|
||||
|
||||
validates :changeset_id, presence: true
|
||||
validates :action, presence: true
|
||||
validates :path, presence: true
|
||||
before_save :init_path
|
||||
before_validation :replace_invalid_utf8_of_path
|
||||
|
||||
def relative_path
|
||||
changeset.repository.relative_path(path)
|
||||
end
|
||||
|
||||
def replace_invalid_utf8_of_path
|
||||
self.path = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
|
||||
self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path)
|
||||
end
|
||||
|
||||
def init_path
|
||||
self.path ||= ""
|
||||
end
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Change < ActiveRecord::Base
|
||||
belongs_to :changeset
|
||||
|
||||
validates :changeset_id, presence: true
|
||||
validates :action, presence: true
|
||||
validates :path, presence: true
|
||||
before_save :init_path
|
||||
before_validation :replace_invalid_utf8_of_path
|
||||
|
||||
def relative_path
|
||||
changeset.repository.relative_path(path)
|
||||
end
|
||||
|
||||
def replace_invalid_utf8_of_path
|
||||
self.path = Redmine::CodesetUtil.replace_invalid_utf8(self.path)
|
||||
self.from_path = Redmine::CodesetUtil.replace_invalid_utf8(self.from_path)
|
||||
end
|
||||
|
||||
def init_path
|
||||
self.path ||= ""
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,332 +1,332 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Changeset < ActiveRecord::Base
|
||||
belongs_to :repository
|
||||
belongs_to :user
|
||||
include UserScoreHelper
|
||||
#after_save :be_user_score # user_score
|
||||
|
||||
has_many :filechanges, :class_name => 'Change', :dependent => :delete_all
|
||||
# fq
|
||||
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
|
||||
# end
|
||||
|
||||
#Added by nie
|
||||
has_one :project_status, :dependent => :destroy
|
||||
has_one :users_status
|
||||
#end
|
||||
|
||||
has_and_belongs_to_many :issues
|
||||
has_and_belongs_to_many :parents,
|
||||
:class_name => "Changeset",
|
||||
:join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
|
||||
:association_foreign_key => 'parent_id', :foreign_key => 'changeset_id'
|
||||
has_and_belongs_to_many :children,
|
||||
:class_name => "Changeset",
|
||||
:join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
|
||||
:association_foreign_key => 'changeset_id', :foreign_key => 'parent_id'
|
||||
|
||||
acts_as_event :title => Proc.new {|o| o.title},
|
||||
:description => :long_comments,
|
||||
:datetime => :committed_on,
|
||||
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}}
|
||||
|
||||
acts_as_searchable :columns => 'comments',
|
||||
:include => {:repository => :project},
|
||||
:project_key => "#{Repository.table_name}.project_id",
|
||||
:date_column => 'committed_on'
|
||||
|
||||
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
|
||||
:author_key => :user_id,
|
||||
:find_options => {:include => [:user, {:repository => :project}]}
|
||||
validates :repository_id, presence: true
|
||||
validates :revision, presence: true, uniqueness: {scope: :repository_id}
|
||||
validates :committed_on, presence: true
|
||||
validates :commit_date, presence: true
|
||||
validates :scmid, uniqueness: {scope: :repository_id, allow_nil: true}
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
|
||||
}
|
||||
|
||||
after_create :scan_for_issues,:refresh_changests#:be_user_score # user_score
|
||||
after_update :be_user_score
|
||||
after_destroy :down_user_score
|
||||
before_create :before_create_cs
|
||||
|
||||
# fq
|
||||
# after_create :act_as_activity
|
||||
# end
|
||||
|
||||
def revision=(r)
|
||||
write_attribute :revision, (r.nil? ? nil : r.to_s)
|
||||
end
|
||||
|
||||
# Returns the identifier of this changeset; depending on repository backends
|
||||
def identifier
|
||||
if repository.class.respond_to? :changeset_identifier
|
||||
repository.class.changeset_identifier self
|
||||
else
|
||||
revision.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def committed_on=(date)
|
||||
self.commit_date = date
|
||||
super
|
||||
end
|
||||
|
||||
# Returns the readable identifier
|
||||
def format_identifier
|
||||
if repository.class.respond_to? :format_changeset_identifier
|
||||
repository.class.format_changeset_identifier self
|
||||
else
|
||||
identifier
|
||||
end
|
||||
end
|
||||
|
||||
def project
|
||||
unless repository.nil?
|
||||
repository.project
|
||||
end
|
||||
end
|
||||
|
||||
def author
|
||||
user || committer.to_s.split('<').first
|
||||
end
|
||||
|
||||
def before_create_cs
|
||||
self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding)
|
||||
self.comments = self.class.normalize_comments(
|
||||
self.comments, repository.repo_log_encoding)
|
||||
self.user = repository.find_committer_user(self.committer)
|
||||
end
|
||||
|
||||
def scan_for_issues
|
||||
scan_comment_for_issue_ids
|
||||
end
|
||||
|
||||
TIMELOG_RE = /
|
||||
(
|
||||
((\d+)(h|hours?))((\d+)(m|min)?)?
|
||||
|
|
||||
((\d+)(h|hours?|m|min))
|
||||
|
|
||||
(\d+):(\d+)
|
||||
|
|
||||
(\d+([\.,]\d+)?)h?
|
||||
)
|
||||
/x
|
||||
|
||||
def scan_comment_for_issue_ids
|
||||
return if comments.blank?
|
||||
# keywords used to reference issues
|
||||
ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
|
||||
ref_keywords_any = ref_keywords.delete('*')
|
||||
# keywords used to fix issues
|
||||
fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip)
|
||||
|
||||
kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
|
||||
|
||||
referenced_issues = []
|
||||
|
||||
comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match|
|
||||
action, refs = match[2], match[3]
|
||||
next unless action.present? || ref_keywords_any
|
||||
|
||||
refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
|
||||
issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
|
||||
if issue
|
||||
referenced_issues << issue
|
||||
fix_issue(issue) if fix_keywords.include?(action.to_s.downcase)
|
||||
log_time(issue, hours) if hours && Setting.commit_logtime_enabled?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
referenced_issues.uniq!
|
||||
self.issues = referenced_issues unless referenced_issues.empty?
|
||||
end
|
||||
|
||||
def short_comments
|
||||
@short_comments || split_comments.first
|
||||
end
|
||||
|
||||
def long_comments
|
||||
@long_comments || split_comments.last
|
||||
end
|
||||
|
||||
def text_tag(ref_project=nil)
|
||||
tag = if scmid?
|
||||
"commit:#{scmid}"
|
||||
else
|
||||
"r#{revision}"
|
||||
end
|
||||
if repository && repository.identifier.present?
|
||||
tag = "#{repository.identifier}|#{tag}"
|
||||
end
|
||||
if ref_project && project && ref_project != project
|
||||
tag = "#{project.identifier}:#{tag}"
|
||||
end
|
||||
tag
|
||||
end
|
||||
|
||||
# Returns the title used for the changeset in the activity/search results
|
||||
def title
|
||||
repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : ''
|
||||
comm = short_comments.blank? ? '' : (': ' + short_comments)
|
||||
"#{l(:label_revision)} #{format_identifier}#{repo}#{comm}"
|
||||
end
|
||||
|
||||
# Returns the previous changeset
|
||||
def previous
|
||||
@previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first
|
||||
end
|
||||
|
||||
# Returns the next changeset
|
||||
def next
|
||||
@next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first
|
||||
end
|
||||
|
||||
# Creates a new Change from it's common parameters
|
||||
def create_change(change)
|
||||
Change.create(:changeset => self,
|
||||
:action => change[:action],
|
||||
:path => change[:path],
|
||||
:from_path => change[:from_path],
|
||||
:from_revision => change[:from_revision])
|
||||
end
|
||||
|
||||
# Finds an issue that can be referenced by the commit message
|
||||
def find_referenced_issue_by_id(id)
|
||||
return nil if id.blank?
|
||||
issue = Issue.find_by_id(id.to_i, :include => :project)
|
||||
if Setting.commit_cross_project_ref?
|
||||
# all issues can be referenced/fixed
|
||||
elsif issue
|
||||
# issue that belong to the repository project, a subproject or a parent project only
|
||||
unless issue.project &&
|
||||
(project == issue.project || project.is_ancestor_of?(issue.project) ||
|
||||
project.is_descendant_of?(issue.project))
|
||||
issue = nil
|
||||
end
|
||||
end
|
||||
issue
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def act_as_activity
|
||||
self.acts << Activity.new(:user_id => self.user_id)
|
||||
end
|
||||
|
||||
def fix_issue(issue)
|
||||
status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
|
||||
if status.nil?
|
||||
logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger
|
||||
return issue
|
||||
end
|
||||
|
||||
# the issue may have been updated by the closure of another one (eg. duplicate)
|
||||
issue.reload
|
||||
# don't change the status is the issue is closed
|
||||
return if issue.status && issue.status.is_closed?
|
||||
|
||||
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
|
||||
issue.status = status
|
||||
unless Setting.commit_fix_done_ratio.blank?
|
||||
issue.done_ratio = Setting.commit_fix_done_ratio.to_i
|
||||
end
|
||||
Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
|
||||
{ :changeset => self, :issue => issue })
|
||||
unless issue.save
|
||||
logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger
|
||||
end
|
||||
issue
|
||||
end
|
||||
|
||||
def log_time(issue, hours)
|
||||
time_entry = TimeEntry.new(
|
||||
:user => user,
|
||||
:hours => hours,
|
||||
:issue => issue,
|
||||
:spent_on => commit_date,
|
||||
:comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project),
|
||||
:locale => Setting.default_language)
|
||||
)
|
||||
time_entry.activity = log_time_activity unless log_time_activity.nil?
|
||||
|
||||
unless time_entry.save
|
||||
logger.warn("TimeEntry could not be created by changeset #{id}: #{time_entry.errors.full_messages}") if logger
|
||||
end
|
||||
time_entry
|
||||
end
|
||||
|
||||
def log_time_activity
|
||||
if Setting.commit_logtime_activity_id.to_i > 0
|
||||
TimeEntryActivity.find_by_id(Setting.commit_logtime_activity_id.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
def split_comments
|
||||
comments =~ /\A(.+?)\r?\n(.*)$/m
|
||||
@short_comments = $1 || comments
|
||||
@long_comments = $2.to_s.strip
|
||||
return @short_comments, @long_comments
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
# Strips and reencodes a commit log before insertion into the database
|
||||
def self.normalize_comments(str, encoding)
|
||||
Changeset.to_utf8(str.to_s.strip, encoding)
|
||||
end
|
||||
|
||||
def self.to_utf8(str, encoding)
|
||||
Redmine::CodesetUtil.to_utf8(str, encoding)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# update user score
|
||||
def be_user_score
|
||||
UserScore.project(:push_code, self.user,self, { changeset_id: self.id })
|
||||
unless self.user.nil?
|
||||
#更新用户等级
|
||||
UserLevels.update_user_level(self.user)
|
||||
update_changeset(self.user,1)
|
||||
update_changeset(self.user,2,self.repository.project)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#积分刷新
|
||||
def down_user_score
|
||||
UserLevels.update_user_level(self.user)
|
||||
update_changeset(self.user,1)
|
||||
update_changeset(self.user,2,self.repository.project)
|
||||
end
|
||||
|
||||
#刷新本次提交(补全相关信息如:user_id等)
|
||||
def refresh_changests
|
||||
unless self.repository.nil?
|
||||
self.repository.fetch_changesets if Setting.autofetch_changesets?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Changeset < ActiveRecord::Base
|
||||
belongs_to :repository
|
||||
belongs_to :user
|
||||
include UserScoreHelper
|
||||
#after_save :be_user_score # user_score
|
||||
|
||||
has_many :filechanges, :class_name => 'Change', :dependent => :delete_all
|
||||
# fq
|
||||
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
|
||||
# end
|
||||
|
||||
#Added by nie
|
||||
has_one :project_status, :dependent => :destroy
|
||||
has_one :users_status
|
||||
#end
|
||||
|
||||
has_and_belongs_to_many :issues
|
||||
has_and_belongs_to_many :parents,
|
||||
:class_name => "Changeset",
|
||||
:join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
|
||||
:association_foreign_key => 'parent_id', :foreign_key => 'changeset_id'
|
||||
has_and_belongs_to_many :children,
|
||||
:class_name => "Changeset",
|
||||
:join_table => "#{table_name_prefix}changeset_parents#{table_name_suffix}",
|
||||
:association_foreign_key => 'changeset_id', :foreign_key => 'parent_id'
|
||||
|
||||
acts_as_event :title => Proc.new {|o| o.title},
|
||||
:description => :long_comments,
|
||||
:datetime => :committed_on,
|
||||
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project, :repository_id => o.repository.identifier_param, :rev => o.identifier}}
|
||||
|
||||
acts_as_searchable :columns => 'comments',
|
||||
:include => {:repository => :project},
|
||||
:project_key => "#{Repository.table_name}.project_id",
|
||||
:date_column => 'committed_on'
|
||||
|
||||
acts_as_activity_provider :timestamp => "#{table_name}.committed_on",
|
||||
:author_key => :user_id,
|
||||
:find_options => {:include => [:user, {:repository => :project}]}
|
||||
validates :repository_id, presence: true
|
||||
validates :revision, presence: true, uniqueness: {scope: :repository_id}
|
||||
validates :committed_on, presence: true
|
||||
validates :commit_date, presence: true
|
||||
validates :scmid, uniqueness: {scope: :repository_id, allow_nil: true}
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
includes(:repository => :project).where(Project.allowed_to_condition(args.shift || User.current, :view_changesets, *args))
|
||||
}
|
||||
|
||||
after_create :scan_for_issues,:refresh_changests#:be_user_score # user_score
|
||||
after_update :be_user_score
|
||||
after_destroy :down_user_score
|
||||
before_create :before_create_cs
|
||||
|
||||
# fq
|
||||
# after_create :act_as_activity
|
||||
# end
|
||||
|
||||
def revision=(r)
|
||||
write_attribute :revision, (r.nil? ? nil : r.to_s)
|
||||
end
|
||||
|
||||
# Returns the identifier of this changeset; depending on repository backends
|
||||
def identifier
|
||||
if repository.class.respond_to? :changeset_identifier
|
||||
repository.class.changeset_identifier self
|
||||
else
|
||||
revision.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def committed_on=(date)
|
||||
self.commit_date = date
|
||||
super
|
||||
end
|
||||
|
||||
# Returns the readable identifier
|
||||
def format_identifier
|
||||
if repository.class.respond_to? :format_changeset_identifier
|
||||
repository.class.format_changeset_identifier self
|
||||
else
|
||||
identifier
|
||||
end
|
||||
end
|
||||
|
||||
def project
|
||||
unless repository.nil?
|
||||
repository.project
|
||||
end
|
||||
end
|
||||
|
||||
def author
|
||||
user || committer.to_s.split('<').first
|
||||
end
|
||||
|
||||
def before_create_cs
|
||||
self.committer = self.class.to_utf8(self.committer, repository.repo_log_encoding)
|
||||
self.comments = self.class.normalize_comments(
|
||||
self.comments, repository.repo_log_encoding)
|
||||
self.user = repository.find_committer_user(self.committer)
|
||||
end
|
||||
|
||||
def scan_for_issues
|
||||
scan_comment_for_issue_ids
|
||||
end
|
||||
|
||||
TIMELOG_RE = /
|
||||
(
|
||||
((\d+)(h|hours?))((\d+)(m|min)?)?
|
||||
|
|
||||
((\d+)(h|hours?|m|min))
|
||||
|
|
||||
(\d+):(\d+)
|
||||
|
|
||||
(\d+([\.,]\d+)?)h?
|
||||
)
|
||||
/x
|
||||
|
||||
def scan_comment_for_issue_ids
|
||||
return if comments.blank?
|
||||
# keywords used to reference issues
|
||||
ref_keywords = Setting.commit_ref_keywords.downcase.split(",").collect(&:strip)
|
||||
ref_keywords_any = ref_keywords.delete('*')
|
||||
# keywords used to fix issues
|
||||
fix_keywords = Setting.commit_fix_keywords.downcase.split(",").collect(&:strip)
|
||||
|
||||
kw_regexp = (ref_keywords + fix_keywords).collect{|kw| Regexp.escape(kw)}.join("|")
|
||||
|
||||
referenced_issues = []
|
||||
|
||||
comments.scan(/([\s\(\[,-]|^)((#{kw_regexp})[\s:]+)?(#\d+(\s+@#{TIMELOG_RE})?([\s,;&]+#\d+(\s+@#{TIMELOG_RE})?)*)(?=[[:punct:]]|\s|<|$)/i) do |match|
|
||||
action, refs = match[2], match[3]
|
||||
next unless action.present? || ref_keywords_any
|
||||
|
||||
refs.scan(/#(\d+)(\s+@#{TIMELOG_RE})?/).each do |m|
|
||||
issue, hours = find_referenced_issue_by_id(m[0].to_i), m[2]
|
||||
if issue
|
||||
referenced_issues << issue
|
||||
fix_issue(issue) if fix_keywords.include?(action.to_s.downcase)
|
||||
log_time(issue, hours) if hours && Setting.commit_logtime_enabled?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
referenced_issues.uniq!
|
||||
self.issues = referenced_issues unless referenced_issues.empty?
|
||||
end
|
||||
|
||||
def short_comments
|
||||
@short_comments || split_comments.first
|
||||
end
|
||||
|
||||
def long_comments
|
||||
@long_comments || split_comments.last
|
||||
end
|
||||
|
||||
def text_tag(ref_project=nil)
|
||||
tag = if scmid?
|
||||
"commit:#{scmid}"
|
||||
else
|
||||
"r#{revision}"
|
||||
end
|
||||
if repository && repository.identifier.present?
|
||||
tag = "#{repository.identifier}|#{tag}"
|
||||
end
|
||||
if ref_project && project && ref_project != project
|
||||
tag = "#{project.identifier}:#{tag}"
|
||||
end
|
||||
tag
|
||||
end
|
||||
|
||||
# Returns the title used for the changeset in the activity/search results
|
||||
def title
|
||||
repo = (repository && repository.identifier.present?) ? " (#{repository.identifier})" : ''
|
||||
comm = short_comments.blank? ? '' : (': ' + short_comments)
|
||||
"#{l(:label_revision)} #{format_identifier}#{repo}#{comm}"
|
||||
end
|
||||
|
||||
# Returns the previous changeset
|
||||
def previous
|
||||
@previous ||= Changeset.where(["id < ? AND repository_id = ?", id, repository_id]).order('id DESC').first
|
||||
end
|
||||
|
||||
# Returns the next changeset
|
||||
def next
|
||||
@next ||= Changeset.where(["id > ? AND repository_id = ?", id, repository_id]).order('id ASC').first
|
||||
end
|
||||
|
||||
# Creates a new Change from it's common parameters
|
||||
def create_change(change)
|
||||
Change.create(:changeset => self,
|
||||
:action => change[:action],
|
||||
:path => change[:path],
|
||||
:from_path => change[:from_path],
|
||||
:from_revision => change[:from_revision])
|
||||
end
|
||||
|
||||
# Finds an issue that can be referenced by the commit message
|
||||
def find_referenced_issue_by_id(id)
|
||||
return nil if id.blank?
|
||||
issue = Issue.find_by_id(id.to_i, :include => :project)
|
||||
if Setting.commit_cross_project_ref?
|
||||
# all issues can be referenced/fixed
|
||||
elsif issue
|
||||
# issue that belong to the repository project, a subproject or a parent project only
|
||||
unless issue.project &&
|
||||
(project == issue.project || project.is_ancestor_of?(issue.project) ||
|
||||
project.is_descendant_of?(issue.project))
|
||||
issue = nil
|
||||
end
|
||||
end
|
||||
issue
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def act_as_activity
|
||||
self.acts << Activity.new(:user_id => self.user_id)
|
||||
end
|
||||
|
||||
def fix_issue(issue)
|
||||
status = IssueStatus.find_by_id(Setting.commit_fix_status_id.to_i)
|
||||
if status.nil?
|
||||
logger.warn("No status matches commit_fix_status_id setting (#{Setting.commit_fix_status_id})") if logger
|
||||
return issue
|
||||
end
|
||||
|
||||
# the issue may have been updated by the closure of another one (eg. duplicate)
|
||||
issue.reload
|
||||
# don't change the status is the issue is closed
|
||||
return if issue.status && issue.status.is_closed?
|
||||
|
||||
journal = issue.init_journal(user || User.anonymous, ll(Setting.default_language, :text_status_changed_by_changeset, text_tag(issue.project)))
|
||||
issue.status = status
|
||||
unless Setting.commit_fix_done_ratio.blank?
|
||||
issue.done_ratio = Setting.commit_fix_done_ratio.to_i
|
||||
end
|
||||
Redmine::Hook.call_hook(:model_changeset_scan_commit_for_issue_ids_pre_issue_update,
|
||||
{ :changeset => self, :issue => issue })
|
||||
unless issue.save
|
||||
logger.warn("Issue ##{issue.id} could not be saved by changeset #{id}: #{issue.errors.full_messages}") if logger
|
||||
end
|
||||
issue
|
||||
end
|
||||
|
||||
def log_time(issue, hours)
|
||||
time_entry = TimeEntry.new(
|
||||
:user => user,
|
||||
:hours => hours,
|
||||
:issue => issue,
|
||||
:spent_on => commit_date,
|
||||
:comments => l(:text_time_logged_by_changeset, :value => text_tag(issue.project),
|
||||
:locale => Setting.default_language)
|
||||
)
|
||||
time_entry.activity = log_time_activity unless log_time_activity.nil?
|
||||
|
||||
unless time_entry.save
|
||||
logger.warn("TimeEntry could not be created by changeset #{id}: #{time_entry.errors.full_messages}") if logger
|
||||
end
|
||||
time_entry
|
||||
end
|
||||
|
||||
def log_time_activity
|
||||
if Setting.commit_logtime_activity_id.to_i > 0
|
||||
TimeEntryActivity.find_by_id(Setting.commit_logtime_activity_id.to_i)
|
||||
end
|
||||
end
|
||||
|
||||
def split_comments
|
||||
comments =~ /\A(.+?)\r?\n(.*)$/m
|
||||
@short_comments = $1 || comments
|
||||
@long_comments = $2.to_s.strip
|
||||
return @short_comments, @long_comments
|
||||
end
|
||||
|
||||
public
|
||||
|
||||
# Strips and reencodes a commit log before insertion into the database
|
||||
def self.normalize_comments(str, encoding)
|
||||
Changeset.to_utf8(str.to_s.strip, encoding)
|
||||
end
|
||||
|
||||
def self.to_utf8(str, encoding)
|
||||
Redmine::CodesetUtil.to_utf8(str, encoding)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# update user score
|
||||
def be_user_score
|
||||
UserScore.project(:push_code, self.user,self, { changeset_id: self.id })
|
||||
unless self.user.nil?
|
||||
#更新用户等级
|
||||
UserLevels.update_user_level(self.user)
|
||||
update_changeset(self.user,1)
|
||||
update_changeset(self.user,2,self.repository.project)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
#积分刷新
|
||||
def down_user_score
|
||||
UserLevels.update_user_level(self.user)
|
||||
update_changeset(self.user,1)
|
||||
update_changeset(self.user,2,self.repository.project)
|
||||
end
|
||||
|
||||
#刷新本次提交(补全相关信息如:user_id等)
|
||||
def refresh_changests
|
||||
unless self.repository.nil?
|
||||
self.repository.fetch_changesets if Setting.autofetch_changesets?
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Comment < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
belongs_to :commented, :polymorphic => true, :counter_cache => true
|
||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||
validates_presence_of :commented, :author, :comments
|
||||
safe_attributes 'comments'
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class Comment < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
belongs_to :commented, :polymorphic => true, :counter_cache => true
|
||||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
|
||||
validates_presence_of :commented, :author, :comments
|
||||
safe_attributes 'comments'
|
||||
end
|
||||
|
|
|
@ -1,134 +1,134 @@
|
|||
class Contest < ActiveRecord::Base
|
||||
attr_accessible :author_id, :budget, :commit, :deadline, :description, :name, :password
|
||||
include Redmine::SafeAttributes
|
||||
|
||||
belongs_to :author, :class_name => 'User', :foreign_key => :author_id
|
||||
has_many :contesting_projects, :dependent => :destroy
|
||||
has_many :projects, :through => :contesting_projects
|
||||
has_many :contesting_softapplications, :dependent => :destroy
|
||||
has_many :softapplications, :through => :contesting_softapplications, :dependent => :destroy
|
||||
has_many :projects_member, :class_name => 'User', :through => :projects
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
|
||||
has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy
|
||||
has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy
|
||||
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
|
||||
has_many :contestnotifications, :dependent => :destroy, :include => :author
|
||||
|
||||
|
||||
|
||||
acts_as_attachable
|
||||
|
||||
NAME_LENGTH_LIMIT = 60
|
||||
DESCRIPTION_LENGTH_LIMIT = 250
|
||||
validates :name, length: {maximum: NAME_LENGTH_LIMIT}, presence: true
|
||||
validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT}
|
||||
validates :author_id, presence: true
|
||||
validates :budget, presence: true
|
||||
validates :deadline, format: {:with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/}
|
||||
validate :validate_user
|
||||
after_create :act_as_activity
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
nil
|
||||
}
|
||||
|
||||
scope :like, lambda {|arg|
|
||||
if arg.blank?
|
||||
where(nil)
|
||||
else
|
||||
pattern = "%#{arg.to_s.strip.downcase}%"
|
||||
where("LOWER(id) LIKE :p OR LOWER(name) LIKE :p OR LOWER(description) LIKE :p", :p => pattern)
|
||||
end
|
||||
}
|
||||
|
||||
acts_as_watchable
|
||||
acts_as_taggable
|
||||
|
||||
acts_as_event :title => Proc.new {|o| "#{l(:label_requirement)} ##{o.id}: #{o.name}" },
|
||||
:description => :description,
|
||||
:author => :author,
|
||||
:url => Proc.new {|o| {:controller => 'contests', :action => 'show_contest', :id => o.id}}
|
||||
|
||||
acts_as_activity_provider :find_options => {:include => [:projects, :author]},
|
||||
:author_key => :author_id
|
||||
|
||||
safe_attributes 'name',
|
||||
'description',
|
||||
'budget',
|
||||
'deadline',
|
||||
'password'
|
||||
|
||||
|
||||
def add_jour(user, notes, reference_user_id = 0, options = {})
|
||||
if options.count == 0
|
||||
self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
|
||||
else
|
||||
jfm = self.journals_for_messages.build(options)
|
||||
jfm.save
|
||||
jfm
|
||||
end
|
||||
end
|
||||
|
||||
# modified by longjun
|
||||
# 这个函数没有用到
|
||||
# def self.creat_contests(budget, deadline, name, description=nil)
|
||||
# self.create(:author_id => User.current.id, :budget => budget,
|
||||
# :deadline => deadline, :name => name, :description => description, :commit => 0)
|
||||
# end
|
||||
# end longjun
|
||||
|
||||
def update_contests(budget, deadline, name, description=nil)
|
||||
if(User.current.id == self.author_id)
|
||||
self.name = name
|
||||
self.budget = budget
|
||||
self.deadline = deadline
|
||||
self.description = description
|
||||
self.save
|
||||
end
|
||||
end
|
||||
|
||||
def delete_contests
|
||||
unless self.nil?
|
||||
if User.current.id == self.author_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Closes open and locked project versions that are completed
|
||||
def close_completed_versions_contest
|
||||
Version.transaction do
|
||||
versions.where(:status => %w(open locked)).all.each do |version|
|
||||
if version.completed?
|
||||
version.update_attribute(:status, 'closed')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_commit(commit)
|
||||
self.update_attribute(:commit, commit)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :author_id, :invalid if author.nil? || !author.active?
|
||||
end
|
||||
|
||||
|
||||
def act_as_activity
|
||||
self.acts << Activity.new(:user_id => self.author_id)
|
||||
end
|
||||
|
||||
def validate_contest_manager(user_id)
|
||||
unless user_id.nil?
|
||||
if self.author_id == user_id
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
class Contest < ActiveRecord::Base
|
||||
attr_accessible :author_id, :budget, :commit, :deadline, :description, :name, :password
|
||||
include Redmine::SafeAttributes
|
||||
|
||||
belongs_to :author, :class_name => 'User', :foreign_key => :author_id
|
||||
has_many :contesting_projects, :dependent => :destroy
|
||||
has_many :projects, :through => :contesting_projects
|
||||
has_many :contesting_softapplications, :dependent => :destroy
|
||||
has_many :softapplications, :through => :contesting_softapplications, :dependent => :destroy
|
||||
has_many :projects_member, :class_name => 'User', :through => :projects
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :acts, :class_name => 'Activity', :as => :act, :dependent => :destroy
|
||||
has_many :join_in_competitions, foreign_key: 'competition_id', :dependent => :destroy
|
||||
has_many :join_in_contests, class_name: 'JoinInCompetition', foreign_key: 'competition_id', :dependent => :destroy
|
||||
has_many :praise_tread, as: :praise_tread_object, dependent: :destroy
|
||||
has_many :contestnotifications, :dependent => :destroy, :include => :author
|
||||
|
||||
|
||||
|
||||
acts_as_attachable
|
||||
|
||||
NAME_LENGTH_LIMIT = 60
|
||||
DESCRIPTION_LENGTH_LIMIT = 250
|
||||
validates :name, length: {maximum: NAME_LENGTH_LIMIT}, presence: true
|
||||
validates :description, length: {maximum: DESCRIPTION_LENGTH_LIMIT}
|
||||
validates :author_id, presence: true
|
||||
validates :budget, presence: true
|
||||
validates :deadline, format: {:with =>/^[1-9][0-9]{3}\-0?[1-9]|1[12]\-0?[1-9]|[12]\d|3[01]$/}
|
||||
validate :validate_user
|
||||
after_create :act_as_activity
|
||||
|
||||
scope :visible, lambda {|*args|
|
||||
nil
|
||||
}
|
||||
|
||||
scope :like, lambda {|arg|
|
||||
if arg.blank?
|
||||
where(nil)
|
||||
else
|
||||
pattern = "%#{arg.to_s.strip.downcase}%"
|
||||
where("LOWER(id) LIKE :p OR LOWER(name) LIKE :p OR LOWER(description) LIKE :p", :p => pattern)
|
||||
end
|
||||
}
|
||||
|
||||
acts_as_watchable
|
||||
acts_as_taggable
|
||||
|
||||
acts_as_event :title => Proc.new {|o| "#{l(:label_requirement)} ##{o.id}: #{o.name}" },
|
||||
:description => :description,
|
||||
:author => :author,
|
||||
:url => Proc.new {|o| {:controller => 'contests', :action => 'show_contest', :id => o.id}}
|
||||
|
||||
acts_as_activity_provider :find_options => {:include => [:projects, :author]},
|
||||
:author_key => :author_id
|
||||
|
||||
safe_attributes 'name',
|
||||
'description',
|
||||
'budget',
|
||||
'deadline',
|
||||
'password'
|
||||
|
||||
|
||||
def add_jour(user, notes, reference_user_id = 0, options = {})
|
||||
if options.count == 0
|
||||
self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
|
||||
else
|
||||
jfm = self.journals_for_messages.build(options)
|
||||
jfm.save
|
||||
jfm
|
||||
end
|
||||
end
|
||||
|
||||
# modified by longjun
|
||||
# 这个函数没有用到
|
||||
# def self.creat_contests(budget, deadline, name, description=nil)
|
||||
# self.create(:author_id => User.current.id, :budget => budget,
|
||||
# :deadline => deadline, :name => name, :description => description, :commit => 0)
|
||||
# end
|
||||
# end longjun
|
||||
|
||||
def update_contests(budget, deadline, name, description=nil)
|
||||
if(User.current.id == self.author_id)
|
||||
self.name = name
|
||||
self.budget = budget
|
||||
self.deadline = deadline
|
||||
self.description = description
|
||||
self.save
|
||||
end
|
||||
end
|
||||
|
||||
def delete_contests
|
||||
unless self.nil?
|
||||
if User.current.id == self.author_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Closes open and locked project versions that are completed
|
||||
def close_completed_versions_contest
|
||||
Version.transaction do
|
||||
versions.where(:status => %w(open locked)).all.each do |version|
|
||||
if version.completed?
|
||||
version.update_attribute(:status, 'closed')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def set_commit(commit)
|
||||
self.update_attribute(:commit, commit)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :author_id, :invalid if author.nil? || !author.active?
|
||||
end
|
||||
|
||||
|
||||
def act_as_activity
|
||||
self.acts << Activity.new(:user_id => self.author_id)
|
||||
end
|
||||
|
||||
def validate_contest_manager(user_id)
|
||||
unless user_id.nil?
|
||||
if self.author_id == user_id
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class ContestNotification < ActiveRecord::Base
|
||||
attr_accessible :content, :title
|
||||
validates :title, length: {maximum: 30}
|
||||
end
|
||||
class ContestNotification < ActiveRecord::Base
|
||||
attr_accessible :content, :title
|
||||
validates :title, length: {maximum: 30}
|
||||
end
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
class ContestingProject < ActiveRecord::Base
|
||||
attr_accessible :contest_id, :description, :project_id, :user_id, :reward
|
||||
|
||||
belongs_to :contest
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
|
||||
DESCRIPTION_LENGTH_LIMIT = 500
|
||||
validates :description, length: {maximum:DESCRIPTION_LENGTH_LIMIT }
|
||||
validates :user_id, presence: true
|
||||
validates :contest_id, presence: true, uniqueness: {scope: :project_id}
|
||||
validates :project_id, presence: true
|
||||
|
||||
validate :validate_user
|
||||
validate :validate_contest
|
||||
validate :validate_project
|
||||
|
||||
def self.create_contesting(contest_id, project_id, description = nil)
|
||||
self.create(:user_id => User.current.id, :contest_id => contest_id,
|
||||
:project_id => project_id, :description => description)
|
||||
end
|
||||
|
||||
|
||||
def update_reward(which)
|
||||
self.update_attribute(:reward,which)
|
||||
end
|
||||
|
||||
def get_reward
|
||||
self.reward
|
||||
end
|
||||
|
||||
def cancel_contesting
|
||||
unless self.nil?
|
||||
if User.current.id == self.user_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :user_id, :invalid if user.nil? || !user.active?
|
||||
end
|
||||
|
||||
def validate_contest
|
||||
errors.add :contest_id, :invalid if contest.nil?
|
||||
end
|
||||
|
||||
def validate_project
|
||||
errors.add :project_id, :invalid if project.nil?
|
||||
end
|
||||
end
|
||||
class ContestingProject < ActiveRecord::Base
|
||||
attr_accessible :contest_id, :description, :project_id, :user_id, :reward
|
||||
|
||||
belongs_to :contest
|
||||
belongs_to :project
|
||||
belongs_to :user
|
||||
|
||||
DESCRIPTION_LENGTH_LIMIT = 500
|
||||
validates :description, length: {maximum:DESCRIPTION_LENGTH_LIMIT }
|
||||
validates :user_id, presence: true
|
||||
validates :contest_id, presence: true, uniqueness: {scope: :project_id}
|
||||
validates :project_id, presence: true
|
||||
|
||||
validate :validate_user
|
||||
validate :validate_contest
|
||||
validate :validate_project
|
||||
|
||||
def self.create_contesting(contest_id, project_id, description = nil)
|
||||
self.create(:user_id => User.current.id, :contest_id => contest_id,
|
||||
:project_id => project_id, :description => description)
|
||||
end
|
||||
|
||||
|
||||
def update_reward(which)
|
||||
self.update_attribute(:reward,which)
|
||||
end
|
||||
|
||||
def get_reward
|
||||
self.reward
|
||||
end
|
||||
|
||||
def cancel_contesting
|
||||
unless self.nil?
|
||||
if User.current.id == self.user_id
|
||||
self.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_user
|
||||
errors.add :user_id, :invalid if user.nil? || !user.active?
|
||||
end
|
||||
|
||||
def validate_contest
|
||||
errors.add :contest_id, :invalid if contest.nil?
|
||||
end
|
||||
|
||||
def validate_project
|
||||
errors.add :project_id, :invalid if project.nil?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,310 +1,310 @@
|
|||
class Course < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
|
||||
STATUS_ACTIVE = 1
|
||||
STATUS_CLOSED = 5
|
||||
STATUS_ARCHIVED = 9
|
||||
|
||||
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period
|
||||
belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
|
||||
belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表
|
||||
belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表
|
||||
has_many :bid
|
||||
has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
|
||||
has_many :memberships, :class_name => 'Member'
|
||||
has_many :member_principals, :class_name => 'Member',
|
||||
:include => :principal,
|
||||
:conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})"
|
||||
has_many :principals, :through => :member_principals, :source => :principal
|
||||
has_many :users, :through => :members
|
||||
has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :homework_for_courses, :dependent => :destroy
|
||||
has_many :student, :class_name => 'StudentsForCourse', :source => :user
|
||||
has_many :course_infos, :class_name => 'CourseInfos',:dependent => :destroy
|
||||
has_many :enabled_modules, :dependent => :delete_all
|
||||
has_many :boards, :dependent => :destroy, :order => "position ASC"
|
||||
#has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy
|
||||
has_many :news, :dependent => :destroy, :include => :author
|
||||
has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy
|
||||
|
||||
acts_as_taggable
|
||||
acts_as_nested_set :order => 'name', :dependent => :destroy
|
||||
acts_as_attachable :view_permission => :view_files,
|
||||
:delete_permission => :manage_files
|
||||
|
||||
validates :password, presence: true
|
||||
validates :term, presence: true
|
||||
validates :name, presence: true
|
||||
validates :class_period, presence: true,format: {:with =>/^\d*$/}
|
||||
before_save :self_validate
|
||||
after_create :create_board_sync
|
||||
before_destroy :delete_all_members
|
||||
|
||||
safe_attributes 'extra',
|
||||
'time',
|
||||
'name',
|
||||
'extra',
|
||||
'code',
|
||||
'location',
|
||||
'tea_id',
|
||||
'password',
|
||||
'term',
|
||||
'is_public',
|
||||
'description',
|
||||
'class_period'
|
||||
|
||||
acts_as_customizable
|
||||
|
||||
scope :all_course
|
||||
scope :active, lambda { where(:status => STATUS_ACTIVE) }
|
||||
scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
|
||||
scope :all_public, lambda { where(:is_public => true) }
|
||||
scope :visible, lambda {|*args| where(Course.visible_condition(args.shift || User.current, *args)) }
|
||||
scope :allowed_to, lambda {|*args|
|
||||
user = User.current
|
||||
permission = nil
|
||||
if args.first.is_a?(Symbol)
|
||||
permission = args.shift
|
||||
else
|
||||
user = args.shift
|
||||
permission = args.shift
|
||||
end
|
||||
where(Course.allowed_to_condition(user, permission, *args))
|
||||
}
|
||||
scope :like, lambda {|arg|
|
||||
if arg.blank?
|
||||
where(nil)
|
||||
else
|
||||
pattern = "%#{arg.to_s.strip.downcase}%"
|
||||
where(" LOWER(name) LIKE :p ", :p => pattern)
|
||||
end
|
||||
}
|
||||
|
||||
def visible?(user=User.current)
|
||||
user.allowed_to?(:view_course, self)
|
||||
end
|
||||
|
||||
def parent_id_changed?
|
||||
false
|
||||
end
|
||||
|
||||
# Returns the mail adresses of users that should be always notified on project events
|
||||
def recipients
|
||||
notified_users.collect {|user| user.mail}
|
||||
end
|
||||
|
||||
# Returns the users that should be notified on project events
|
||||
def notified_users
|
||||
# TODO: User part should be extracted to User#notify_about?
|
||||
members.select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal}
|
||||
end
|
||||
|
||||
|
||||
# 课程的短描述信息
|
||||
def short_description(length = 255)
|
||||
description.gsub(/<\/?.*?>/,"").html_safe if description
|
||||
#description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description
|
||||
end
|
||||
|
||||
# 课程的短名称信息
|
||||
def short_name(length = 8)
|
||||
name.gsub(/<\/?.*?>/,"").html_safe if name
|
||||
end
|
||||
|
||||
def strip_html(html)
|
||||
return html if html.empty? || !html.include?('<')
|
||||
output = ""
|
||||
tokenizer = HTML::Tokenizer.new(html)
|
||||
while token = tokenizer.next
|
||||
node = HTML::Node.parse(nil, 0, 0, token, false)
|
||||
output += token unless (node.kind_of? HTML::Tag) or (token =~ /^<!/)
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
def extra_frozen?
|
||||
errors[:extra].blank? && !(new_record? || extra.blank?)
|
||||
end
|
||||
|
||||
def archived?
|
||||
self.status == STATUS_ARCHIVED
|
||||
end
|
||||
|
||||
def self.visible_condition(user, options={})
|
||||
allowed_to_condition(user, :view_course, options)
|
||||
end
|
||||
|
||||
# 获取课程的资源类型列表
|
||||
def attachmenttypes
|
||||
@attachmenttypes = Attachmentstype.find(:all, :conditions => ["#{Attachmentstype.table_name}.typeId= ?",self.attachmenttype ])
|
||||
end
|
||||
|
||||
|
||||
# 获取资源后缀名列表
|
||||
def contenttypes
|
||||
attachmenttypes
|
||||
if @attachmenttypes.length >0
|
||||
@attachmenttypes.last().suffixArr
|
||||
end
|
||||
end
|
||||
|
||||
def active?
|
||||
self.status == STATUS_ACTIVE
|
||||
end
|
||||
|
||||
#课程权限判断
|
||||
def allows_to?(action)
|
||||
if archived?
|
||||
# No action allowed on archived projects
|
||||
return false
|
||||
end
|
||||
unless active? || Redmine::AccessControl.read_action?(action)
|
||||
# No write action allowed on closed projects
|
||||
return false
|
||||
end
|
||||
# No action allowed on disabled modules
|
||||
if action.is_a? Hash
|
||||
allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
|
||||
else
|
||||
allowed_permissions.include? action
|
||||
end
|
||||
end
|
||||
|
||||
# 课程允许的权限集合
|
||||
def allowed_permissions
|
||||
@allowed_permissions ||= begin
|
||||
module_names = enabled_modules.all(:select => :name).collect {|m| m.name}
|
||||
Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
|
||||
end
|
||||
end
|
||||
|
||||
# 课程允许的动作集合
|
||||
def allowed_actions
|
||||
@actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
|
||||
end
|
||||
|
||||
# 返回用户组可以访问的课程
|
||||
def users_by_role
|
||||
members.includes(:user, :roles).all.inject({}) do |h, m|
|
||||
m.roles.each do |r|
|
||||
h[r] ||= []
|
||||
h[r] << m.user
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
#自定义验证
|
||||
def self_validate
|
||||
|
||||
end
|
||||
|
||||
# 创建课程讨论区
|
||||
def create_board_sync
|
||||
@board = self.boards.build
|
||||
self.name=" #{l(:label_borad_course) }"
|
||||
@board.name = self.name
|
||||
@board.description = self.name.to_s
|
||||
@board.project_id = -1
|
||||
if @board.save
|
||||
logger.debug "[Course Model] ===> #{@board.to_json}"
|
||||
else
|
||||
logger.error "[Course Model] ===> Auto create board when course saved, because #{@board.full_messages}"
|
||||
end
|
||||
end
|
||||
|
||||
# 新增课程留言
|
||||
# add by nwb
|
||||
def self.add_new_jour(user, notes, id, options={})
|
||||
course = Course.find(id)
|
||||
if options.count == 0
|
||||
pjfm = course.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0)
|
||||
else
|
||||
pjfm = course.journals_for_messages.build(options)
|
||||
end
|
||||
pjfm.save
|
||||
pjfm
|
||||
end
|
||||
|
||||
# 删除课程所有成员
|
||||
def delete_all_members
|
||||
if self.members && self.members.count > 0
|
||||
me, mr = Member.table_name, MemberRole.table_name
|
||||
connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.course_id = #{id})")
|
||||
Member.delete_all(['course_id = ?', id])
|
||||
end
|
||||
end
|
||||
|
||||
def get_endup_time
|
||||
begin
|
||||
end_time = Time.parse(self.endup_time)
|
||||
rescue Exception => e
|
||||
end_time = Time.parse("3000-01-01")
|
||||
Rails.logger.error "[Error] course endup_time error. ===> #{e}"
|
||||
ensure
|
||||
return end_time
|
||||
end
|
||||
end
|
||||
|
||||
def get_time
|
||||
begin
|
||||
time = Date.new(self.time).to_time
|
||||
rescue Exception => e
|
||||
time = Time.parse("3000-01-01")
|
||||
Rails.logger.error "[Error] course time error. ===> #{e}"
|
||||
ensure
|
||||
return time
|
||||
end
|
||||
end
|
||||
|
||||
def self.allowed_to_condition(user, permission, options={})
|
||||
perm = Redmine::AccessControl.permission(permission)
|
||||
base_statement = (perm && perm.read? ? "#{Course.table_name}.status <> #{Course::STATUS_ARCHIVED}" : "#{Course.table_name}.status = #{Course::STATUS_ACTIVE}")
|
||||
if perm && perm.course_module
|
||||
base_statement << " AND #{Course.table_name}.id IN (SELECT em.course_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.course_module}')"
|
||||
end
|
||||
|
||||
if options[:course]
|
||||
course_statement = "#{Course.table_name}.id = #{options[:course].id}"
|
||||
course_statement << " OR (#{Course.table_name}.lft > #{options[:course].lft} AND #{Course.table_name}.rgt < #{options[:course].rgt})" if options[:with_subcourses]
|
||||
base_statement = "(#{course_statement}) AND (#{base_statement})"
|
||||
end
|
||||
|
||||
if user.admin?
|
||||
base_statement
|
||||
else
|
||||
statement_by_role = {}
|
||||
unless options[:member]
|
||||
role = user.logged? ? Role.non_member : Role.anonymous
|
||||
if role.allowed_to?(permission)
|
||||
statement_by_role[role] = "#{Course.table_name}.is_public = #{connection.quoted_true}"
|
||||
end
|
||||
end
|
||||
if user.logged?
|
||||
user.courses_by_role.each do |role, courses|
|
||||
if role.allowed_to?(permission) && courses.any?
|
||||
statement_by_role[role] = "#{Course.table_name}.id IN (#{courses.collect(&:id).join(',')})"
|
||||
end
|
||||
end
|
||||
end
|
||||
if statement_by_role.empty?
|
||||
"1=0"
|
||||
else
|
||||
if block_given?
|
||||
statement_by_role.each do |role, statement|
|
||||
if s = yield(role, user)
|
||||
statement_by_role[role] = "(#{statement} AND (#{s}))"
|
||||
end
|
||||
end
|
||||
end
|
||||
"((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题
|
||||
#def name
|
||||
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
|
||||
#end
|
||||
end
|
||||
class Course < ActiveRecord::Base
|
||||
include Redmine::SafeAttributes
|
||||
|
||||
STATUS_ACTIVE = 1
|
||||
STATUS_CLOSED = 5
|
||||
STATUS_ARCHIVED = 9
|
||||
|
||||
attr_accessible :code, :extra, :name, :state, :tea_id, :time , :location, :state, :term, :password,:is_public,:description,:class_period
|
||||
belongs_to :project, :class_name => 'Course', :foreign_key => :extra, primary_key: :identifier
|
||||
belongs_to :teacher, :class_name => 'User', :foreign_key => :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表
|
||||
belongs_to :school, :class_name => 'School', :foreign_key => :school_id #定义一个方法school,该方法通过school_id来调用School表
|
||||
has_many :bid
|
||||
has_many :members, :include => [:principal, :roles], :conditions => "#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE}"
|
||||
has_many :memberships, :class_name => 'Member'
|
||||
has_many :member_principals, :class_name => 'Member',
|
||||
:include => :principal,
|
||||
:conditions => "#{Principal.table_name}.type='Group' OR (#{Principal.table_name}.type='User' AND #{Principal.table_name}.status=#{Principal::STATUS_ACTIVE})"
|
||||
has_many :principals, :through => :member_principals, :source => :principal
|
||||
has_many :users, :through => :members
|
||||
has_many :homeworks, :through => :homework_for_courses, :source => :bid, :dependent => :destroy
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :homework_for_courses, :dependent => :destroy
|
||||
has_many :student, :class_name => 'StudentsForCourse', :source => :user
|
||||
has_many :course_infos, :class_name => 'CourseInfos',:dependent => :destroy
|
||||
has_many :enabled_modules, :dependent => :delete_all
|
||||
has_many :boards, :dependent => :destroy, :order => "position ASC"
|
||||
#has_many :course_journals_for_messages, :class_name => 'CourseJournalsForMessage', :as => :jour, :dependent => :destroy
|
||||
has_many :news, :dependent => :destroy, :include => :author
|
||||
has_one :course_status, :class_name => "CourseStatus", :dependent => :destroy
|
||||
|
||||
acts_as_taggable
|
||||
acts_as_nested_set :order => 'name', :dependent => :destroy
|
||||
acts_as_attachable :view_permission => :view_files,
|
||||
:delete_permission => :manage_files
|
||||
|
||||
validates :password, presence: true
|
||||
validates :term, presence: true
|
||||
validates :name, presence: true
|
||||
validates :class_period, presence: true,format: {:with =>/^\d*$/}
|
||||
before_save :self_validate
|
||||
after_create :create_board_sync
|
||||
before_destroy :delete_all_members
|
||||
|
||||
safe_attributes 'extra',
|
||||
'time',
|
||||
'name',
|
||||
'extra',
|
||||
'code',
|
||||
'location',
|
||||
'tea_id',
|
||||
'password',
|
||||
'term',
|
||||
'is_public',
|
||||
'description',
|
||||
'class_period'
|
||||
|
||||
acts_as_customizable
|
||||
|
||||
scope :all_course
|
||||
scope :active, lambda { where(:status => STATUS_ACTIVE) }
|
||||
scope :status, lambda {|arg| where(arg.blank? ? nil : {:status => arg.to_i}) }
|
||||
scope :all_public, lambda { where(:is_public => true) }
|
||||
scope :visible, lambda {|*args| where(Course.visible_condition(args.shift || User.current, *args)) }
|
||||
scope :allowed_to, lambda {|*args|
|
||||
user = User.current
|
||||
permission = nil
|
||||
if args.first.is_a?(Symbol)
|
||||
permission = args.shift
|
||||
else
|
||||
user = args.shift
|
||||
permission = args.shift
|
||||
end
|
||||
where(Course.allowed_to_condition(user, permission, *args))
|
||||
}
|
||||
scope :like, lambda {|arg|
|
||||
if arg.blank?
|
||||
where(nil)
|
||||
else
|
||||
pattern = "%#{arg.to_s.strip.downcase}%"
|
||||
where(" LOWER(name) LIKE :p ", :p => pattern)
|
||||
end
|
||||
}
|
||||
|
||||
def visible?(user=User.current)
|
||||
user.allowed_to?(:view_course, self)
|
||||
end
|
||||
|
||||
def parent_id_changed?
|
||||
false
|
||||
end
|
||||
|
||||
# Returns the mail adresses of users that should be always notified on project events
|
||||
def recipients
|
||||
notified_users.collect {|user| user.mail}
|
||||
end
|
||||
|
||||
# Returns the users that should be notified on project events
|
||||
def notified_users
|
||||
# TODO: User part should be extracted to User#notify_about?
|
||||
members.select {|m| m.principal.present? && (m.mail_notification? || m.principal.mail_notification == 'all')}.collect {|m| m.principal}
|
||||
end
|
||||
|
||||
|
||||
# 课程的短描述信息
|
||||
def short_description(length = 255)
|
||||
description.gsub(/<\/?.*?>/,"").html_safe if description
|
||||
#description.gsub(/^(.{#{length}}[^\n\r]*).*$/m, '\1...').strip if description
|
||||
end
|
||||
|
||||
# 课程的短名称信息
|
||||
def short_name(length = 8)
|
||||
name.gsub(/<\/?.*?>/,"").html_safe if name
|
||||
end
|
||||
|
||||
def strip_html(html)
|
||||
return html if html.empty? || !html.include?('<')
|
||||
output = ""
|
||||
tokenizer = HTML::Tokenizer.new(html)
|
||||
while token = tokenizer.next
|
||||
node = HTML::Node.parse(nil, 0, 0, token, false)
|
||||
output += token unless (node.kind_of? HTML::Tag) or (token =~ /^<!/)
|
||||
end
|
||||
return output
|
||||
end
|
||||
|
||||
def extra_frozen?
|
||||
errors[:extra].blank? && !(new_record? || extra.blank?)
|
||||
end
|
||||
|
||||
def archived?
|
||||
self.status == STATUS_ARCHIVED
|
||||
end
|
||||
|
||||
def self.visible_condition(user, options={})
|
||||
allowed_to_condition(user, :view_course, options)
|
||||
end
|
||||
|
||||
# 获取课程的资源类型列表
|
||||
def attachmenttypes
|
||||
@attachmenttypes = Attachmentstype.find(:all, :conditions => ["#{Attachmentstype.table_name}.typeId= ?",self.attachmenttype ])
|
||||
end
|
||||
|
||||
|
||||
# 获取资源后缀名列表
|
||||
def contenttypes
|
||||
attachmenttypes
|
||||
if @attachmenttypes.length >0
|
||||
@attachmenttypes.last().suffixArr
|
||||
end
|
||||
end
|
||||
|
||||
def active?
|
||||
self.status == STATUS_ACTIVE
|
||||
end
|
||||
|
||||
#课程权限判断
|
||||
def allows_to?(action)
|
||||
if archived?
|
||||
# No action allowed on archived projects
|
||||
return false
|
||||
end
|
||||
unless active? || Redmine::AccessControl.read_action?(action)
|
||||
# No write action allowed on closed projects
|
||||
return false
|
||||
end
|
||||
# No action allowed on disabled modules
|
||||
if action.is_a? Hash
|
||||
allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
|
||||
else
|
||||
allowed_permissions.include? action
|
||||
end
|
||||
end
|
||||
|
||||
# 课程允许的权限集合
|
||||
def allowed_permissions
|
||||
@allowed_permissions ||= begin
|
||||
module_names = enabled_modules.all(:select => :name).collect {|m| m.name}
|
||||
Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
|
||||
end
|
||||
end
|
||||
|
||||
# 课程允许的动作集合
|
||||
def allowed_actions
|
||||
@actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
|
||||
end
|
||||
|
||||
# 返回用户组可以访问的课程
|
||||
def users_by_role
|
||||
members.includes(:user, :roles).all.inject({}) do |h, m|
|
||||
m.roles.each do |r|
|
||||
h[r] ||= []
|
||||
h[r] << m.user
|
||||
end
|
||||
h
|
||||
end
|
||||
end
|
||||
|
||||
#自定义验证
|
||||
def self_validate
|
||||
|
||||
end
|
||||
|
||||
# 创建课程讨论区
|
||||
def create_board_sync
|
||||
@board = self.boards.build
|
||||
self.name=" #{l(:label_borad_course) }"
|
||||
@board.name = self.name
|
||||
@board.description = self.name.to_s
|
||||
@board.project_id = -1
|
||||
if @board.save
|
||||
logger.debug "[Course Model] ===> #{@board.to_json}"
|
||||
else
|
||||
logger.error "[Course Model] ===> Auto create board when course saved, because #{@board.full_messages}"
|
||||
end
|
||||
end
|
||||
|
||||
# 新增课程留言
|
||||
# add by nwb
|
||||
def self.add_new_jour(user, notes, id, options={})
|
||||
course = Course.find(id)
|
||||
if options.count == 0
|
||||
pjfm = course.journals_for_messages.build(:user_id => user.id, :notes => notes, :reply_id => 0)
|
||||
else
|
||||
pjfm = course.journals_for_messages.build(options)
|
||||
end
|
||||
pjfm.save
|
||||
pjfm
|
||||
end
|
||||
|
||||
# 删除课程所有成员
|
||||
def delete_all_members
|
||||
if self.members && self.members.count > 0
|
||||
me, mr = Member.table_name, MemberRole.table_name
|
||||
connection.delete("DELETE FROM #{mr} WHERE #{mr}.member_id IN (SELECT #{me}.id FROM #{me} WHERE #{me}.course_id = #{id})")
|
||||
Member.delete_all(['course_id = ?', id])
|
||||
end
|
||||
end
|
||||
|
||||
def get_endup_time
|
||||
begin
|
||||
end_time = Time.parse(self.endup_time)
|
||||
rescue Exception => e
|
||||
end_time = Time.parse("3000-01-01")
|
||||
Rails.logger.error "[Error] course endup_time error. ===> #{e}"
|
||||
ensure
|
||||
return end_time
|
||||
end
|
||||
end
|
||||
|
||||
def get_time
|
||||
begin
|
||||
time = Date.new(self.time).to_time
|
||||
rescue Exception => e
|
||||
time = Time.parse("3000-01-01")
|
||||
Rails.logger.error "[Error] course time error. ===> #{e}"
|
||||
ensure
|
||||
return time
|
||||
end
|
||||
end
|
||||
|
||||
def self.allowed_to_condition(user, permission, options={})
|
||||
perm = Redmine::AccessControl.permission(permission)
|
||||
base_statement = (perm && perm.read? ? "#{Course.table_name}.status <> #{Course::STATUS_ARCHIVED}" : "#{Course.table_name}.status = #{Course::STATUS_ACTIVE}")
|
||||
if perm && perm.course_module
|
||||
base_statement << " AND #{Course.table_name}.id IN (SELECT em.course_id FROM #{EnabledModule.table_name} em WHERE em.name='#{perm.course_module}')"
|
||||
end
|
||||
|
||||
if options[:course]
|
||||
course_statement = "#{Course.table_name}.id = #{options[:course].id}"
|
||||
course_statement << " OR (#{Course.table_name}.lft > #{options[:course].lft} AND #{Course.table_name}.rgt < #{options[:course].rgt})" if options[:with_subcourses]
|
||||
base_statement = "(#{course_statement}) AND (#{base_statement})"
|
||||
end
|
||||
|
||||
if user.admin?
|
||||
base_statement
|
||||
else
|
||||
statement_by_role = {}
|
||||
unless options[:member]
|
||||
role = user.logged? ? Role.non_member : Role.anonymous
|
||||
if role.allowed_to?(permission)
|
||||
statement_by_role[role] = "#{Course.table_name}.is_public = #{connection.quoted_true}"
|
||||
end
|
||||
end
|
||||
if user.logged?
|
||||
user.courses_by_role.each do |role, courses|
|
||||
if role.allowed_to?(permission) && courses.any?
|
||||
statement_by_role[role] = "#{Course.table_name}.id IN (#{courses.collect(&:id).join(',')})"
|
||||
end
|
||||
end
|
||||
end
|
||||
if statement_by_role.empty?
|
||||
"1=0"
|
||||
else
|
||||
if block_given?
|
||||
statement_by_role.each do |role, statement|
|
||||
if s = yield(role, user)
|
||||
statement_by_role[role] = "(#{statement} AND (#{s}))"
|
||||
end
|
||||
end
|
||||
end
|
||||
"((#{base_statement}) AND (#{statement_by_role.values.join(' OR ')}))"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#项目与课程分离后,很多课程的名称等信息为空,这些数据信息存储在项目表中!!就是数据兼容的问题
|
||||
#def name
|
||||
# read_attribute('name') || Project.find_by_identifier(self.extra).try(:name)
|
||||
#end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class CourseStatus < ActiveRecord::Base
|
||||
attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count
|
||||
belongs_to :course
|
||||
validates :course_id, presence: true,uniqueness: true
|
||||
end
|
||||
class CourseStatus < ActiveRecord::Base
|
||||
attr_accessible :changesets_count, :course_ac_para, :course_id, :grade, :watchers_count
|
||||
belongs_to :course
|
||||
validates :course_id, presence: true,uniqueness: true
|
||||
end
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EnabledModule < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name, :scope => :project_id
|
||||
|
||||
after_create :module_enabled
|
||||
private
|
||||
|
||||
# after_create callback used to do things when a module is enabled
|
||||
def module_enabled
|
||||
case name
|
||||
when 'wiki'
|
||||
# Create a wiki with a default start page
|
||||
if project && project.wiki.nil?
|
||||
Wiki.create(:project => project, :start_page => 'Wiki')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
class EnabledModule < ActiveRecord::Base
|
||||
belongs_to :project
|
||||
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name, :scope => :project_id
|
||||
|
||||
after_create :module_enabled
|
||||
private
|
||||
|
||||
# after_create callback used to do things when a module is enabled
|
||||
def module_enabled
|
||||
case name
|
||||
when 'wiki'
|
||||
# Create a wiki with a default start page
|
||||
if project && project.wiki.nil?
|
||||
Wiki.create(:project => project, :start_page => 'Wiki')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
class Softapplication < ActiveRecord::Base
|
||||
attr_accessible :android_min_version_available, :app_type_id, :app_type_name, :description, :name, :user_id, :contest_id, :application_developers, :deposit_project_url, :deposit_project
|
||||
acts_as_attachable :view_permission => :view_files
|
||||
seems_rateable :allow_update => true, :dimensions => :quality
|
||||
|
||||
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :contesting_softapplications, :dependent => :destroy
|
||||
#has_many :projecting_softapplications, :dependent => :destroy
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
has_many :contests, :through => :contesting_softapplications
|
||||
|
||||
validates_length_of :name, :maximum => 25
|
||||
validates_length_of :application_developers, :maximum => 125
|
||||
validates_length_of :android_min_version_available, :maximum => 125
|
||||
|
||||
def add_jour(user, notes, reference_user_id = 0, options = {})
|
||||
if options.count == 0
|
||||
self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
|
||||
else
|
||||
jfm = self.journals_for_messages.build(options)
|
||||
jfm.save
|
||||
jfm
|
||||
end
|
||||
end
|
||||
def set_commit(commit)
|
||||
self.update_attribute(:commit, commit)
|
||||
end
|
||||
|
||||
def editable_by? usr
|
||||
usr.admin? || self.user == usr
|
||||
end
|
||||
|
||||
def destroyable_by? usr
|
||||
self.user == usr || usr.admin?
|
||||
end
|
||||
|
||||
end
|
||||
class Softapplication < ActiveRecord::Base
|
||||
attr_accessible :android_min_version_available, :app_type_id, :app_type_name, :description, :name, :user_id, :contest_id, :application_developers, :deposit_project_url, :deposit_project
|
||||
acts_as_attachable :view_permission => :view_files
|
||||
seems_rateable :allow_update => true, :dimensions => :quality
|
||||
|
||||
|
||||
has_many :journals_for_messages, :as => :jour, :dependent => :destroy
|
||||
has_many :contesting_softapplications, :dependent => :destroy
|
||||
#has_many :projecting_softapplications, :dependent => :destroy
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
has_many :contests, :through => :contesting_softapplications
|
||||
|
||||
validates_length_of :name, :maximum => 25
|
||||
validates_length_of :application_developers, :maximum => 125
|
||||
validates_length_of :android_min_version_available, :maximum => 125
|
||||
|
||||
def add_jour(user, notes, reference_user_id = 0, options = {})
|
||||
if options.count == 0
|
||||
self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
|
||||
else
|
||||
jfm = self.journals_for_messages.build(options)
|
||||
jfm.save
|
||||
jfm
|
||||
end
|
||||
end
|
||||
def set_commit(commit)
|
||||
self.update_attribute(:commit, commit)
|
||||
end
|
||||
|
||||
def editable_by? usr
|
||||
usr.admin? || self.user == usr
|
||||
end
|
||||
|
||||
def destroyable_by? usr
|
||||
self.user == usr || usr.admin?
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
class WebFooterCompany < ActiveRecord::Base
|
||||
attr_accessible :logo_size, :name, :url
|
||||
validates :name, presence: true, length: { maximum: 500 }
|
||||
validates :url, length: { maximum: 500 },
|
||||
format: { with: /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/,
|
||||
message: l(:is_not_url_error)
|
||||
}
|
||||
end
|
||||
class WebFooterCompany < ActiveRecord::Base
|
||||
attr_accessible :logo_size, :name, :url
|
||||
validates :name, presence: true, length: { maximum: 500 }
|
||||
validates :url, length: { maximum: 500 },
|
||||
format: { with: /(http|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:\/~\+#]*[\w\-\@?^=%&\/~\+#])?/,
|
||||
message: l(:is_not_url_error)
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
class WebFooterOranizer < ActiveRecord::Base
|
||||
attr_accessible :description, :name
|
||||
end
|
||||
class WebFooterOranizer < ActiveRecord::Base
|
||||
attr_accessible :description, :name
|
||||
end
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<div class="tabs">
|
||||
<ul>
|
||||
<li><%= link_to l(:label_project_first_page), {:action => 'first_page_made'}, class: "#{current_page?(first_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_course_first_page), {:action => 'course_page_made'}, class: "#{current_page?(course_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_contest_first_page), {:action => 'contest_page_made'}, class: "#{current_page?(contest_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_web_footer_page), {:action => 'web_footer_made'}, class: "#{current_page?(web_footer_made_path)? 'selected' : nil }" %></li>
|
||||
</ul>
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li><%= link_to l(:label_project_first_page), {:action => 'first_page_made'}, class: "#{current_page?(first_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_course_first_page), {:action => 'course_page_made'}, class: "#{current_page?(course_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_contest_first_page), {:action => 'contest_page_made'}, class: "#{current_page?(contest_page_made_path)? 'selected' : nil }" %></li>
|
||||
<li><%= link_to l(:label_web_footer_page), {:action => 'web_footer_made'}, class: "#{current_page?(web_footer_made_path)? 'selected' : nil }" %></li>
|
||||
</ul>
|
||||
</div>
|
|
@ -1,41 +1,41 @@
|
|||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'contest_page_made') do%>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
|
||||
<h4><%=l(:label_contest_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@contest_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @contest_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @contest_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='contest_title'> <%= l(:label_site_title) %>:</label>
|
||||
<%= text_field_tag 'contest_title', params[:label_site_title], :value => @contest_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='contest_description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<%= text_area_tag 'contest_description',@contest_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'contest_page_made') do%>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
|
||||
<h4><%=l(:label_contest_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@contest_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @contest_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @contest_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='contest_title'> <%= l(:label_site_title) %>:</label>
|
||||
<%= text_field_tag 'contest_title', params[:label_site_title], :value => @contest_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='contest_description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<%= text_area_tag 'contest_description',@contest_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -1,39 +1,39 @@
|
|||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'course_page_made') do %>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<h4><%=l(:label_course_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@course_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @course_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @course_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='course_title'> <%= l(:label_site_title) %>:</label>
|
||||
<%= text_field_tag 'course_title', params[:label_site_title], :value => @course_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='course_description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<%= text_area_tag 'course_description',@course_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'course_page_made') do %>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<h4><%=l(:label_course_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@course_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @course_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @course_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='course_title'> <%= l(:label_site_title) %>:</label>
|
||||
<%= text_field_tag 'course_title', params[:label_site_title], :value => @course_page.title,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='course_description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<%= text_area_tag 'course_description',@course_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -1,60 +1,60 @@
|
|||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'first_page_made') do %>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<h4><%=l(:label_project_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@first_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @first_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @first_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='title'> <%= l(:label_show_course) %>:</label>
|
||||
<select name="show_course" id="show_course" style="font-size:small;width:497px;margin-left:10px;display: inline">
|
||||
<option value="1" <%= "selected=selected" if @first_page.show_course == 1 %>><%= l(:general_text_yes) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.show_course == 2 %>><%= l(:general_text_no) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='title'> <%= l(:label_show_contest) %>:</label>
|
||||
<select name="show_contest" id="show_contest" style="font-size:small;width:497px;margin-left:10px;display: inline">
|
||||
<option value="1" <%= "selected=selected" if @first_page.show_contest == 1 %>><%= l(:general_text_yes) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.show_contest == 2 %>><%= l(:general_text_no) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='sort_type' style="vertical-align: top"> <%= l(:label_sort_type)%>:</label>
|
||||
<select name="sort_type" id="sort_type" style="font-size:small;width:497px;margin-left:80px;">
|
||||
<option value="1" <%= "selected=selected" if @first_page.sort_type == 1 %>><%= l(:label_sort_by_active) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.sort_type == 2 %>><%= l(:label_sort_by_influence) %></option>
|
||||
<option value="0" <%= "selected=selected" if @first_page.sort_type == 0 %>><%= l(:label_sort_by_time) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<!-- <#%= text_area_tag 'description',@first_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -->
|
||||
<%= text_area 'first_page', 'description', :value => @first_page.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %>
|
||||
<%= wikitoolbar_for 'first_page_description' %>
|
||||
</p>
|
||||
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'first_page_made') do %>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<h4><%=l(:label_project_first_page)%></h4>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='attachments_fields'> <%= l(:label_site_image) %>:</label>
|
||||
</p>
|
||||
<div style="margin-left: 82px;" id="avatar">
|
||||
<%= render :partial=>"avatar/avatar_form",:style => "display:inline",:locals=> {source:@first_page} %>
|
||||
</div>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_width' style="vertical-align: top"> <%= l(:label_image_width)%>:</label>
|
||||
<%= text_field_tag 'image_width', params[:label_image_width],:value => @first_page.image_width,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='image_height' style="vertical-align: top"> <%= l(:label_imgae_height)%>:</label>
|
||||
<%= text_field_tag 'image_height', params[:label_imgae_height], :value => @first_page.image_height,:size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='title'> <%= l(:label_show_course) %>:</label>
|
||||
<select name="show_course" id="show_course" style="font-size:small;width:497px;margin-left:10px;display: inline">
|
||||
<option value="1" <%= "selected=selected" if @first_page.show_course == 1 %>><%= l(:general_text_yes) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.show_course == 2 %>><%= l(:general_text_no) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='title'> <%= l(:label_show_contest) %>:</label>
|
||||
<select name="show_contest" id="show_contest" style="font-size:small;width:497px;margin-left:10px;display: inline">
|
||||
<option value="1" <%= "selected=selected" if @first_page.show_contest == 1 %>><%= l(:general_text_yes) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.show_contest == 2 %>><%= l(:general_text_no) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='sort_type' style="vertical-align: top"> <%= l(:label_sort_type)%>:</label>
|
||||
<select name="sort_type" id="sort_type" style="font-size:small;width:497px;margin-left:80px;">
|
||||
<option value="1" <%= "selected=selected" if @first_page.sort_type == 1 %>><%= l(:label_sort_by_active) %></option>
|
||||
<option value="2" <%= "selected=selected" if @first_page.sort_type == 2 %>><%= l(:label_sort_by_influence) %></option>
|
||||
<option value="0" <%= "selected=selected" if @first_page.sort_type == 0 %>><%= l(:label_sort_by_time) %></option>
|
||||
</select>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='description' style="vertical-align: top"> <%= l(:label_site_description)%>:</label>
|
||||
<!-- <#%= text_area_tag 'description',@first_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -->
|
||||
<%= text_area 'first_page', 'description', :value => @first_page.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %>
|
||||
<%= wikitoolbar_for 'first_page_description' %>
|
||||
</p>
|
||||
|
||||
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -1,69 +1,69 @@
|
|||
<% if User.current.admin? %>
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
|
||||
</div>
|
||||
|
||||
<h3><%= l(:label_user_plural)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'search') do %>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<%= l(:label_filter_plural) %>
|
||||
</legend>
|
||||
<label for='status'><%= l(:field_status) %>:</label>
|
||||
<%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
|
||||
|
||||
<% if @groups.present? %>
|
||||
<label for='group_id'><%= l(:label_group) %>:</label>
|
||||
<%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %>
|
||||
<% end %>
|
||||
|
||||
<label for='name'><%= l(:label_user) %>:</label>
|
||||
<%= text_field_tag 'name', params[:name], :size => 30 %>
|
||||
<%= submit_tag l(:label_search), :class => "small", :name => nil %><!--Modified by young-->
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="list" style="width: 100%;table-layout: fixed;">
|
||||
<thead>
|
||||
<tr >
|
||||
<%= sort_header_tag('login', :caption => l(:field_login)) %>
|
||||
<%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
|
||||
<%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
|
||||
<%= sort_header_tag('mail', :caption => l(:field_mail)) %>
|
||||
|
||||
<%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
|
||||
<%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
|
||||
<%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
|
||||
<th style="width: 100px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for user in @users -%>
|
||||
<tr class="<%= user.css_classes %> <%= cycle("odd", "even") %>">
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="username" title='<%=user.login%>'> <%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="firstname" align="center" title='<%=user.firstname%>'><%= h(user.firstname) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="lastname" align="center" title='<%=user.lastname%>'><%= h(user.lastname) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="email" align="center" title='<%=user.mail%>'><%= mail_to(h(user.mail)) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" align="center" align="center"><%= checked_image user.admin? %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="created_on" align="center" title='<%=format_time(user.created_on)%>'><%= format_time(user.created_on) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="last_login_on" align="center" title='<%= format_time(user.last_login_on)%>'><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
|
||||
<td class="buttons"> <%= change_status_link(user) %>
|
||||
<%= delete_link user_path(user, :back_url => admin_users_path(params)) unless User.current == user %> </td>
|
||||
</tr>
|
||||
<% end -%>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<%= pagination_links_full @user_pages, @user_count %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% html_title(l(:label_user_plural)) -%>
|
||||
<%else %>
|
||||
|
||||
<% end%>
|
||||
<% if User.current.admin? %>
|
||||
<div class="contextual">
|
||||
<%= link_to l(:label_user_new), new_user_path, :class => 'icon icon-add' %>
|
||||
</div>
|
||||
|
||||
<h3><%= l(:label_user_plural)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'search') do %>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<%= l(:label_filter_plural) %>
|
||||
</legend>
|
||||
<label for='status'><%= l(:field_status) %>:</label>
|
||||
<%= select_tag 'status', users_status_options_for_select(@status), :class => "small", :onchange => "this.form.submit(); return false;" %>
|
||||
|
||||
<% if @groups.present? %>
|
||||
<label for='group_id'><%= l(:label_group) %>:</label>
|
||||
<%= select_tag 'group_id', content_tag('option') + options_from_collection_for_select(@groups, :id, :name, params[:group_id].to_i), :onchange => "this.form.submit(); return false;" %>
|
||||
<% end %>
|
||||
|
||||
<label for='name'><%= l(:label_user) %>:</label>
|
||||
<%= text_field_tag 'name', params[:name], :size => 30 %>
|
||||
<%= submit_tag l(:label_search), :class => "small", :name => nil %><!--Modified by young-->
|
||||
</fieldset>
|
||||
<% end %>
|
||||
|
||||
|
||||
<div class="autoscroll">
|
||||
<table class="list" style="width: 100%;table-layout: fixed;">
|
||||
<thead>
|
||||
<tr >
|
||||
<%= sort_header_tag('login', :caption => l(:field_login)) %>
|
||||
<%= sort_header_tag('firstname', :caption => l(:field_firstname)) %>
|
||||
<%= sort_header_tag('lastname', :caption => l(:field_lastname)) %>
|
||||
<%= sort_header_tag('mail', :caption => l(:field_mail)) %>
|
||||
|
||||
<%= sort_header_tag('admin', :caption => l(:field_admin), :default_order => 'desc') %>
|
||||
<%= sort_header_tag('created_on', :caption => l(:field_created_on), :default_order => 'desc') %>
|
||||
<%= sort_header_tag('last_login_on', :caption => l(:field_last_login_on), :default_order => 'desc') %>
|
||||
<th style="width: 100px;"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% for user in @users -%>
|
||||
<tr class="<%= user.css_classes %> <%= cycle("odd", "even") %>">
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="username" title='<%=user.login%>'> <%= avatar(user, :size => "14") %><%= link_to h(user.login), edit_user_path(user) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="firstname" align="center" title='<%=user.firstname%>'><%= h(user.firstname) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="lastname" align="center" title='<%=user.lastname%>'><%= h(user.lastname) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="email" align="center" title='<%=user.mail%>'><%= mail_to(h(user.mail)) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" align="center" align="center"><%= checked_image user.admin? %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="created_on" align="center" title='<%=format_time(user.created_on)%>'><%= format_time(user.created_on) %></td>
|
||||
<td style="white-space: nowrap;overflow: hidden;text-overflow: ellipsis;" class="last_login_on" align="center" title='<%= format_time(user.last_login_on)%>'><%= format_time(user.last_login_on) unless user.last_login_on.nil? %></td>
|
||||
<td class="buttons"> <%= change_status_link(user) %>
|
||||
<%= delete_link user_path(user, :back_url => admin_users_path(params)) unless User.current == user %> </td>
|
||||
</tr>
|
||||
<% end -%>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<%= pagination_links_full @user_pages, @user_count %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% html_title(l(:label_user_plural)) -%>
|
||||
<%else %>
|
||||
|
||||
<% end%>
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'web_footer_made') do%>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<div style="float:right"><%= link_to l(:label_cooperation_compnay), web_footer_companies_path %></div>
|
||||
<h4><%=l(:label_web_footer_page)%></h4>
|
||||
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='organizer_name'> <%= l(:label_organizer_name) %>:</label>
|
||||
<%= text_field_tag 'organizer_name', params[:label_organizer_name], :value => @organizer.nil? ? "":@organizer.name,:size => 30,:style => "font-size:small;width:497px;margin-left:80px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_footer_oranizer_description' style="vertical-align: top"> <%= l(:label_web_footer_description)%>:</label>
|
||||
<!-- <#%= text_area_tag 'description',@first_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -->
|
||||
<%= text_area 'web_footer_oranizer', 'description', :value => @organizer.nil? ? "" : @organizer.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %>
|
||||
<%= wikitoolbar_for 'web_footer_oranizer_description' %>
|
||||
</p>
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
<h3><%=l(:label_first_page_made)%></h3>
|
||||
|
||||
<%= form_tag(:controller => 'admin', :action => 'web_footer_made') do%>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_title'><%= l(:label_web_title) %>:</label>
|
||||
<%= text_field_tag 'web_title', params[:wbe_title],:value => @first_page.web_title, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %>
|
||||
</p>
|
||||
<%= render 'tab_partial' %>
|
||||
<div style="float:right"><%= link_to l(:label_cooperation_compnay), web_footer_companies_path %></div>
|
||||
<h4><%=l(:label_web_footer_page)%></h4>
|
||||
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='organizer_name'> <%= l(:label_organizer_name) %>:</label>
|
||||
<%= text_field_tag 'organizer_name', params[:label_organizer_name], :value => @organizer.nil? ? "":@organizer.name,:size => 30,:style => "font-size:small;width:497px;margin-left:80px;" %>
|
||||
</p>
|
||||
<p style="margin-left:60px;padding-right: 20px;">
|
||||
<label for='web_footer_oranizer_description' style="vertical-align: top"> <%= l(:label_web_footer_description)%>:</label>
|
||||
<!-- <#%= text_area_tag 'description',@first_page.description,:rows => 8, :size => 30,:style => "font-size:small;width:490px;margin-left:10px;" %> -->
|
||||
<%= text_area 'web_footer_oranizer', 'description', :value => @organizer.nil? ? "" : @organizer.description,:cols => 80, :rows => 15, :class => 'wiki-edit' %>
|
||||
<%= wikitoolbar_for 'web_footer_oranizer_description' %>
|
||||
</p>
|
||||
<%= submit_tag l(:button_save), :class => "small", :name => nil %>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -1,17 +1,17 @@
|
|||
<!-- #wang -->
|
||||
<% for attachment in attachments %>
|
||||
<% if attachments.count > 1 && attachment != attachments.first%>
|
||||
<br/>
|
||||
<% end %>
|
||||
<%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
|
||||
<% if attachment.is_text? %>
|
||||
<%= link_to image_tag('magnifier.png'),
|
||||
:controller => 'attachments', :action => 'show',
|
||||
:id => attachment, :filename => attachment.filename %>
|
||||
<% end %>
|
||||
<span title="<%= attachment.description%>">
|
||||
<%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %>
|
||||
</span>
|
||||
<span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
|
||||
|
||||
<% end -%>
|
||||
<!-- #wang -->
|
||||
<% for attachment in attachments %>
|
||||
<% if attachments.count > 1 && attachment != attachments.first%>
|
||||
<br/>
|
||||
<% end %>
|
||||
<%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
|
||||
<% if attachment.is_text? %>
|
||||
<%= link_to image_tag('magnifier.png'),
|
||||
:controller => 'attachments', :action => 'show',
|
||||
:id => attachment, :filename => attachment.filename %>
|
||||
<% end %>
|
||||
<span title="<%= attachment.description%>">
|
||||
<%= h(truncate(" - #{attachment.description}", length: 20, omission: '...')) unless attachment.description.blank? %>
|
||||
</span>
|
||||
<span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
|
||||
|
||||
<% end -%>
|
||||
|
|
|
@ -1,63 +1,63 @@
|
|||
<span id="attachments_fields" xmlns="http://www.w3.org/1999/html">
|
||||
<% if defined?(container) && container && container.saved_attachments %>
|
||||
<% if isReply %>
|
||||
<% container.saved_attachments.each_with_index do |attachment, i| %>
|
||||
<span id="attachments_p<%= i %>" class="attachment">
|
||||
<%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%>
|
||||
<%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") +
|
||||
link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
|
||||
<%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %>
|
||||
<span class="ispublic-label"><%= l(:field_is_public)%>:</span>
|
||||
<%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%>
|
||||
<%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% container.attachments.each_with_index do |attachment, i| %>
|
||||
<span id="attachments_p<%= i %>" class="attachment">
|
||||
<%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%>
|
||||
<%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") +
|
||||
link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
|
||||
<%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %>
|
||||
<span class="ispublic-label"><%= l(:field_is_public)%>:</span>
|
||||
<%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%>
|
||||
<%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
<script type='text/javascript'>
|
||||
// function CompatibleSend()
|
||||
// {
|
||||
// var obj=document.getElementById("_file");
|
||||
// var file= $(obj).clone();
|
||||
// file.click();
|
||||
// }
|
||||
</script>
|
||||
<span class="add_attachment">
|
||||
<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %>
|
||||
<!--%= link_to image_tag(),"javascript:void(0)", :onclick => "_file.click()"%-->
|
||||
<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()" %>
|
||||
<%= file_field_tag 'attachments[dummy][file]',
|
||||
:id => '_file',
|
||||
:class => 'file_selector',
|
||||
:multiple => true,
|
||||
:onchange => 'addInputFiles(this);',
|
||||
:style => 'display:none',
|
||||
:data => {
|
||||
:max_file_size => Setting.attachment_max_size.to_i.kilobytes,
|
||||
:max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
|
||||
:max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
|
||||
:upload_path => uploads_path(:format => 'js'),
|
||||
:description_placeholder => l(:label_optional_description)
|
||||
} %>
|
||||
<span id="upload_file_count"><%= l(:label_no_file_uploaded)%></span>
|
||||
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
|
||||
</span>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag 'attachments' %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<span id="attachments_fields" xmlns="http://www.w3.org/1999/html">
|
||||
<% if defined?(container) && container && container.saved_attachments %>
|
||||
<% if isReply %>
|
||||
<% container.saved_attachments.each_with_index do |attachment, i| %>
|
||||
<span id="attachments_p<%= i %>" class="attachment">
|
||||
<%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%>
|
||||
<%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") +
|
||||
link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
|
||||
<%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %>
|
||||
<span class="ispublic-label"><%= l(:field_is_public)%>:</span>
|
||||
<%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%>
|
||||
<%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% container.attachments.each_with_index do |attachment, i| %>
|
||||
<span id="attachments_p<%= i %>" class="attachment">
|
||||
<%= text_field_tag("attachments[p#{i}][filename]", attachment.filename, :class => 'filename readonly', :readonly=>'readonly')%>
|
||||
<%= text_field_tag("attachments[p#{i}][description]", attachment.description, :maxlength => 255, :placeholder => l(:label_optional_description), :class => 'description', :style=>"display: inline-block;") +
|
||||
link_to(' '.html_safe, attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :method => 'delete', :remote => true, :class => 'remove-upload') %>
|
||||
<%#= render :partial => 'tags/tag', :locals => {:obj => attachment, :object_flag => "6"} %>
|
||||
<span class="ispublic-label"><%= l(:field_is_public)%>:</span>
|
||||
<%= check_box_tag("attachments[p#{i}][is_public_checkbox]", attachment.is_public,attachment.is_public == 1 ? true : false, :class => 'is_public')%>
|
||||
<%= hidden_field_tag "attachments[p#{i}][token]", "#{attachment.token}" %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
<script type='text/javascript'>
|
||||
// function CompatibleSend()
|
||||
// {
|
||||
// var obj=document.getElementById("_file");
|
||||
// var file= $(obj).clone();
|
||||
// file.click();
|
||||
// }
|
||||
</script>
|
||||
<span class="add_attachment">
|
||||
<%#= button_tag "浏览", :type=>"button", :onclick=>"CompatibleSend();" %>
|
||||
<!--%= link_to image_tag(),"javascript:void(0)", :onclick => "_file.click()"%-->
|
||||
<%= button_tag "浏览", :type=>"button", :onclick=>"_file.click()" %>
|
||||
<%= file_field_tag 'attachments[dummy][file]',
|
||||
:id => '_file',
|
||||
:class => 'file_selector',
|
||||
:multiple => true,
|
||||
:onchange => 'addInputFiles(this);',
|
||||
:style => 'display:none',
|
||||
:data => {
|
||||
:max_file_size => Setting.attachment_max_size.to_i.kilobytes,
|
||||
:max_file_size_message => l(:error_attachment_too_big, :max_size => number_to_human_size(Setting.attachment_max_size.to_i.kilobytes)),
|
||||
:max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
|
||||
:upload_path => uploads_path(:format => 'js'),
|
||||
:description_placeholder => l(:label_optional_description)
|
||||
} %>
|
||||
<span id="upload_file_count"><%= l(:label_no_file_uploaded)%></span>
|
||||
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
|
||||
</span>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag 'attachments' %>
|
||||
<% end %>
|
||||
|
||||
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
<div class="attachments">
|
||||
<% for attachment in attachments %>
|
||||
<p style="width: 100%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
|
||||
<span title="<%= attachment.filename%>">
|
||||
<%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
|
||||
</span>
|
||||
<% if attachment.is_text? %>
|
||||
<%= link_to image_tag('magnifier.png'),
|
||||
:controller => 'attachments',
|
||||
:action => 'show',
|
||||
:id => attachment,
|
||||
:filename => attachment.filename%>
|
||||
<% end %>
|
||||
<span title="<%= attachment.description%>">
|
||||
<%= h(truncate(" - #{attachment.description}", length: 15, omission: '...')) unless attachment.description.blank? %>
|
||||
</span>
|
||||
<span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
|
||||
<% if options[:deletable] %>
|
||||
<% if attachment.container_type == 'HomeworkAttach' %>
|
||||
<%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'delete_homework', :id => attachment.id},
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:method => :delete,
|
||||
:class => 'delete',
|
||||
:title => l(:button_delete) %>
|
||||
<% else %>
|
||||
<%= link_to image_tag('delete.png'), attachment_path(attachment),
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:method => :delete,
|
||||
:class => 'delete',
|
||||
#:remote => true,
|
||||
#:id => "attachments_" + attachment.id.to_s,
|
||||
:title => l(:button_delete) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if options[:author] %>
|
||||
<span class="author" title="attachment.author">
|
||||
<%= link_to h(truncate(attachment.author.name, length: 10, omission: '...')),user_path(attachment.author) %>,
|
||||
<%= format_time(attachment.created_on) %>
|
||||
</span>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if defined?(thumbnails) && thumbnails %>
|
||||
<% images = attachments.select(&:thumbnailable?) %>
|
||||
<% if images.any? %>
|
||||
<div class="thumbnails">
|
||||
<% images.each do |attachment| %>
|
||||
<div><%= thumbnail_tag(attachment) %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="attachments">
|
||||
<% for attachment in attachments %>
|
||||
<p style="width: 100%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;">
|
||||
<span title="<%= attachment.filename%>">
|
||||
<%= link_to_short_attachment attachment, :class => 'icon icon-attachment', :download => true -%>
|
||||
</span>
|
||||
<% if attachment.is_text? %>
|
||||
<%= link_to image_tag('magnifier.png'),
|
||||
:controller => 'attachments',
|
||||
:action => 'show',
|
||||
:id => attachment,
|
||||
:filename => attachment.filename%>
|
||||
<% end %>
|
||||
<span title="<%= attachment.description%>">
|
||||
<%= h(truncate(" - #{attachment.description}", length: 15, omission: '...')) unless attachment.description.blank? %>
|
||||
</span>
|
||||
<span class="size">(<%= number_to_human_size attachment.filesize %>)</span>
|
||||
<% if options[:deletable] %>
|
||||
<% if attachment.container_type == 'HomeworkAttach' %>
|
||||
<%= link_to image_tag('delete.png'), {:controller => 'attachments', :action => 'delete_homework', :id => attachment.id},
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:method => :delete,
|
||||
:class => 'delete',
|
||||
:title => l(:button_delete) %>
|
||||
<% else %>
|
||||
<%= link_to image_tag('delete.png'), attachment_path(attachment),
|
||||
:data => {:confirm => l(:text_are_you_sure)},
|
||||
:method => :delete,
|
||||
:class => 'delete',
|
||||
#:remote => true,
|
||||
#:id => "attachments_" + attachment.id.to_s,
|
||||
:title => l(:button_delete) %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if options[:author] %>
|
||||
<span class="author" title="attachment.author">
|
||||
<%= link_to h(truncate(attachment.author.name, length: 10, omission: '...')),user_path(attachment.author) %>,
|
||||
<%= format_time(attachment.created_on) %>
|
||||
</span>
|
||||
<% end %>
|
||||
</p>
|
||||
<% end %>
|
||||
<% if defined?(thumbnails) && thumbnails %>
|
||||
<% images = attachments.select(&:thumbnailable?) %>
|
||||
<% if images.any? %>
|
||||
<div class="thumbnails">
|
||||
<% images.each do |attachment| %>
|
||||
<div><%= thumbnail_tag(attachment) %></div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
<!-- fq -->
|
||||
<% else %>
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'bid' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;"><%= l(:label_bids_form_new_description) %></p>
|
||||
<p><%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :placeholder => "#{l(:label_requirement_name)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;"><%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_requirement_description)}" %></p>
|
||||
<p><%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_new_money) %>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
|
||||
</p>
|
||||
<p><%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;", :placeholder => "#{l(:label_deadline)}", :readonly => true %><%= calendar_for('bid_deadline')%>
|
||||
</p>
|
||||
|
||||
<!-- fq -->
|
||||
<% else %>
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'bid' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;"><%= l(:label_bids_form_new_description) %></p>
|
||||
<p><%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :placeholder => "#{l(:label_requirement_name)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;"><%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_requirement_description)}" %></p>
|
||||
<p><%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_new_money) %>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
|
||||
</p>
|
||||
<p><%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;", :placeholder => "#{l(:label_deadline)}", :readonly => true %><%= calendar_for('bid_deadline')%>
|
||||
</p>
|
||||
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
<!-- huang -->
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'bid' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;"><%= l(:label_bids_form_contest_new_description) %></p>
|
||||
<p><%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_name)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;"><%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_description)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;"><%= f.text_field :password, :size => 60, :style => "width:488px;margin-left: 10px;" %></p>
|
||||
|
||||
<p>
|
||||
<%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_reward_what) %>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
</p>
|
||||
<!-- <em class="info" style="margin-left:95px;"><%= l(:text_contest_reward) %></em> -->
|
||||
<p><%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :placeholder => "#{l(:label_deadline)}" %><%= calendar_for('bid_deadline')%></p>
|
||||
<!-- huang -->
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'bid' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;"><%= l(:label_bids_form_contest_new_description) %></p>
|
||||
<p><%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_name)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;"><%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;margin-left:10px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT, :placeholder => "#{l(:label_contest_description)}" %></p>
|
||||
|
||||
<p style="margin-left:-10px;"><%= f.text_field :password, :size => 60, :style => "width:488px;margin-left: 10px;" %></p>
|
||||
|
||||
<p>
|
||||
<%= f.text_field :budget, :required => true, :size => 60, :style => "width:350px;", :placeholder => l(:label_bids_reward_what) %>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
</p>
|
||||
<!-- <em class="info" style="margin-left:95px;"><%= l(:text_contest_reward) %></em> -->
|
||||
<p><%= f.text_field :deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :placeholder => "#{l(:label_deadline)}" %><%= calendar_for('bid_deadline')%></p>
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<% tip1 = (@bid.reward_type == 3) ? l(:label_student_response) : l(:label_user_response) %>
|
||||
<p class="font_lighter" style="font-size: 15px; padding-left: 12px; "><%=tip1%></p>
|
||||
|
||||
<div id='leave-message'>
|
||||
<%= render :partial => 'new', :locals => {:bid => @bid, :sta => @state} %>
|
||||
</div>
|
||||
<% label = ''
|
||||
case @bid.reward_type
|
||||
when 1
|
||||
label = l(:label_respond_requirement)
|
||||
when 2
|
||||
label = l(:label_contest_requirement)
|
||||
when 3
|
||||
label = l(:label_question_requirement)
|
||||
else
|
||||
end
|
||||
%>
|
||||
|
||||
|
||||
<% if journals.size >0 %>
|
||||
<ul class="message-for-user">
|
||||
<% for journal in journals%>
|
||||
<li id='word_li_<%= journal.id.to_s %>' class="outer-message-for-user">
|
||||
<span class="portrait"><%= image_tag(url_to_avatar(journal.user), :class => "avatar") %></span>
|
||||
<span class="body">
|
||||
<span class="user"><%= link_to journal.user, user_path(journal.user)%></span>
|
||||
<span class="font_lighter"><%= label %></span>
|
||||
<div> <%= textilizable journal.notes%> </div>
|
||||
<span class="font_lighter">
|
||||
<%= l(:label_bids_published) %>
|
||||
<%= time_tag(journal.created_on).html_safe %>
|
||||
<%= l(:label_bids_published_ago) %>
|
||||
</span>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<span>
|
||||
<% if reply_allow %>
|
||||
<%= link_to(l(:button_quote), {:controller => 'bids', :action => 'new', :id => bid, :journal_id => journal},
|
||||
:remote => true,:method => 'post', :title => l(:button_quote))%>
|
||||
<%= link_to l(:label_bid_respond_quote),'',
|
||||
{:focus => 'project_respond', :onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user.name}: '); $('##{ids} textarea') ;return false;"}
|
||||
%>
|
||||
<% end %>
|
||||
<% if @user==User.current|| User.current.admin? %>
|
||||
<%= link_to(l(:label_bid_respond_delete),
|
||||
{:controller => 'words', :action => 'destroy', :object_id => journal, :user_id => @user},
|
||||
:remote => true, :confirm => l(:text_are_you_sure), :method => 'delete',
|
||||
:class => "delete", :title => l(:button_delete)) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
<div style="clear: both;"></div>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<% if reply_allow %>
|
||||
<div id='<%= ids %>' class="respond-form">
|
||||
<%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="clear: both;"></div>
|
||||
<div>
|
||||
<%= render :partial => "words/journal_reply", :locals => {:journal => journal } %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<% tip1 = (@bid.reward_type == 3) ? l(:label_student_response) : l(:label_user_response) %>
|
||||
<p class="font_lighter" style="font-size: 15px; padding-left: 12px; "><%=tip1%></p>
|
||||
|
||||
<div id='leave-message'>
|
||||
<%= render :partial => 'new', :locals => {:bid => @bid, :sta => @state} %>
|
||||
</div>
|
||||
<% label = ''
|
||||
case @bid.reward_type
|
||||
when 1
|
||||
label = l(:label_respond_requirement)
|
||||
when 2
|
||||
label = l(:label_contest_requirement)
|
||||
when 3
|
||||
label = l(:label_question_requirement)
|
||||
else
|
||||
end
|
||||
%>
|
||||
|
||||
|
||||
<% if journals.size >0 %>
|
||||
<ul class="message-for-user">
|
||||
<% for journal in journals%>
|
||||
<li id='word_li_<%= journal.id.to_s %>' class="outer-message-for-user">
|
||||
<span class="portrait"><%= image_tag(url_to_avatar(journal.user), :class => "avatar") %></span>
|
||||
<span class="body">
|
||||
<span class="user"><%= link_to journal.user, user_path(journal.user)%></span>
|
||||
<span class="font_lighter"><%= label %></span>
|
||||
<div> <%= textilizable journal.notes%> </div>
|
||||
<span class="font_lighter">
|
||||
<%= l(:label_bids_published) %>
|
||||
<%= time_tag(journal.created_on).html_safe %>
|
||||
<%= l(:label_bids_published_ago) %>
|
||||
</span>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<span>
|
||||
<% if reply_allow %>
|
||||
<%= link_to(l(:button_quote), {:controller => 'bids', :action => 'new', :id => bid, :journal_id => journal},
|
||||
:remote => true,:method => 'post', :title => l(:button_quote))%>
|
||||
<%= link_to l(:label_bid_respond_quote),'',
|
||||
{:focus => 'project_respond', :onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user.name}: '); $('##{ids} textarea') ;return false;"}
|
||||
%>
|
||||
<% end %>
|
||||
<% if @user==User.current|| User.current.admin? %>
|
||||
<%= link_to(l(:label_bid_respond_delete),
|
||||
{:controller => 'words', :action => 'destroy', :object_id => journal, :user_id => @user},
|
||||
:remote => true, :confirm => l(:text_are_you_sure), :method => 'delete',
|
||||
:class => "delete", :title => l(:button_delete)) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
<div style="clear: both;"></div>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<% if reply_allow %>
|
||||
<div id='<%= ids %>' class="respond-form">
|
||||
<%= render :partial => 'words/new_respond', :locals => {:journal => journal, :m_reply_id => journal} %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="clear: both;"></div>
|
||||
<div>
|
||||
<%= render :partial => "words/journal_reply", :locals => {:journal => journal } %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
|
|
@ -1,56 +1,56 @@
|
|||
<!-- fq -->
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
|
||||
<%= error_messages_for 'bid' %>
|
||||
<p>
|
||||
<%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :onblur => "regexName();" %>
|
||||
</p>
|
||||
<p>
|
||||
<span id="bid_name_span"></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :onchange => "regexDeadLine();") %>
|
||||
<%= calendar_for('bid_deadline')%>
|
||||
<span id="bid_deadline_span">
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.select :is_evaluation, is_evaluation_option %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.select :proportion, proportion_option %>
|
||||
</p>
|
||||
<p>
|
||||
<%= hidden_field_tag 'course_id', @course.id %>
|
||||
</p>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<%= l(:label_attachment_plural) %>
|
||||
</legend>
|
||||
<p>
|
||||
<%= render :partial => 'attachments/form', :locals => {:container => @bid} %>
|
||||
</p>
|
||||
<!-- fq -->
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
|
||||
<%= error_messages_for 'bid' %>
|
||||
<p>
|
||||
<%= f.text_field :name, :required => true, :size => 60, :style => "width:490px;", :maxlength => Bid::NAME_LENGTH_LIMIT, :onblur => "regexName();" %>
|
||||
</p>
|
||||
<p>
|
||||
<span id="bid_name_span"></span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= f.text_area :description, :rows => 8, :class => 'wiki-edit', :style => "font-size:small;width:490px;", :maxlength => Bid::DESCRIPTION_LENGTH_LIMIT %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.text_field(:deadline, :required => true, :size => 60, :style => "width:150px;", :readonly => true, :onchange => "regexDeadLine();") %>
|
||||
<%= calendar_for('bid_deadline')%>
|
||||
<span id="bid_deadline_span">
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.select :is_evaluation, is_evaluation_option %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.select :proportion, proportion_option %>
|
||||
</p>
|
||||
<p>
|
||||
<%= hidden_field_tag 'course_id', @course.id %>
|
||||
</p>
|
||||
<fieldset>
|
||||
<legend>
|
||||
<%= l(:label_attachment_plural) %>
|
||||
</legend>
|
||||
<p>
|
||||
<%= render :partial => 'attachments/form', :locals => {:container => @bid} %>
|
||||
</p>
|
||||
</fieldset>
|
|
@ -1,82 +1,82 @@
|
|||
<!-- fq -->
|
||||
|
||||
<style>
|
||||
input[type="submit"].bid_btn {
|
||||
vertical-align: middle;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("../images/button/bg106.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
textarea:focus {
|
||||
border: #d5dee9 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function clearInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == content) {
|
||||
$('#' + id).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == '') {
|
||||
$('#' + id).val(content);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%= form_tag({:controller => 'bids',
|
||||
:action => 'new_bid',
|
||||
:remote => true,
|
||||
:method => :post,
|
||||
:id => 'new-bid-form'}) do %>
|
||||
|
||||
<table border="0" width="600px" style="border-left: 1px solid #acaeb1; border-right: 1px solid #acaeb1;
|
||||
border-top: 1px solid #acaeb1; border-bottom: 1px solid #acaeb1; margin-top: 30px; margin-left: 30px;">
|
||||
<tr>
|
||||
<td colspan="2"><%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6,
|
||||
:onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="22%"><%= select_tag 'bid_reward_type', "<option value = '0'>#{l(:label_choose_reward)}</option><option value = '1'>#{l(:label_money)}</option><option value = '2'>#{l(:label_reward_1)}</option><option value = '3'>#{l(:label_bids_credit)}</option>".html_safe, :class => 'noline' %></td>
|
||||
<td><%= text_field_tag 'bid_budget', "#{l(:label_requirement_bargain_money)}", :class => 'noline', :required => true,
|
||||
:onfocus => "clearInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')", :onblur => "showInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')" %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :required => true,
|
||||
:onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :readonly => true, :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%>
|
||||
<%= calendar_for('bid_deadline')%></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table id="bidding_table" border="0" width="600" style="margin-top: 10px; margin-left: 30px;">
|
||||
|
||||
<tr>
|
||||
<td align="right"> <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- fq -->
|
||||
|
||||
<style>
|
||||
input[type="submit"].bid_btn {
|
||||
vertical-align: middle;
|
||||
width: 80px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("../images/button/bg106.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
textarea:focus {
|
||||
border: #d5dee9 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function clearInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == content) {
|
||||
$('#' + id).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == '') {
|
||||
$('#' + id).val(content);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%= form_tag({:controller => 'bids',
|
||||
:action => 'new_bid',
|
||||
:remote => true,
|
||||
:method => :post,
|
||||
:id => 'new-bid-form'}) do %>
|
||||
|
||||
<table border="0" width="600px" style="border-left: 1px solid #acaeb1; border-right: 1px solid #acaeb1;
|
||||
border-top: 1px solid #acaeb1; border-bottom: 1px solid #acaeb1; margin-top: 30px; margin-left: 30px;">
|
||||
<tr>
|
||||
<td colspan="2"><%= text_field_tag 'bid_title', "#{l(:label_requirement_name)}", :class => 'noline', :required => true, :onfocus => "clearInfo('bid_title', '#{l(:label_requirement_name)}')", :onblur => "showInfo('bid_title', '#{l(:label_requirement_name)}')"%></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><%= text_area_tag 'bid_description', "#{l(:label_requirement_description)}", :class => 'noline', :required => true, :style => "resize: none;", :rows => 6,
|
||||
:onfocus => "clearInfo('bid_description', '#{l(:label_requirement_description)}')", :onblur => "showInfo('bid_description', '#{l(:label_requirement_description)}')" %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="22%"><%= select_tag 'bid_reward_type', "<option value = '0'>#{l(:label_choose_reward)}</option><option value = '1'>#{l(:label_money)}</option><option value = '2'>#{l(:label_reward_1)}</option><option value = '3'>#{l(:label_bids_credit)}</option>".html_safe, :class => 'noline' %></td>
|
||||
<td><%= text_field_tag 'bid_budget', "#{l(:label_requirement_bargain_money)}", :class => 'noline', :required => true,
|
||||
:onfocus => "clearInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')", :onblur => "showInfo('bid_budget', '#{l(:label_requirement_bargain_money)}')" %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><div class="tableline"></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><%= text_field_tag 'bid_deadline', "#{l(:label_deadline)}", :class => 'noline', :required => true,
|
||||
:onfocus => "clearInfo('bid_deadline', '#{l(:label_deadline)}')", :readonly => true, :onblur => "showInfo('bid_deadline', '#{l(:label_deadline)}')"%>
|
||||
<%= calendar_for('bid_deadline')%></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table id="bidding_table" border="0" width="600" style="margin-top: 10px; margin-left: 30px;">
|
||||
|
||||
<tr>
|
||||
<td align="right"> <%= submit_tag l(:button_new_bid), :name => nil , :class => "bid_btn", :onmouseout => "this.style.backgroundPosition = 'left top'", :onmouseover => "this.style.backgroundPosition = 'left -31px'"%> </td>
|
||||
</tr>
|
||||
</table>
|
||||
<%end%>
|
|
@ -1,60 +1,60 @@
|
|||
<script type="text/javascript">
|
||||
function regexName()
|
||||
{
|
||||
var name = $("#bid_name").val();
|
||||
|
||||
if(name=="")
|
||||
{
|
||||
$("#bid_name_span").text("名称不能为空");
|
||||
$("#bid_name_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#bid_name_span").text("填写正确");
|
||||
$("#bid_name_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function regexDeadLine()
|
||||
{
|
||||
var deadline = $("#bid_deadline").val();
|
||||
var regex = /^\d{4}-\d{2}-\d{2}$/;
|
||||
if(deadline=="")
|
||||
{
|
||||
$("#bid_deadline_span").text("截止日期不能为空");
|
||||
$("#bid_deadline_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
else if(regex.test(deadline))
|
||||
{
|
||||
$("#bid_deadline_span").text("填写正确");
|
||||
$("#bid_deadline_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#bid_deadline_span").text("截止日期格式错误");
|
||||
$("#bid_deadline_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function submitHomework(id)
|
||||
{
|
||||
if(regexDeadLine()&®exName())
|
||||
{
|
||||
$("#edit_bid_" + id).submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<h3><%= l(:label_edit_homework) %></h3>
|
||||
|
||||
<%= labelled_form_for @bid do |f| %>
|
||||
<div class="box tabular">
|
||||
<%#= render :partial => 'homework_form', :locals => { :f => f } %>
|
||||
<%= render :partial => 'homework_form', :locals => { :f => f } %>
|
||||
<input type="button" onclick="submitHomework(<%= @bid.id%>);" value="<%= l(:button_create)%>" class="enterprise">
|
||||
<% end %>
|
||||
<script type="text/javascript">
|
||||
function regexName()
|
||||
{
|
||||
var name = $("#bid_name").val();
|
||||
|
||||
if(name=="")
|
||||
{
|
||||
$("#bid_name_span").text("名称不能为空");
|
||||
$("#bid_name_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#bid_name_span").text("填写正确");
|
||||
$("#bid_name_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function regexDeadLine()
|
||||
{
|
||||
var deadline = $("#bid_deadline").val();
|
||||
var regex = /^\d{4}-\d{2}-\d{2}$/;
|
||||
if(deadline=="")
|
||||
{
|
||||
$("#bid_deadline_span").text("截止日期不能为空");
|
||||
$("#bid_deadline_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
else if(regex.test(deadline))
|
||||
{
|
||||
$("#bid_deadline_span").text("填写正确");
|
||||
$("#bid_deadline_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#bid_deadline_span").text("截止日期格式错误");
|
||||
$("#bid_deadline_span").css('color','#ff0000');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function submitHomework(id)
|
||||
{
|
||||
if(regexDeadLine()&®exName())
|
||||
{
|
||||
$("#edit_bid_" + id).submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<h3><%= l(:label_edit_homework) %></h3>
|
||||
|
||||
<%= labelled_form_for @bid do |f| %>
|
||||
<div class="box tabular">
|
||||
<%#= render :partial => 'homework_form', :locals => { :f => f } %>
|
||||
<%= render :partial => 'homework_form', :locals => { :f => f } %>
|
||||
<input type="button" onclick="submitHomework(<%= @bid.id%>);" value="<%= l(:button_create)%>" class="enterprise">
|
||||
<% end %>
|
||||
</div>
|
|
@ -1,36 +1,36 @@
|
|||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="portrait"><%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%></span>
|
||||
<span class="body" style="word-break: break-all;word-wrap: break-word;">
|
||||
<h3><%= link_to(@bid.author.lastname+@bid.author.firstname, user_path(@bid.author))%>:<%= link_to(@bid.name,respond_path(@bid)) %></h3>
|
||||
<% if @bid.reward_type.nil? or @bid.reward_type == 1%>
|
||||
<p>
|
||||
<strong><%= l(:label_bids_reward_method) %><span class="bonus"><%= l(:label_call_bonus) %> <%= l(:label_RMB_sign) %><%= @bid.budget %></span></strong>
|
||||
</p>
|
||||
<% elsif @bid.reward_type == 2%>
|
||||
<p>
|
||||
<strong><%= l(:label_bids_reward_method) %><span class="bonus"><%= @bid.budget%></span></strong>
|
||||
</p>
|
||||
<% else %>
|
||||
<% end %>
|
||||
<div class="bid_description">
|
||||
<%= textilizable(@bid, :description) %>
|
||||
<% if @bid.attachments.any?%>
|
||||
<% options = {:author => true,:deletable => (@bid.author.id == User.current.id || User.current.admin? ? true : false)} %>
|
||||
<%= render :partial => 'attachments/links', :locals => {:attachments => @bid.attachments, :options => options} %>
|
||||
<% end %>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
|
||||
<div id="history">
|
||||
<%= render :partial => 'history', :locals => { :bid => @bid, :journals => @jour, :state => false} %>
|
||||
</div>
|
||||
|
||||
<div class="pagination" style="float:left;">
|
||||
<ul>
|
||||
<%= pagination_links_full @feedback_pages %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="portrait"><%= image_tag(url_to_avatar(@bid.author), :class => "avatar")%></span>
|
||||
<span class="body" style="word-break: break-all;word-wrap: break-word;">
|
||||
<h3><%= link_to(@bid.author.lastname+@bid.author.firstname, user_path(@bid.author))%>:<%= link_to(@bid.name,respond_path(@bid)) %></h3>
|
||||
<% if @bid.reward_type.nil? or @bid.reward_type == 1%>
|
||||
<p>
|
||||
<strong><%= l(:label_bids_reward_method) %><span class="bonus"><%= l(:label_call_bonus) %> <%= l(:label_RMB_sign) %><%= @bid.budget %></span></strong>
|
||||
</p>
|
||||
<% elsif @bid.reward_type == 2%>
|
||||
<p>
|
||||
<strong><%= l(:label_bids_reward_method) %><span class="bonus"><%= @bid.budget%></span></strong>
|
||||
</p>
|
||||
<% else %>
|
||||
<% end %>
|
||||
<div class="bid_description">
|
||||
<%= textilizable(@bid, :description) %>
|
||||
<% if @bid.attachments.any?%>
|
||||
<% options = {:author => true,:deletable => (@bid.author.id == User.current.id || User.current.admin? ? true : false)} %>
|
||||
<%= render :partial => 'attachments/links', :locals => {:attachments => @bid.attachments, :options => options} %>
|
||||
<% end %>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
|
||||
<div id="history">
|
||||
<%= render :partial => 'history', :locals => { :bid => @bid, :journals => @jour, :state => false} %>
|
||||
</div>
|
||||
|
||||
<div class="pagination" style="float:left;">
|
||||
<ul>
|
||||
<%= pagination_links_full @feedback_pages %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
<h3><%= @query.new_record? ? l(:label_calendar) : h(@query.name) %></h3>
|
||||
|
||||
<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project},
|
||||
:method => :get, :id => 'query_form') do %>
|
||||
<%= hidden_field_tag 'set_filter', '1' %>
|
||||
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
|
||||
<legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
|
||||
<div style="<%= @query.new_record? ? "" : "display: none;" %>">
|
||||
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<p style="float:right;">
|
||||
<%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %>
|
||||
</p>
|
||||
<p class="buttons">
|
||||
<%= label_tag('month', l(:label_month)) %>
|
||||
<%= select_month(@month, :prefix => "month", :discard_type => true) %>
|
||||
<%= label_tag('year', l(:label_year)) %>
|
||||
<%= select_year(@year, :prefix => "year", :discard_type => true) %>
|
||||
|
||||
<%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %>
|
||||
<%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= error_messages_for 'query' %>
|
||||
<% if @query.valid? %>
|
||||
<%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %>
|
||||
<p class="legend cal">
|
||||
<span class="starting"><%= l(:text_tip_issue_begin_day) %></span>
|
||||
<span class="ending"><%= l(:text_tip_issue_end_day) %></span>
|
||||
<span class="starting ending"><%= l(:text_tip_issue_begin_end_day) %></span>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= render :partial => 'issues/sidebar' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_calendar)) -%>
|
||||
<h3><%= @query.new_record? ? l(:label_calendar) : h(@query.name) %></h3>
|
||||
|
||||
<%= form_tag({:controller => 'calendars', :action => 'show', :project_id => @project},
|
||||
:method => :get, :id => 'query_form') do %>
|
||||
<%= hidden_field_tag 'set_filter', '1' %>
|
||||
<fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
|
||||
<legend onclick="toggleFieldset(this);"><%= l(:label_filter_plural) %></legend>
|
||||
<div style="<%= @query.new_record? ? "" : "display: none;" %>">
|
||||
<%= render :partial => 'queries/filters', :locals => {:query => @query} %>
|
||||
</div>
|
||||
</fieldset>
|
||||
<p style="float:right;">
|
||||
<%= link_to_previous_month(@year, @month) %> | <%= link_to_next_month(@year, @month) %>
|
||||
</p>
|
||||
<p class="buttons">
|
||||
<%= label_tag('month', l(:label_month)) %>
|
||||
<%= select_month(@month, :prefix => "month", :discard_type => true) %>
|
||||
<%= label_tag('year', l(:label_year)) %>
|
||||
<%= select_year(@year, :prefix => "year", :discard_type => true) %>
|
||||
|
||||
<%= link_to_function l(:button_apply), '$("#query_form").submit()', :class => 'icon icon-checked' %>
|
||||
<%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 }, :class => 'icon icon-reload' %>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<%= error_messages_for 'query' %>
|
||||
<% if @query.valid? %>
|
||||
<%= render :partial => 'common/calendar', :locals => {:calendar => @calendar} %>
|
||||
<p class="legend cal">
|
||||
<span class="starting"><%= l(:text_tip_issue_begin_day) %></span>
|
||||
<span class="ending"><%= l(:text_tip_issue_end_day) %></span>
|
||||
<span class="starting ending"><%= l(:text_tip_issue_begin_end_day) %></span>
|
||||
</p>
|
||||
<% end %>
|
||||
|
||||
<% content_for :sidebar do %>
|
||||
<%= render :partial => 'issues/sidebar' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_calendar)) -%>
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>没有访问权限</title>
|
||||
<style>
|
||||
body{ font-size:12px; font-family:"微软雅黑","宋体"; line-height:1.9; background:#fff; font-style:normal;}
|
||||
div,html,img,ul,li,p,body,h1,h2,h3,h4,p,a,table,tr,td,fieldset,input,span{ margin:0; padding:0;}
|
||||
div,img,tr,td{ border:0;}
|
||||
table,tr,td{border:0 cellspacing:0; cellpadding:0;}
|
||||
ul,li{ list-style-type:none}
|
||||
.cl{ clear:both; overflow:hidden; }
|
||||
a{ text-decoration:none; }
|
||||
a:hover{ }
|
||||
|
||||
.error_content{ width:550px; height:200px; margin:0 auto; padding:10px 0;}
|
||||
.error_left{color:#15bccf; font-size:100px; font-weight:bold; font-style:oblique; width:200px; height:120px; padding-right:30px; float:left;}
|
||||
.error_right{ width:240px; height:120px; float:left;color:#15bccf; font-size: 17px; font-weight:bold; padding-left:30px; margin-top:40px; border-left:1px dashed #CCC; }
|
||||
.error_link{ margin-top:8px;}
|
||||
.error_link a{ display:block; width:80px; height:28px; font-size:14px; font-weight:bold; color:#fff; text-align:center; background:#15bccf; float:left; margin-right:10px;}
|
||||
.error_link a:hover{ background:#ff8417;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="error_content">
|
||||
<div class="error_left">403</div>
|
||||
<div class="error_right">
|
||||
<p>ERROR FORBIDDEN<br />
|
||||
没有访问权限!建议您</p>
|
||||
<div class="error_link">
|
||||
<!---<a href="http://forge.trustie.net/" target="_blank">返回首页</a>---->
|
||||
<a href="javascript:history.back()">后退一步</a>
|
||||
<a href="http://user.trustie.net/users/5/user_newfeedback">给我留言</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>没有访问权限</title>
|
||||
<style>
|
||||
body{ font-size:12px; font-family:"微软雅黑","宋体"; line-height:1.9; background:#fff; font-style:normal;}
|
||||
div,html,img,ul,li,p,body,h1,h2,h3,h4,p,a,table,tr,td,fieldset,input,span{ margin:0; padding:0;}
|
||||
div,img,tr,td{ border:0;}
|
||||
table,tr,td{border:0 cellspacing:0; cellpadding:0;}
|
||||
ul,li{ list-style-type:none}
|
||||
.cl{ clear:both; overflow:hidden; }
|
||||
a{ text-decoration:none; }
|
||||
a:hover{ }
|
||||
|
||||
.error_content{ width:550px; height:200px; margin:0 auto; padding:10px 0;}
|
||||
.error_left{color:#15bccf; font-size:100px; font-weight:bold; font-style:oblique; width:200px; height:120px; padding-right:30px; float:left;}
|
||||
.error_right{ width:240px; height:120px; float:left;color:#15bccf; font-size: 17px; font-weight:bold; padding-left:30px; margin-top:40px; border-left:1px dashed #CCC; }
|
||||
.error_link{ margin-top:8px;}
|
||||
.error_link a{ display:block; width:80px; height:28px; font-size:14px; font-weight:bold; color:#fff; text-align:center; background:#15bccf; float:left; margin-right:10px;}
|
||||
.error_link a:hover{ background:#ff8417;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="error_content">
|
||||
<div class="error_left">403</div>
|
||||
<div class="error_right">
|
||||
<p>ERROR FORBIDDEN<br />
|
||||
没有访问权限!建议您</p>
|
||||
<div class="error_link">
|
||||
<!---<a href="http://forge.trustie.net/" target="_blank">返回首页</a>---->
|
||||
<a href="javascript:history.back()">后退一步</a>
|
||||
<a href="http://user.trustie.net/users/5/user_newfeedback">给我留言</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>页面不见了</title>
|
||||
<style>
|
||||
body{ font-size:12px; font-family:"微软雅黑","宋体"; line-height:1.9; background:#fff;}
|
||||
div,html,img,ul,li,p,body,h1,h2,h3,h4,p,a,table,tr,td,fieldset,input,span{ margin:0; padding:0;}
|
||||
div,img,tr,td{ border:0;}
|
||||
table,tr,td{border:0 cellspacing:0; cellpadding:0;}
|
||||
ul,li{ list-style-type:none}
|
||||
.cl{ clear:both; overflow:hidden; }
|
||||
a{ text-decoration:none; }
|
||||
a:hover{ }
|
||||
|
||||
.error_content{ width:550px; height:200px; margin:0 auto; padding:10px 0;}
|
||||
.error_left{color:#15bccf; font-size:100px; font-weight:bold; font-style:oblique; width:200px; height:120px; padding-right:30px; float:left;}
|
||||
.error_right{ width:240px; height:120px; float:left;color:#15bccf; font-size: 18px; font-weight:bold; padding-left:30px; margin-top:40px; border-left:1px dashed #CCC; }
|
||||
.error_link{ margin-top:8px;}
|
||||
.error_link a{ display:block; width:80px; height:28px; font-size:14px; font-weight:bold; color:#fff; text-align:center; background:#15bccf; float:left; margin-right:10px;}
|
||||
.error_link a:hover{ background:#ff8417;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="error_content">
|
||||
<div class="error_left">404</div>
|
||||
<div class="error_right">
|
||||
<p><span style="font-size:24px;">ERROR PAGE</span><br />
|
||||
页面不见了!建议您</p>
|
||||
<div class="error_link">
|
||||
<!---<a href="http://forge.trustie.net/" target="_blank">返回首页</a>---->
|
||||
<a href="javascript:history.back()">后退一步</a>
|
||||
<a href="http://user.trustie.net/users/5/user_newfeedback">给我留言</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>页面不见了</title>
|
||||
<style>
|
||||
body{ font-size:12px; font-family:"微软雅黑","宋体"; line-height:1.9; background:#fff;}
|
||||
div,html,img,ul,li,p,body,h1,h2,h3,h4,p,a,table,tr,td,fieldset,input,span{ margin:0; padding:0;}
|
||||
div,img,tr,td{ border:0;}
|
||||
table,tr,td{border:0 cellspacing:0; cellpadding:0;}
|
||||
ul,li{ list-style-type:none}
|
||||
.cl{ clear:both; overflow:hidden; }
|
||||
a{ text-decoration:none; }
|
||||
a:hover{ }
|
||||
|
||||
.error_content{ width:550px; height:200px; margin:0 auto; padding:10px 0;}
|
||||
.error_left{color:#15bccf; font-size:100px; font-weight:bold; font-style:oblique; width:200px; height:120px; padding-right:30px; float:left;}
|
||||
.error_right{ width:240px; height:120px; float:left;color:#15bccf; font-size: 18px; font-weight:bold; padding-left:30px; margin-top:40px; border-left:1px dashed #CCC; }
|
||||
.error_link{ margin-top:8px;}
|
||||
.error_link a{ display:block; width:80px; height:28px; font-size:14px; font-weight:bold; color:#fff; text-align:center; background:#15bccf; float:left; margin-right:10px;}
|
||||
.error_link a:hover{ background:#ff8417;}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="error_content">
|
||||
<div class="error_left">404</div>
|
||||
<div class="error_right">
|
||||
<p><span style="font-size:24px;">ERROR PAGE</span><br />
|
||||
页面不见了!建议您</p>
|
||||
<div class="error_link">
|
||||
<!---<a href="http://forge.trustie.net/" target="_blank">返回首页</a>---->
|
||||
<a href="javascript:history.back()">后退一步</a>
|
||||
<a href="http://user.trustie.net/users/5/user_newfeedback">给我留言</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,38 +1,38 @@
|
|||
<table class="cal" style="width: 100%;table-layout: fixed;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" title="<%= l(:label_week) %>" class="week-number"></th>
|
||||
<% 7.times do |i| %>
|
||||
<th scope="col" style='white-space: nowrap;overflow: hidden;text-overflow: ellipsis;'><%= day_name( (calendar.first_wday+i)%7 ) %></th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<% day = calendar.startdt
|
||||
while day <= calendar.enddt %>
|
||||
<%= ("<td class='week-number' title='#{ l(:label_week) }'>#{(day+(11-day.cwday)%7).cweek}</td>".html_safe) if day.cwday == calendar.first_wday %>
|
||||
<td class="<%= day.month==calendar.month ? 'even' : 'odd' %><%= ' today' if Date.today == day %>"
|
||||
style="word-break: break-all;word-wrap: break-word;">
|
||||
<p class="day-num"><%= day.day %></p>
|
||||
<% calendar.events_on(day).each do |i| %>
|
||||
<% if i.is_a? Issue %>
|
||||
<div class="<%= i.css_classes %> <%= 'starting' if day == i.start_date %> <%= 'ending' if day == i.due_date %> tooltip">
|
||||
<%= h("#{i.project} -") unless @project && @project == i.project %>
|
||||
<%= link_to_issue i, :truncate => 30 %>
|
||||
<span class="tip"><%= render_issue_tooltip i %></span>
|
||||
</div>
|
||||
<% else %>
|
||||
<span class="icon icon-package">
|
||||
<%= h("#{i.project} -") unless @project && @project == i.project %>
|
||||
<%= link_to_version i%>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
<%= '</tr><tr>'.html_safe if day.cwday==calendar.last_wday and day!=calendar.enddt %>
|
||||
<% day = day + 1
|
||||
end %>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<table class="cal" style="width: 100%;table-layout: fixed;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" title="<%= l(:label_week) %>" class="week-number"></th>
|
||||
<% 7.times do |i| %>
|
||||
<th scope="col" style='white-space: nowrap;overflow: hidden;text-overflow: ellipsis;'><%= day_name( (calendar.first_wday+i)%7 ) %></th>
|
||||
<% end %>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<% day = calendar.startdt
|
||||
while day <= calendar.enddt %>
|
||||
<%= ("<td class='week-number' title='#{ l(:label_week) }'>#{(day+(11-day.cwday)%7).cweek}</td>".html_safe) if day.cwday == calendar.first_wday %>
|
||||
<td class="<%= day.month==calendar.month ? 'even' : 'odd' %><%= ' today' if Date.today == day %>"
|
||||
style="word-break: break-all;word-wrap: break-word;">
|
||||
<p class="day-num"><%= day.day %></p>
|
||||
<% calendar.events_on(day).each do |i| %>
|
||||
<% if i.is_a? Issue %>
|
||||
<div class="<%= i.css_classes %> <%= 'starting' if day == i.start_date %> <%= 'ending' if day == i.due_date %> tooltip">
|
||||
<%= h("#{i.project} -") unless @project && @project == i.project %>
|
||||
<%= link_to_issue i, :truncate => 30 %>
|
||||
<span class="tip"><%= render_issue_tooltip i %></span>
|
||||
</div>
|
||||
<% else %>
|
||||
<span class="icon icon-package">
|
||||
<%= h("#{i.project} -") unless @project && @project == i.project %>
|
||||
<%= link_to_version i%>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</td>
|
||||
<%= '</tr><tr>'.html_safe if day.cwday==calendar.last_wday and day!=calendar.enddt %>
|
||||
<% day = day + 1
|
||||
end %>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
|
||||
<%= textilizable @text, :attachments => @attachments, :object => @previewed %>
|
||||
</fieldset>
|
||||
<fieldset class="preview"><legend><%= l(:label_preview) %></legend>
|
||||
<%= textilizable @text, :attachments => @attachments, :object => @previewed %>
|
||||
</fieldset>
|
||||
|
|
|
@ -1,26 +1,80 @@
|
|||
<%= error_messages_for @contestnotifications %>
|
||||
<script type="text/javascript">
|
||||
function regexTitle()
|
||||
{
|
||||
var title = $.trim($("#contestnotification_title").val());
|
||||
if(title.length ==0)
|
||||
{
|
||||
$("#title_span").text("<%= l(:label_no_contest_news_title) %>");
|
||||
$("#title_span").css('color','#ff0000');
|
||||
$("#title_span").focus();
|
||||
return false;
|
||||
}
|
||||
else if(title.length <= 254)
|
||||
{
|
||||
$("#title_span").text("<%= l(:label_field_correct) %>");
|
||||
$("#title_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#title_span").text("<%= l(:label_contest_news_title_condition) %>");
|
||||
$("#title_span").css('color','#ff0000');
|
||||
$("#title_span").focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//验证描述:不能为空,不能多余5000个字符
|
||||
function regexDescription()
|
||||
{
|
||||
var description = $.trim($("#contestnotification_description").val());
|
||||
if(description.length ==0)
|
||||
{
|
||||
$("#description_span").text("<%= l(:label_no_contest_news_description) %>");
|
||||
$("#description_span").css('color','#ff0000');
|
||||
$("#description_span").focus();
|
||||
return false;
|
||||
}
|
||||
else if(description.length <= 5000)
|
||||
{
|
||||
$("#description_span").text("<%= l(:label_field_correct) %>");
|
||||
$("#description_span").css('color','#008000');
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#description_span").text("<%= l(:label_contest_news_condition) %>");
|
||||
$("#description_span").css('color','#ff0000');
|
||||
$("#description_span").focus();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<div class="add_frame_header" >
|
||||
<%= l(:bale_news_notice) %>
|
||||
</div>
|
||||
<div class="box tabular">
|
||||
<p>
|
||||
<%= f.text_field :title,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:maxlength => 60,
|
||||
:style => "width:488px;"
|
||||
%>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.text_area :description,
|
||||
:required => true,
|
||||
:cols => 60,
|
||||
:rows => 11,
|
||||
:class => 'wiki-edit',
|
||||
:style => "width:490px;"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= f.text_field :title,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:maxlength => 60,
|
||||
:style => "width:488px;",
|
||||
:onblur => "regexTitle();"
|
||||
%>
|
||||
</p>
|
||||
<span id="title_span" style="padding-left: 100px;"></span>
|
||||
<p>
|
||||
<%= f.text_area :description,
|
||||
:required => true,
|
||||
:cols => 60,
|
||||
:rows => 11,
|
||||
:class => 'wiki-edit',
|
||||
:style => "width:490px;",
|
||||
:onblur => "regexDescription();"
|
||||
%>
|
||||
</p>
|
||||
<span id="description_span" style="padding-left: 100px;"></span>
|
||||
</div>
|
||||
|
||||
<%= wikitoolbar_for 'news_description' %>
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
<h3><%=l(:label_edit_contest_notice)%></h3>
|
||||
|
||||
<%= labelled_form_for @contestnotification,
|
||||
:url => contest_contestnotification_path,
|
||||
:html => { :id => 'contestnotifications-form',
|
||||
:multipart => true,
|
||||
:method => :put } do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%#= preview_link preview_contestnotifications_path(id: @contestnotification),
|
||||
'contestnotifications-form'
|
||||
%>
|
||||
<% end %>
|
||||
<div id="preview" class="wiki"></div>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<h3><%=l(:label_edit_contest_notice)%></h3>
|
||||
|
||||
<%= labelled_form_for @contestnotification,
|
||||
:url => contest_contestnotification_path,
|
||||
:html => { :id => 'contestnotifications-form',
|
||||
:multipart => true,
|
||||
:method => :put } do |f| %>
|
||||
<%= render :partial => 'form', :locals => { :f => f } %>
|
||||
<%= submit_tag l(:button_save) %>
|
||||
<%#= preview_link preview_contestnotifications_path(id: @contestnotification),
|
||||
'contestnotifications-form'
|
||||
%>
|
||||
<% end %>
|
||||
<div id="preview" class="wiki"></div>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<% end %>
|
|
@ -1,3 +1,137 @@
|
|||
<<<<<<< HEAD
|
||||
<span style="font-size: 16px; border-bottom:1px solid #f0f0f0; margin-right: 15px;">
|
||||
<%= l(:label_notification) %>
|
||||
</span>
|
||||
<% if User.current.logged? && (User.current.admin? ||User.current == @contest.author) %>
|
||||
<%= link_to(l(:bale_news_notice),
|
||||
new_contest_contestnotification_path(@contest),
|
||||
:class => 'icon icon-add',
|
||||
:onclick => 'showAndScrollTo("add-contestnotifications", "contestnotifications_title"); return false;') %>
|
||||
<% end %>
|
||||
<% if @contest %>
|
||||
<div id="add-contestnotifications" class="add_frame" style="display:none;">
|
||||
<%= labelled_form_for @contestnotification, :url => contest_contestnotifications_path(@contest),
|
||||
:html => {:id => 'contestnotifications-form', :multipart => true} do |f| %>
|
||||
<%= render :partial => 'contestnotifications/form', :locals => {:f => f} %>
|
||||
<%= submit_tag l(:button_create), :class => 'whiteButton m3p10 h30', :name => nil %>
|
||||
<%#= preview_link preview_contestnotifications_path(:contest_id => @contest), 'contestnotifications-form', target='preview', {:class => 'whiteButton m3p10'} %>
|
||||
|
|
||||
<%= link_to l(:button_cancel), "#", :onclick => '$("#add-contestnotifications").hide(); return false;', :class => 'whiteButton m3p10' %>
|
||||
<% end if @contest %>
|
||||
<div id="preview" class="wiki"></div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div>
|
||||
|
||||
<div style="margin-left: 20px;">
|
||||
<span class="portrait">
|
||||
<%= image_tag(url_to_avatar(@contest.author), :class => "avatar")%>
|
||||
</span>
|
||||
<span class="body">
|
||||
<h3>
|
||||
<%= link_to(@contest.author.lastname+@contest.author.firstname,
|
||||
user_path(@contest.author))
|
||||
%>
|
||||
:<%= @contest.name %></h3>
|
||||
<p>
|
||||
<strong>
|
||||
<%= l(:label_bids_reward_method) %>
|
||||
<span class="bonus">
|
||||
<%= @contest.budget%>
|
||||
</span>
|
||||
</strong>
|
||||
</p>
|
||||
<div class="bid_description" style="width: 100%;word-break:break-all;word-wrap: break-word;">
|
||||
<%= @contest.description %>
|
||||
</div>
|
||||
<span id="praise_tread" style="float: right">
|
||||
<%= render :partial => "/praise_tread/praise_tread",
|
||||
:locals => {:obj => @contest,
|
||||
:show_flag => true,
|
||||
:user_id =>User.current.id,
|
||||
:horizontal => false}
|
||||
%>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
|
||||
<br><br>
|
||||
<% @contestnotificationss.each do |contestnotifications| %>
|
||||
<table class="content-text-list">
|
||||
<tr>
|
||||
<td colspan="2" valign="top" width="50"><%= link_to image_tag(url_to_avatar(contestnotifications.author), :class => "avatar"), user_path(contestnotifications.author) %></td>
|
||||
<td>
|
||||
<table width="580px" border="0">
|
||||
|
||||
<tr>
|
||||
<td colspan="2" valign="top">
|
||||
<strong><%= link_to_user(contestnotifications.author) if contestnotifications.respond_to?(:author) %></strong><span style="margin-left: 4px;" class="font_lighter">
|
||||
<%= l(:label_project_notice) %></span><span><%= link_to h(contestnotifications.title), contest_contestnotification_path(@contest, contestnotifications) %></span>
|
||||
<span style="float: right">
|
||||
<%= link_to l(:button_edit), edit_contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %>
|
||||
<%= delete_link contest_contestnotification_path(@contest, contestnotifications) if (User.current.admin? && User.current.logged? )||(User.current == @contest.author && User.current.logged?) %>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" width="580px">
|
||||
<span class="font_description"><%= textilizable(contestnotifications, :description) %></span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="left"><span class="font_lighter"> <%= l :label_update_time %>
|
||||
<%= format_time(contestnotifications.created_at) %></span></td>
|
||||
<td width="350" align="right" class="a"><%= link_to l(:label_check_comment), contest_contestnotification_path(@contest, contestnotifications) %><%#= "(#{l(:label_x_comments, :count => contestnotifications.notificationcomments_count)})" if contestnotifications.notificationcomments_count >= 0 %></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
</div>
|
||||
<!--end-->
|
||||
<div style="padding-right: 10px">
|
||||
<div class="pagination">
|
||||
<ul>
|
||||
<%= pagination_links_full @contestnotifications_pages %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% content_for :header_tags do %>
|
||||
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %>
|
||||
<%= stylesheet_link_tag 'scm' %>
|
||||
<% end %>
|
||||
|
||||
<% html_title(l(:label_contest_notification)) -%>
|
||||
</div>
|
||||
|
||||
<script type='text/javascript'>
|
||||
$(document).ready(function ($) {
|
||||
$('.content-text-list').each(function () {
|
||||
$(this).find('.delete_icon').hide();
|
||||
$(this).mouseenter(function (event) {
|
||||
$(this).find('.delete_icon').show();
|
||||
});
|
||||
$(this).mouseleave(function (event) {
|
||||
$(this).find('.delete_icon').hide();
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
=======
|
||||
<script type="text/javascript">
|
||||
function submitContestNews()
|
||||
{
|
||||
if(regexTitle() && regexDescription())
|
||||
{
|
||||
$("#contestnotifications-form").submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<span style="font-size: 16px; border-bottom:1px solid #f0f0f0; margin-right: 15px;">
|
||||
<%= l(:label_notification) %>
|
||||
</span>
|
||||
|
@ -12,10 +146,9 @@
|
|||
<%= labelled_form_for @contestnotification, :url => contest_contestnotifications_path(@contest),
|
||||
:html => {:id => 'contestnotifications-form', :multipart => true} do |f| %>
|
||||
<%= render :partial => 'contestnotifications/form', :locals => {:f => f} %>
|
||||
<%= submit_tag l(:button_create), :class => 'whiteButton m3p10 h30', :name => nil %>
|
||||
<%#= preview_link preview_contestnotifications_path(:contest_id => @contest), 'contestnotifications-form', target='preview', {:class => 'whiteButton m3p10'} %>
|
||||
<input type="button" onclick="submitContestNews();" class="enterprise" value="<%= l(:button_create)%>"/>
|
||||
|
|
||||
<%= link_to l(:button_cancel), "#", :onclick => '$("#add-contestnotifications").hide(); return false;', :class => 'whiteButton m3p10' %>
|
||||
<input type="button" onclick="$('#add-contestnotifications').hide(); return false;" class="enterprise" value="<%= l(:button_cancel)%>"/>
|
||||
<% end if @contest %>
|
||||
<div id="preview" class="wiki"></div>
|
||||
</div>
|
||||
|
@ -120,4 +253,5 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
>>>>>>> d2f4b38eb6fd68a67940b8ffe735d8f7437acde1
|
||||
<!--end-->
|
|
@ -1,11 +1,17 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
function submitContestNews()
|
||||
{
|
||||
if(regexTitle() && regexDescription())
|
||||
{
|
||||
$("#contestnotifications-form").submit();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<%= labelled_form_for @contestnotification,
|
||||
:url => contest_contestnotifications_path(@contest),
|
||||
:html => { :id => 'contestnotifications-form', :multipart => true } do |f| %>
|
||||
<%= render :partial => 'contestnotifications/form', :locals => { :f => f } %>
|
||||
<%= submit_tag l(:button_create), :class => "whiteButton m3p10 h30" %>
|
||||
<%= submit_tag l(:button_cancel), :class => "whiteButton m3p10 h30",:onclick => "cancel();" %>
|
||||
|
||||
|
||||
<input type="button" onclick="submitContestNews();" class="enterprise" value="<%= l(:button_create)%>"/>
|
||||
<%= link_to l(:button_cancel), contest_contestnotifications_path(@contest.id) %>
|
||||
<% end %>
|
||||
<div id="preview" class="wiki"></div>
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
<!-- huang -->
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'contest' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;">
|
||||
<%= l(:label_bids_form_contest_new_description) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.text_field :name,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:style => "width:490px;",
|
||||
:maxlength => Contest::NAME_LENGTH_LIMIT,
|
||||
:placeholder => "#{l(:label_contest_name)}"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;">
|
||||
<%= f.text_area :description,
|
||||
:rows => 5,
|
||||
:class => 'wiki-edit',
|
||||
:style => "font-size:small;width:490px;margin-left:10px;",
|
||||
:maxlength => Contest::DESCRIPTION_LENGTH_LIMIT,
|
||||
:placeholder => "#{l(:label_contest_description)}"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:-10px;">
|
||||
<%= f.text_field :password,
|
||||
:size => 60,
|
||||
:style => "width:488px;margin-left: 10px;"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= f.text_area :budget,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:rows => 4,
|
||||
:maxlength => Contest::DESCRIPTION_LENGTH_LIMIT,
|
||||
:style => "width:490px;",
|
||||
:placeholder => l(:label_bids_reward_what)
|
||||
%>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
</p>
|
||||
<!-- <em class="info" style="margin-left:95px;"><%#= l(:text_contest_reward) %></em> -->
|
||||
<p>
|
||||
<%= f.text_field :deadline,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:style => "width:150px;",
|
||||
:readonly => true,
|
||||
:placeholder => "#{l(:label_deadline)}"
|
||||
%>
|
||||
<%= calendar_for('contest_deadline')%>
|
||||
</p>
|
||||
<!-- huang -->
|
||||
<script type="text/javascript" language="javascript">
|
||||
function show(id, id_t, label_reward, label_money, label_credit, label_content) {
|
||||
var text = $('#' + id);
|
||||
var text_t = $('#' + id_t);
|
||||
if (text.val() == 0) {
|
||||
text_t.attr("placeholder", label_reward);
|
||||
}
|
||||
if (text.val() == 1) {
|
||||
text_t.attr("placeholder", label_money);
|
||||
}
|
||||
if (text.val() == 3) {
|
||||
text_t.attr("placeholder", label_credit);
|
||||
}
|
||||
if (text.val() == 2) {
|
||||
text_t.attr("placeholder", label_content);
|
||||
}
|
||||
return content;
|
||||
}
|
||||
</script>
|
||||
<%= error_messages_for 'contest' %>
|
||||
<!--[form:project]-->
|
||||
<p style="width:500px;">
|
||||
<%= l(:label_bids_form_contest_new_description) %>
|
||||
</p>
|
||||
<p>
|
||||
<%= f.text_field :name,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:style => "width:490px;",
|
||||
:maxlength => Contest::NAME_LENGTH_LIMIT,
|
||||
:placeholder => "#{l(:label_contest_name)}"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:-10px;padding-right: 20px;">
|
||||
<%= f.text_area :description,
|
||||
:rows => 5,
|
||||
:class => 'wiki-edit',
|
||||
:style => "font-size:small;width:490px;margin-left:10px;",
|
||||
:maxlength => Contest::DESCRIPTION_LENGTH_LIMIT,
|
||||
:placeholder => "#{l(:label_contest_description)}"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p style="margin-left:-10px;">
|
||||
<%= f.text_field :password,
|
||||
:size => 60,
|
||||
:style => "width:488px;margin-left: 10px;"
|
||||
%>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= f.text_area :budget,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:rows => 4,
|
||||
:maxlength => Contest::DESCRIPTION_LENGTH_LIMIT,
|
||||
:style => "width:490px;",
|
||||
:placeholder => l(:label_bids_reward_what)
|
||||
%>
|
||||
|
||||
<!-- 设置奖项设置的打开 关闭开关-->
|
||||
</p>
|
||||
<!-- <em class="info" style="margin-left:95px;"><%#= l(:text_contest_reward) %></em> -->
|
||||
<p>
|
||||
<%= f.text_field :deadline,
|
||||
:required => true,
|
||||
:size => 60,
|
||||
:style => "width:150px;",
|
||||
:readonly => true,
|
||||
:placeholder => "#{l(:label_deadline)}"
|
||||
%>
|
||||
<%= calendar_for('contest_deadline')%>
|
||||
</p>
|
||||
|
|
|
@ -1,79 +1,79 @@
|
|||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<% tip1 = l(:label_user_response) %>
|
||||
<p class="font_lighter" style="font-size: 15px; padding-left: 12px; "><%=tip1%></p>
|
||||
|
||||
<div id='leave-message'>
|
||||
<%= render :partial => 'new', :locals => {:contest => @contest, :sta => @state} %>
|
||||
</div>
|
||||
|
||||
|
||||
<% if journals.size >0 %>
|
||||
<ul class="message-for-user">
|
||||
<% for journal in journals%>
|
||||
<li id='word_li_<%= journal.id.to_s %>' class="outer-message-for-user">
|
||||
<span class="portrait">
|
||||
<%= image_tag(url_to_avatar(journal.user), :class => "avatar") %>
|
||||
</span>
|
||||
<span class="body">
|
||||
<span class="user">
|
||||
<%= link_to journal.user, user_path(journal.user)%>
|
||||
</span>
|
||||
<span class="font_lighter">
|
||||
<% label = l(:label_contest_requirement) %>
|
||||
</span>
|
||||
<div> <%= textilizable journal.notes%> </div>
|
||||
<span class="font_lighter">
|
||||
<%= l(:label_bids_published) %>
|
||||
<%= time_tag(journal.created_on).html_safe %>
|
||||
<%= l(:label_bids_published_ago) %>
|
||||
</span>
|
||||
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
|
||||
<span>
|
||||
<% if reply_allow %>
|
||||
<%= link_to(l(:button_quote),
|
||||
contests_path(:id => contest,
|
||||
:journal_id => journal),
|
||||
:remote => true,
|
||||
:method => 'post',
|
||||
:title => l(:button_quote))
|
||||
%>
|
||||
<%= link_to l(:label_bid_respond_quote),
|
||||
'',
|
||||
{:focus => 'project_respond',
|
||||
:onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user}: '); $('##{ids} textarea') ;return false;"
|
||||
}
|
||||
%>
|
||||
<% end %>
|
||||
|
||||
<% if @user==User.current|| User.current.admin? %>
|
||||
<%= link_to(l(:label_bid_respond_delete),
|
||||
|
||||
words_destroy_path(:user_id => @user, :object_id => journal),
|
||||
:remote => true,
|
||||
:confirm => l(:text_are_you_sure),
|
||||
:method => 'delete',
|
||||
:class => "delete",
|
||||
:title => l(:button_delete)) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<% if reply_allow %>
|
||||
<div id='<%= ids %>' class="respond-form">
|
||||
<%= render :partial => 'words/new_respond',
|
||||
:locals => {:journal => journal, :m_reply_id => journal}
|
||||
%>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="clear: both;"></div>
|
||||
<div>
|
||||
<%= render :partial => "words/journal_reply", :locals => {:journal => journal } %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
<% tip1 = l(:label_user_response) %>
|
||||
<p class="font_lighter" style="font-size: 15px; padding-left: 12px; "><%=tip1%></p>
|
||||
|
||||
<div id='leave-message'>
|
||||
<%= render :partial => 'new', :locals => {:contest => @contest, :sta => @state} %>
|
||||
</div>
|
||||
|
||||
|
||||
<% if journals.size >0 %>
|
||||
<ul class="message-for-user">
|
||||
<% for journal in journals%>
|
||||
<li id='word_li_<%= journal.id.to_s %>' class="outer-message-for-user">
|
||||
<span class="portrait">
|
||||
<%= image_tag(url_to_avatar(journal.user), :class => "avatar") %>
|
||||
</span>
|
||||
<span class="body">
|
||||
<span class="user">
|
||||
<%= link_to journal.user, user_path(journal.user)%>
|
||||
</span>
|
||||
<span class="font_lighter">
|
||||
<% label = l(:label_contest_requirement) %>
|
||||
</span>
|
||||
<div> <%= textilizable journal.notes%> </div>
|
||||
<span class="font_lighter">
|
||||
<%= l(:label_bids_published) %>
|
||||
<%= time_tag(journal.created_on).html_safe %>
|
||||
<%= l(:label_bids_published_ago) %>
|
||||
</span>
|
||||
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
|
||||
<span>
|
||||
<% if reply_allow %>
|
||||
<%= link_to(l(:button_quote),
|
||||
contests_path(:id => contest,
|
||||
:journal_id => journal),
|
||||
:remote => true,
|
||||
:method => 'post',
|
||||
:title => l(:button_quote))
|
||||
%>
|
||||
<%= link_to l(:label_bid_respond_quote),
|
||||
'',
|
||||
{:focus => 'project_respond',
|
||||
:onclick => "toggleAndSettingWordsVal($('##{ids}'), $('##{ids} textarea'), '#{l(:label_reply_plural)} #{journal.user}: '); $('##{ids} textarea') ;return false;"
|
||||
}
|
||||
%>
|
||||
<% end %>
|
||||
|
||||
<% if @user==User.current|| User.current.admin? %>
|
||||
<%= link_to(l(:label_bid_respond_delete),
|
||||
|
||||
words_destroy_path(:user_id => @user, :object_id => journal),
|
||||
:remote => true,
|
||||
:confirm => l(:text_are_you_sure),
|
||||
:method => 'delete',
|
||||
:class => "delete",
|
||||
:title => l(:button_delete)) %>
|
||||
<% end %>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div style="clear: both;"></div>
|
||||
<% ids = 'project_respond_form_'+ journal.id.to_s%>
|
||||
<% if reply_allow %>
|
||||
<div id='<%= ids %>' class="respond-form">
|
||||
<%= render :partial => 'words/new_respond',
|
||||
:locals => {:journal => journal, :m_reply_id => journal}
|
||||
%>
|
||||
</div>
|
||||
<% end %>
|
||||
<div style="clear: both;"></div>
|
||||
<div>
|
||||
<%= render :partial => "words/journal_reply", :locals => {:journal => journal } %>
|
||||
</div>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<!-- huang -->
|
||||
<h3><%=l(:label_newtype_contest)%></h3>
|
||||
|
||||
<%= labelled_form_for @contest,
|
||||
:url => {:controller => 'contests', :action => 'create_contest'},
|
||||
method: :post do |f| %>
|
||||
<div class="box tabular">
|
||||
<%= render :partial => 'form_contest', :locals => { :f => f } %>
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= javascript_tag "$('#bid_name').focus();" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<!-- huang -->
|
||||
<h3><%=l(:label_newtype_contest)%></h3>
|
||||
|
||||
<%= labelled_form_for @contest,
|
||||
:url => {:controller => 'contests', :action => 'create_contest'},
|
||||
method: :post do |f| %>
|
||||
<div class="box tabular">
|
||||
<%= render :partial => 'form_contest', :locals => { :f => f } %>
|
||||
<%= submit_tag l(:button_create) %>
|
||||
<%= javascript_tag "$('#bid_name').focus();" %>
|
||||
<% end %>
|
||||
</div>
|
||||
<% html_title(l(:label_newtype_contest)) -%>
|
|
@ -1,315 +1,315 @@
|
|||
<style>
|
||||
input[type="submit"].contest_btn {
|
||||
vertical-align: middle;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
/*margin-right: -4px;*/
|
||||
}
|
||||
|
||||
input[type="button"].contest_btn {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
border: #d5dee9 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function clearInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == content) {
|
||||
$('#' + id).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == '') {
|
||||
$('#' + id).val(content);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$("#put-bid-form").hide();
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$("#put-project-form").hide();
|
||||
}
|
||||
|
||||
function selectChange(obj)
|
||||
{
|
||||
if(obj.value=="其他")
|
||||
{
|
||||
//document.getElementById("a").style.display = ""
|
||||
$("#other_span").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#other_span").hide();
|
||||
$("#other_input").val("");
|
||||
//document.getElementById("a").style.display = "none"
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<%= render_flash_messages %>
|
||||
<!--参赛步骤-->
|
||||
<div style="padding-left: 23px; padding-bottom: 10px; color: grey; font-size: 12px">
|
||||
<div>
|
||||
<%= l(:label_wellmeaning_intimation_contentone) %>
|
||||
</div>
|
||||
<div style="margin-left: 59px; padding-top: 2px">
|
||||
1) <%= l(:label_wellmeaning_intimation_contenttwo) %>
|
||||
</div>
|
||||
<div style="margin-left: 59px; padding-top: 2px">
|
||||
2) <%= l(:label_wellmeaning_intimation_contentthree) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if User.current.logged? %>
|
||||
<div style="padding-bottom: 10px; line-height: 15px">
|
||||
<div style="padding-left: 82px; font-size: 14px">
|
||||
<span><strong><%= l(:label_attending_contest) %>:</strong></span>
|
||||
<span>
|
||||
<%= link_to l(:label_new_attendingcontest_work),
|
||||
"javascript:void(0);",
|
||||
onclick: "$('#put-project-form').slideToggle();"
|
||||
%>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="put-project-form" style=" padding-left: 83px; width: 88%">
|
||||
<%= render "new_softapplication" %>
|
||||
</div>
|
||||
<!-- end longjun -->
|
||||
<% else %>
|
||||
<div style="font-size: 14px;margin:10px;padding-left: 73px">
|
||||
<%= l(:label_user_login_attending_contest) %>
|
||||
<%= link_to l(:label_user_login_new), signin_path %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
|
||||
<!--参赛作品列表,通过判断,竞赛的id为2,3,6的显示参赛作品为提交的项目,否则显示参赛的应用-->
|
||||
|
||||
<% if @contest.id == 2 or @contest.id == 3 or @contest.id == 6 %>
|
||||
|
||||
<% @contesting_project.sort.reverse.each do |c_project| %>
|
||||
<% if c_project.project %>
|
||||
<div style="padding-left: 18px">
|
||||
<div style="font-size: 15px">
|
||||
<div>
|
||||
<div><strong><%= l(:label_contest_work) %>
|
||||
: <%= link_to(c_project.project.name, project_path(c_project.project), :target => '_blank') %> </strong>
|
||||
|
||||
<div style="float: right">
|
||||
<td style="color: #ec6300;" align="right" valign="0.1em" width="16%">
|
||||
<strong>
|
||||
<span id="reward_result_<%= c_project.id %>"> <!-- 调用js进行刷新 -->
|
||||
<% if get_prize(c_project).nil? or get_prize(c_project) == "" %>
|
||||
<% if @contest.deadline < Date.today %>
|
||||
<span style="color: red"><%= l(:label_noawards) %></span>
|
||||
<% else %>
|
||||
<span style="color: red"><%= l(:label_noawards_current) %></span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% case get_prize(c_project) %>
|
||||
<% when '-1' %>
|
||||
<%= image_tag("/images/bid/special_reward.png") %>
|
||||
<% when '0' %>
|
||||
<%= image_tag("/images/bid/first_reward.png") %>
|
||||
<% when '1' %>
|
||||
<%= image_tag("/images/bid/second_reward.png") %>
|
||||
<% when '2' %>
|
||||
<%= image_tag("/images/bid/third_reward.png") %>
|
||||
<% when '3' %>
|
||||
<%= image_tag("/images/bid/forth_reward.png") %>
|
||||
<% when '4' %>
|
||||
<%= image_tag("/images/bid/fifth_reward.png") %>
|
||||
<% when '5' %>
|
||||
<%= image_tag("/images/bid/qualified.png") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</strong>
|
||||
</td>
|
||||
|
||||
<!-- 评价显隐控制按钮-->
|
||||
<% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %>
|
||||
<td valign="top" align="right" width="10%">
|
||||
<span> <%= toggle_link l(:label_reward), c_project.id.to_s %></span>
|
||||
<!-- 评价应标项目的表单 -->
|
||||
<span style="display: none; vertical-align: top " id='<%= c_project.id %>'>
|
||||
<%= form_for "set_reward_project", :remote => true, :url => set_reward_project_contest_path do |f| %>
|
||||
<%= f.text_field :c_id, :style => "display:none", :value => c_project.id, :size => "0" %>
|
||||
<%= f.select :reward, "<option value = '-1'>#{l(:label_special_reward)}</option>
|
||||
<option value = '0'>#{l(:label_first_reward)}</option>
|
||||
<option value = '1'>#{l(:label_second_reward)}</option>
|
||||
<option value = '2'>#{l(:label_third_reward)}</option>
|
||||
<option value = '3'>#{l(:label_fourth_reward)}</option>
|
||||
<option value = '4'>#{l(:label_fifth_reward)}</option>
|
||||
<option value = '5'>#{l(:label_comfort_reward)}</option>".html_safe %>
|
||||
<%= f.submit :value => l(:button_submit), :class => "submit" %>
|
||||
<% end %>
|
||||
</span>
|
||||
</td>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</br>
|
||||
</div>
|
||||
<div style="padding-left: 68px">
|
||||
<tr>
|
||||
<td><%= l(:label_profile) %>:</td>
|
||||
<td>
|
||||
<%#= c_project.project.description.truncate(90, omission: '...') %>
|
||||
<%= c_project.project.description %>
|
||||
</td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
<div style="padding-left: 68px; padding-bottom: 8px">
|
||||
<span><strong><%= l(:label_attendingcontest_time) %>
|
||||
:</strong><%= format_time c_project.created_at %></span>
|
||||
<span style="padding-left: 240px"><strong><%= l(:label_attendingcontest_spoksman) %>
|
||||
<!-- modified by zjc 添加超链接 -->
|
||||
<% unless c_project.nil? || c_project.user.nil? %>
|
||||
:</strong><%= link_to c_project.user.name,user_path(c_project.user) %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% @contesting_softapplication.each do |c_softapplication| %>
|
||||
<% if c_softapplication.softapplication %>
|
||||
<div style="padding-left: 18px">
|
||||
<div style="font-size: 15px">
|
||||
<tr>
|
||||
<td><strong><%= l(:label_contest_work) %>: </strong></td>
|
||||
<td> <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication), :target => '_blank') %> </td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px; padding-top: 5px;word-break:break-all;word-wrap: break-word;">
|
||||
<tr>
|
||||
<td><strong><%= l(:label_profile) %>:</strong></td>
|
||||
<td>
|
||||
<%#= c_softapplication.softapplication.description.truncate(90, omission: '...') %>
|
||||
<%= c_softapplication.softapplication.description %>
|
||||
</td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px; pading-bottom: 8px">
|
||||
<span><strong><%= l(:label_attendingcontest_time) %>
|
||||
:</strong><%= format_time c_softapplication.created_at %></span>
|
||||
<span style="padding-left: 240px"><strong><%= l(:label_attendingcontest_spoksman) %>
|
||||
<!-- modified by zjc 添加超链接 -->
|
||||
<% unless c_softapplication.nil? || c_softapplication.softapplication.nil? || c_softapplication.softapplication.user.nil? %>
|
||||
:</strong><%= link_to c_softapplication.softapplication.user.name,user_path(c_softapplication.softapplication.user) %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!--获奖及教师评奖-->
|
||||
<div style="padding-left: 18px; padding-bottom: 5px">
|
||||
<% score = c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_f %>
|
||||
<span style="padding-left: 50px"><strong><%= l(:label_final_scores) %>
|
||||
:</strong></span><span style="color: red"><%= format("%.2f" , score) %>
|
||||
分</span>
|
||||
<span style="padding-left: 334px">
|
||||
<td>
|
||||
<strong>
|
||||
<span id="reward_result_<%= c_softapplication.id %>"> <!-- 调用js进行刷新 -->
|
||||
<% if get_prize(c_softapplication).nil? or get_prize(c_softapplication) == "" %>
|
||||
<% if @contest.deadline < Date.today %>
|
||||
<span style="color: red"><%= l(:label_noawards) %></span>
|
||||
<% else %>
|
||||
<span style="color: red"><%= l(:label_noawards_current) %></span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% case get_prize(c_softapplication) %>
|
||||
<% when '-1' %>
|
||||
<%= image_tag("/images/bid/special_reward.png") %>
|
||||
<% when '0' %>
|
||||
<%= image_tag("/images/bid/first_reward.png") %>
|
||||
<% when '1' %>
|
||||
<%= image_tag("/images/bid/second_reward.png") %>
|
||||
<% when '2' %>
|
||||
<%= image_tag("/images/bid/third_reward.png") %>
|
||||
<% when '3' %>
|
||||
<%= image_tag("/images/bid/forth_reward.png") %>
|
||||
<% when '4' %>
|
||||
<%= image_tag("/images/bid/fifth_reward.png") %>
|
||||
<% when '5' %>
|
||||
<%= image_tag("/images/bid/qualified.png") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</strong>
|
||||
</td>
|
||||
|
||||
<!-- 评价显隐控制按钮-->
|
||||
<% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %>
|
||||
<div style="text-align: right;width: 100%;">
|
||||
<span style="padding-right: 5px; padding-top: 1px"> <%= toggle_link '评奖', c_softapplication.id.to_s %></span>
|
||||
<!-- 评价应标项目的表单 -->
|
||||
<span style="display: none; vertical-align: top " id='<%= c_softapplication.id %>'>
|
||||
<%= form_for "set_reward_softapplication", :remote => true, :url => set_reward_softapplication_contest_path do |f| %>
|
||||
<%= f.text_field :c_id, :style => "display:none", :value => c_softapplication.id, :size => "0" %>
|
||||
<%= f.select :reward, "<option value = '-1'>#{l(:label_special_reward)}</option>
|
||||
<option value = '0'>#{l(:label_first_reward)}</option>
|
||||
<option value = '1'>#{l(:label_second_reward)}</option>
|
||||
<option value = '2'>#{l(:label_third_reward)}</option>
|
||||
<option value = '3'>#{l(:label_fourth_reward)}</option>
|
||||
<option value = '4'>#{l(:label_fifth_reward)}</option>
|
||||
<option value = '5'>#{l(:label_comfort_reward)}</option>".html_safe %>
|
||||
<%= f.submit :value => l(:button_submit), :class => "submit" %>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="pagination">
|
||||
<%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false %>
|
||||
</div>
|
||||
<% html_title(l(:label_contest_joincontest)) -%>
|
||||
<style>
|
||||
input[type="submit"].contest_btn {
|
||||
vertical-align: middle;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
/*margin-right: -4px;*/
|
||||
}
|
||||
|
||||
input[type="button"].contest_btn {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
|
||||
textarea:focus {
|
||||
border: #d5dee9 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function clearInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == content) {
|
||||
$('#' + id).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(id, content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == '') {
|
||||
$('#' + id).val(content);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$("#put-bid-form").hide();
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$("#put-project-form").hide();
|
||||
}
|
||||
|
||||
function selectChange(obj)
|
||||
{
|
||||
if(obj.value=="其他")
|
||||
{
|
||||
//document.getElementById("a").style.display = ""
|
||||
$("#other_span").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#other_span").hide();
|
||||
$("#other_input").val("");
|
||||
//document.getElementById("a").style.display = "none"
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<%= render_flash_messages %>
|
||||
<!--参赛步骤-->
|
||||
<div style="padding-left: 23px; padding-bottom: 10px; color: grey; font-size: 12px">
|
||||
<div>
|
||||
<%= l(:label_wellmeaning_intimation_contentone) %>
|
||||
</div>
|
||||
<div style="margin-left: 59px; padding-top: 2px">
|
||||
1) <%= l(:label_wellmeaning_intimation_contenttwo) %>
|
||||
</div>
|
||||
<div style="margin-left: 59px; padding-top: 2px">
|
||||
2) <%= l(:label_wellmeaning_intimation_contentthree) %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<% if User.current.logged? %>
|
||||
<div style="padding-bottom: 10px; line-height: 15px">
|
||||
<div style="padding-left: 82px; font-size: 14px">
|
||||
<span><strong><%= l(:label_attending_contest) %>:</strong></span>
|
||||
<span>
|
||||
<%= link_to l(:label_new_attendingcontest_work),
|
||||
"javascript:void(0);",
|
||||
onclick: "$('#put-project-form').slideToggle();"
|
||||
%>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="put-project-form" style=" padding-left: 83px; width: 88%">
|
||||
<%= render "new_softapplication" %>
|
||||
</div>
|
||||
|
||||
<% else %>
|
||||
<div style="font-size: 14px;margin:10px;padding-left: 73px">
|
||||
<%= l(:label_user_login_attending_contest) %>
|
||||
<%= link_to l(:label_user_login_new), signin_path %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
|
||||
<!--参赛作品列表,通过判断,竞赛的id为2,3,6的显示参赛作品为提交的项目,否则显示参赛的应用-->
|
||||
|
||||
<% if @contest.id == 2 or @contest.id == 3 or @contest.id == 6 %>
|
||||
|
||||
<% @contesting_project.sort.reverse.each do |c_project| %>
|
||||
<% if c_project.project %>
|
||||
<div style="padding-left: 18px">
|
||||
<div style="font-size: 15px">
|
||||
<div>
|
||||
<div><strong><%= l(:label_contest_work) %>
|
||||
: <%= link_to(c_project.project.name, project_path(c_project.project), :target => '_blank') %> </strong>
|
||||
|
||||
<div style="float: right">
|
||||
<td style="color: #ec6300;" align="right" valign="0.1em" width="16%">
|
||||
<strong>
|
||||
<span id="reward_result_<%= c_project.id %>"> <!-- 调用js进行刷新 -->
|
||||
<% if get_prize(c_project).nil? or get_prize(c_project) == "" %>
|
||||
<% if @contest.deadline < Date.today %>
|
||||
<span style="color: red"><%= l(:label_noawards) %></span>
|
||||
<% else %>
|
||||
<span style="color: red"><%= l(:label_noawards_current) %></span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% case get_prize(c_project) %>
|
||||
<% when '-1' %>
|
||||
<%= image_tag("/images/bid/special_reward.png") %>
|
||||
<% when '0' %>
|
||||
<%= image_tag("/images/bid/first_reward.png") %>
|
||||
<% when '1' %>
|
||||
<%= image_tag("/images/bid/second_reward.png") %>
|
||||
<% when '2' %>
|
||||
<%= image_tag("/images/bid/third_reward.png") %>
|
||||
<% when '3' %>
|
||||
<%= image_tag("/images/bid/forth_reward.png") %>
|
||||
<% when '4' %>
|
||||
<%= image_tag("/images/bid/fifth_reward.png") %>
|
||||
<% when '5' %>
|
||||
<%= image_tag("/images/bid/qualified.png") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</strong>
|
||||
</td>
|
||||
|
||||
<!-- 评价显隐控制按钮-->
|
||||
<% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %>
|
||||
<td valign="top" align="right" width="10%">
|
||||
<span> <%= toggle_link l(:label_reward), c_project.id.to_s %></span>
|
||||
<!-- 评价应标项目的表单 -->
|
||||
<span style="display: none; vertical-align: top " id='<%= c_project.id %>'>
|
||||
<%= form_for "set_reward_project", :remote => true, :url => set_reward_project_contest_path do |f| %>
|
||||
<%= f.text_field :c_id, :style => "display:none", :value => c_project.id, :size => "0" %>
|
||||
<%= f.select :reward, "<option value = '-1'>#{l(:label_special_reward)}</option>
|
||||
<option value = '0'>#{l(:label_first_reward)}</option>
|
||||
<option value = '1'>#{l(:label_second_reward)}</option>
|
||||
<option value = '2'>#{l(:label_third_reward)}</option>
|
||||
<option value = '3'>#{l(:label_fourth_reward)}</option>
|
||||
<option value = '4'>#{l(:label_fifth_reward)}</option>
|
||||
<option value = '5'>#{l(:label_comfort_reward)}</option>".html_safe %>
|
||||
<%= f.submit :value => l(:button_submit), :class => "submit" %>
|
||||
<% end %>
|
||||
</span>
|
||||
</td>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</br>
|
||||
</div>
|
||||
<div style="padding-left: 68px">
|
||||
<tr>
|
||||
<td><%= l(:label_profile) %>:</td>
|
||||
<td>
|
||||
<%#= c_project.project.description.truncate(90, omission: '...') %>
|
||||
<%= c_project.project.description %>
|
||||
</td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
<div style="padding-left: 68px; padding-bottom: 8px">
|
||||
<span><strong><%= l(:label_attendingcontest_time) %>
|
||||
:</strong><%= format_time c_project.created_at %></span>
|
||||
<span style="padding-left: 240px"><strong><%= l(:label_attendingcontest_spoksman) %>
|
||||
<!-- modified by zjc 添加超链接 -->
|
||||
<% unless c_project.nil? || c_project.user.nil? %>
|
||||
:</strong><%= link_to c_project.user.name,user_path(c_project.user) %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% @contesting_softapplication.each do |c_softapplication| %>
|
||||
<% if c_softapplication.softapplication %>
|
||||
<div style="padding-left: 18px">
|
||||
<div style="font-size: 15px">
|
||||
<tr>
|
||||
<td><strong><%= l(:label_contest_work) %>: </strong></td>
|
||||
<td> <%= link_to(c_softapplication.softapplication.name, softapplication_path(c_softapplication.softapplication), :target => '_blank') %> </td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px; padding-top: 5px;word-break:break-all;word-wrap: break-word;">
|
||||
<tr>
|
||||
<td><strong><%= l(:label_profile) %>:</strong></td>
|
||||
<td>
|
||||
<%#= c_softapplication.softapplication.description.truncate(90, omission: '...') %>
|
||||
<%= c_softapplication.softapplication.description %>
|
||||
</td>
|
||||
</tr>
|
||||
</br>
|
||||
</div>
|
||||
|
||||
<div style="padding-left: 68px; pading-bottom: 8px">
|
||||
<span><strong><%= l(:label_attendingcontest_time) %>
|
||||
:</strong><%= format_time c_softapplication.created_at %></span>
|
||||
<span style="padding-left: 240px"><strong><%= l(:label_attendingcontest_spoksman) %>
|
||||
<!-- modified by zjc 添加超链接 -->
|
||||
<% unless c_softapplication.nil? || c_softapplication.softapplication.nil? || c_softapplication.softapplication.user.nil? %>
|
||||
:</strong><%= link_to c_softapplication.softapplication.user.name,user_path(c_softapplication.softapplication.user) %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!--获奖及教师评奖-->
|
||||
<div style="padding-left: 18px; padding-bottom: 5px">
|
||||
<% score = c_softapplication.softapplication.average(:quality).try(:avg).try(:round, 2).to_f %>
|
||||
<span style="padding-left: 50px"><strong><%= l(:label_final_scores) %>
|
||||
:</strong></span><span style="color: red"><%= format("%.2f" , score) %>
|
||||
分</span>
|
||||
<span style="padding-left: 334px">
|
||||
<td>
|
||||
<strong>
|
||||
<span id="reward_result_<%= c_softapplication.id %>"> <!-- 调用js进行刷新 -->
|
||||
<% if get_prize(c_softapplication).nil? or get_prize(c_softapplication) == "" %>
|
||||
<% if @contest.deadline < Date.today %>
|
||||
<span style="color: red"><%= l(:label_noawards) %></span>
|
||||
<% else %>
|
||||
<span style="color: red"><%= l(:label_noawards_current) %></span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<% case get_prize(c_softapplication) %>
|
||||
<% when '-1' %>
|
||||
<%= image_tag("/images/bid/special_reward.png") %>
|
||||
<% when '0' %>
|
||||
<%= image_tag("/images/bid/first_reward.png") %>
|
||||
<% when '1' %>
|
||||
<%= image_tag("/images/bid/second_reward.png") %>
|
||||
<% when '2' %>
|
||||
<%= image_tag("/images/bid/third_reward.png") %>
|
||||
<% when '3' %>
|
||||
<%= image_tag("/images/bid/forth_reward.png") %>
|
||||
<% when '4' %>
|
||||
<%= image_tag("/images/bid/fifth_reward.png") %>
|
||||
<% when '5' %>
|
||||
<%= image_tag("/images/bid/qualified.png") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
</strong>
|
||||
</td>
|
||||
|
||||
<!-- 评价显隐控制按钮-->
|
||||
<% if ((User.current.id == @contest.author_id) && (@contest.deadline > Date.today))||User.current.admin %>
|
||||
<div style="text-align: right;width: 100%;">
|
||||
<span style="padding-right: 5px; padding-top: 1px"> <%= toggle_link '评奖', c_softapplication.id.to_s %></span>
|
||||
<!-- 评价应标项目的表单 -->
|
||||
<span style="display: none; vertical-align: top " id='<%= c_softapplication.id %>'>
|
||||
<%= form_for "set_reward_softapplication", :remote => true, :url => set_reward_softapplication_contest_path do |f| %>
|
||||
<%= f.text_field :c_id, :style => "display:none", :value => c_softapplication.id, :size => "0" %>
|
||||
<%= f.select :reward, "<option value = '-1'>#{l(:label_special_reward)}</option>
|
||||
<option value = '0'>#{l(:label_first_reward)}</option>
|
||||
<option value = '1'>#{l(:label_second_reward)}</option>
|
||||
<option value = '2'>#{l(:label_third_reward)}</option>
|
||||
<option value = '3'>#{l(:label_fourth_reward)}</option>
|
||||
<option value = '4'>#{l(:label_fifth_reward)}</option>
|
||||
<option value = '5'>#{l(:label_comfort_reward)}</option>".html_safe %>
|
||||
<%= f.submit :value => l(:button_submit), :class => "submit" %>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
<% end %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="underline-contests_three"></div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<div class="pagination">
|
||||
<%= pagination_links_full @obj_pages, @obj_count, :per_page_links => false %>
|
||||
</div>
|
||||
<% html_title(l(:label_contest_joincontest)) -%>
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
|
||||
|
||||
<div id="history">
|
||||
<%= render :partial => 'history',
|
||||
:locals => { :contest => @contest, :journals => @jour, :state => false}
|
||||
%>
|
||||
</div>
|
||||
|
||||
<div class="pagination" style="float:left;">
|
||||
<ul>
|
||||
<%= pagination_links_full @feedback_pages %>
|
||||
</ul>
|
||||
</div>
|
||||
<% html_title(l(:label_user_response)) -%>
|
||||
<% reply_allow = JournalsForMessage.create_by_user? User.current %>
|
||||
|
||||
|
||||
<div id="history">
|
||||
<%= render :partial => 'history',
|
||||
:locals => { :contest => @contest, :journals => @jour, :state => false}
|
||||
%>
|
||||
</div>
|
||||
|
||||
<div class="pagination" style="float:left;">
|
||||
<ul>
|
||||
<%= pagination_links_full @feedback_pages %>
|
||||
</ul>
|
||||
</div>
|
||||
<% html_title(l(:label_user_response)) -%>
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
<!--add by bai-->
|
||||
<h3>
|
||||
<%=link_to l(:label_x_join_in_contest, :count => @contest.join_in_contests.count)+"("+@contest.join_in_contests(@user.id).count.to_s+")",
|
||||
show_participator_contest_path
|
||||
%>
|
||||
</h3>
|
||||
<div class="inf_user_image">
|
||||
<% for temp in @contest.join_in_contests %>
|
||||
<% user = temp.user %>
|
||||
<ul class="list_watch">
|
||||
<li>
|
||||
<table width="660px" border="0" align="center">
|
||||
<tr>
|
||||
<!-- modified by bai 显示人名全称-->
|
||||
<td colspan="2" valign="top" width="50" >
|
||||
<%= link_to image_tag(url_to_avatar(user), :class => "avatar"),
|
||||
user_path(user),
|
||||
:title => "#{user.show_name}"
|
||||
%>
|
||||
</td>
|
||||
<td>
|
||||
<table width="580px" border="0">
|
||||
<tr>
|
||||
<td colspan="2" valign="top">
|
||||
<%= content_tag "div",
|
||||
link_to(user.show_name, user_path(user)),
|
||||
:class => "project_avatar_name" ,
|
||||
:title => "#{user.show_name}"
|
||||
%>
|
||||
<!-- added by bai 增加了学员的学号 -->
|
||||
<% if (im_watching_student_id? @contest) && user.user_extensions.identity.to_i.eql?(1) %>
|
||||
<%= l(:label_bidding_user_studentcode) %> :<%= user.user_extensions.student_id%>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<!-- modified by bai 区分课程与项目-->
|
||||
<td colspan="2" width="580px" >
|
||||
<p class="font_description">
|
||||
<% unless user.memberships.empty? %>
|
||||
<% cond = Project.visible_condition(User.current) + "AND projects.project_type <> 1" %>
|
||||
<% memberships = user.memberships.all(:conditions => cond) %>
|
||||
<%= l(:label_x_contribute_to, :count => memberships.count) %>
|
||||
<%
|
||||
links = Array.new
|
||||
memberships.collect{|member| links << link_to_project(member.project) }
|
||||
%>
|
||||
|
||||
<%= raw links.join(" , ") %>
|
||||
<% end %>
|
||||
</p>
|
||||
|
||||
<!-- added by bai -->
|
||||
<!--
|
||||
<p class="font_description">
|
||||
<% unless user.memberships.empty? %>
|
||||
<% cond = Project.visible_condition(User.current) + "AND projects.project_type = 1" %>
|
||||
<% memberships = user.memberships.all(:conditions => cond) %>
|
||||
<%= l(:label_x_course_contribute_to, :count => memberships.count) %>
|
||||
<% for member in memberships %>
|
||||
<%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</p>
|
||||
-->
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- end -->
|
||||
|
||||
<tr>
|
||||
<td width="200" align="right" class="font_lighter">
|
||||
<%= l(:label_user_joinin) %><%= format_date(user.created_on) %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</li>
|
||||
</ul>
|
||||
<% end %>
|
||||
</div>
|
|
@ -1,123 +0,0 @@
|
|||
|
||||
<style>
|
||||
input[type="submit"].contest_btn {
|
||||
vertical-align: middle;
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
/*margin-right: -4px;*/
|
||||
}
|
||||
input[type="button"].contest_btn {
|
||||
width: 60px;
|
||||
height: 30px;
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
color: rgb(0, 0, 0);
|
||||
background: url("/images/button/bg103.jpg") no-repeat scroll left top transparent;
|
||||
padding: 0px 0px 4px 0px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(148, 148, 148);
|
||||
box-shadow: none;
|
||||
text-shadow: none;
|
||||
margin-top: -10px;
|
||||
margin-right: -2px;
|
||||
}
|
||||
textarea:focus {
|
||||
border: #d5dee9 1px solid;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
function clearInfo(id,content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == content) {
|
||||
$('#' + id).val('');
|
||||
}
|
||||
}
|
||||
|
||||
function showInfo(id,content) {
|
||||
var text = $('#' + id);
|
||||
if (text.val() == '') {
|
||||
$('#' + id).val(content);
|
||||
}
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
$("#put-bid-form").hide();
|
||||
}
|
||||
</script>
|
||||
|
||||
<% if User.current.logged? %>
|
||||
<!--我要竞标弹出框-->
|
||||
<div id = 'flash' style="float:left; width: 100%; display: none" ></div>
|
||||
<div id="put-bid-form" style="display: none">
|
||||
<%= form_for "contest_for_save", :remote=>true,
|
||||
:url => {:controller => 'contests', :action => 'add'},
|
||||
:update => "contesting_project_list",
|
||||
:complete => '$("#put-bid-form").hide();' do |f|
|
||||
%>
|
||||
<table id="contesting_table" border="0" width="100%" style="margin-left: 40px;"> <!--该table为点击我要参加后弹出的-->
|
||||
<tr>
|
||||
<td>
|
||||
<%= select_tag 'contest',
|
||||
options_for_select(select_option_helper(@option)),
|
||||
:name => 'contest',
|
||||
:class => 'grayline'
|
||||
%>
|
||||
</td>
|
||||
<div id="prompt_create_pro">
|
||||
<td>
|
||||
<p>
|
||||
<div class="font_lighter" style="font-size: 13px;">
|
||||
<%= link_to l(:label_create_new_projects),
|
||||
new_project_path(course: 0, project_type: 0),
|
||||
:target=>'_blank'
|
||||
%> <!--跳转到project的new.html.erb-->
|
||||
</div>
|
||||
</p>
|
||||
</td>
|
||||
</div>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><%= f.text_area :contest_message, :id => "contest_message", :required => true, :rows => 4, :cols => 40, :placeholder => l(:label_bid_reason), :style => "resize: none;", :class => 'noline'%></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td align="right">
|
||||
<%= submit_tag l(:button_add),
|
||||
:name => nil ,
|
||||
:class => "enterprise",
|
||||
:onmouseout => "this.style.backgroundPosition = 'left top'",
|
||||
:onmouseover => "this.style.backgroundPosition = 'left -30px'"
|
||||
%>
|
||||
<%= submit_tag l(:button_cancel),
|
||||
:name => nil,
|
||||
:onclick => "cancel();",
|
||||
:type => 'button',
|
||||
:class => "enterprise",
|
||||
:onmouseout => "this.style.backgroundPosition = 'left top'",
|
||||
:onmouseover => "this.style.backgroundPosition = 'left -30px'"
|
||||
%>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id='contesting_project_list'>
|
||||
<%= render :partial => 'project_list',
|
||||
:locals => {:contesting_project => @contesting_project,:contest => @contest}
|
||||
%>
|
||||
</div>
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
<!--add by huang-->
|
||||
<h3><%= l(:label_user_watcher)%></h3>
|
||||
<div class="inf_user_image">
|
||||
<% @contest.watcher_users.each do |user| %> <!-- @contest.watcher_users.count -->
|
||||
<ul class="list_watch">
|
||||
<li>
|
||||
<table width="660px" border="0" align="center">
|
||||
<tr>
|
||||
<td colspan="2" valign="top" width="50" ><%= image_tag(url_to_avatar(user), :class => "avatar") %></td>
|
||||
<td><table width="580px" border="0">
|
||||
<tr>
|
||||
<td colspan="2" width="580px" ><p><%= content_tag "div", link_to_user(user), :class =>"project_avatar_name" %></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2" width="580px" ><p class="font_description">
|
||||
<% unless user.memberships.empty? %>
|
||||
<%= l(:label_contribute_to, :project_count => "#{user.memberships.count}") %>
|
||||
<% for member in user.memberships %>
|
||||
<%= link_to_project(member.project) %><%= (user.memberships.last == member) ? '' : ',' %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="200" align="right" class="font_lighter"><%= l(:label_user_joinin) %><%= format_date(user.created_on) %>
|
||||
</td>
|
||||
</tr>
|
||||
</table></td>
|
||||
</tr>
|
||||
</table></li></ul>
|
||||
<% end %>
|
||||
</div>
|
||||
<% html_title(l(:label_followers)) -%>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue