typus 0.9.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. data/.gitignore +8 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +86 -0
  4. data/Rakefile +61 -0
  5. data/VERSION +1 -0
  6. data/app/controllers/admin/master_controller.rb +354 -0
  7. data/app/controllers/typus_controller.rb +128 -0
  8. data/app/helpers/admin/form_helper.rb +386 -0
  9. data/app/helpers/admin/master_helper.rb +104 -0
  10. data/app/helpers/admin/public_helper.rb +27 -0
  11. data/app/helpers/admin/sidebar_helper.rb +236 -0
  12. data/app/helpers/admin/table_helper.rb +227 -0
  13. data/app/helpers/typus_helper.rb +194 -0
  14. data/app/models/typus_mailer.rb +14 -0
  15. data/app/models/typus_user.rb +5 -0
  16. data/app/views/admin/dashboard/_sidebar.html.erb +9 -0
  17. data/app/views/admin/resources/edit.html.erb +24 -0
  18. data/app/views/admin/resources/index.html.erb +23 -0
  19. data/app/views/admin/resources/new.html.erb +22 -0
  20. data/app/views/admin/resources/show.html.erb +18 -0
  21. data/app/views/admin/shared/_footer.html.erb +1 -0
  22. data/app/views/admin/shared/_pagination.html.erb +28 -0
  23. data/app/views/layouts/admin.html.erb +73 -0
  24. data/app/views/layouts/typus.html.erb +29 -0
  25. data/app/views/typus/dashboard.html.erb +9 -0
  26. data/app/views/typus/recover_password.html.erb +7 -0
  27. data/app/views/typus/reset_password.html.erb +15 -0
  28. data/app/views/typus/sign_in.html.erb +9 -0
  29. data/app/views/typus/sign_up.html.erb +7 -0
  30. data/app/views/typus_mailer/reset_password_link.erb +11 -0
  31. data/config/locales/typus/de.yml +109 -0
  32. data/config/locales/typus/es.yml +109 -0
  33. data/config/locales/typus/language.yml.template +113 -0
  34. data/config/locales/typus/pt-BR.yml +111 -0
  35. data/config/locales/typus/ru.yml +111 -0
  36. data/generators/typus/templates/config/initializers/typus.rb +33 -0
  37. data/generators/typus/templates/config/typus/README +51 -0
  38. data/generators/typus/templates/config/typus/application.yml +6 -0
  39. data/generators/typus/templates/config/typus/application_roles.yml +23 -0
  40. data/generators/typus/templates/config/typus/typus.yml +14 -0
  41. data/generators/typus/templates/config/typus/typus_roles.yml +2 -0
  42. data/generators/typus/templates/db/create_typus_users.rb +21 -0
  43. data/generators/typus/templates/public/images/admin/arrow_down.gif +0 -0
  44. data/generators/typus/templates/public/images/admin/arrow_up.gif +0 -0
  45. data/generators/typus/templates/public/images/admin/spinner.gif +0 -0
  46. data/generators/typus/templates/public/images/admin/status_false.gif +0 -0
  47. data/generators/typus/templates/public/images/admin/status_true.gif +0 -0
  48. data/generators/typus/templates/public/images/admin/trash.gif +0 -0
  49. data/generators/typus/templates/public/javascripts/admin/application.js +14 -0
  50. data/generators/typus/templates/public/stylesheets/admin/reset.css +68 -0
  51. data/generators/typus/templates/public/stylesheets/admin/screen.css +729 -0
  52. data/generators/typus/typus_generator.rb +122 -0
  53. data/generators/typus_update_schema_to_01/templates/config/typus.yml +14 -0
  54. data/generators/typus_update_schema_to_01/templates/migration.rb +11 -0
  55. data/generators/typus_update_schema_to_01/typus_update_schema_to_01_generator.rb +19 -0
  56. data/lib/typus.rb +122 -0
  57. data/lib/typus/active_record.rb +307 -0
  58. data/lib/typus/authentication.rb +142 -0
  59. data/lib/typus/configuration.rb +85 -0
  60. data/lib/typus/extensions/routes.rb +15 -0
  61. data/lib/typus/format.rb +55 -0
  62. data/lib/typus/generator.rb +81 -0
  63. data/lib/typus/hash.rb +8 -0
  64. data/lib/typus/locale.rb +17 -0
  65. data/lib/typus/object.rb +21 -0
  66. data/lib/typus/quick_edit.rb +40 -0
  67. data/lib/typus/reloader.rb +15 -0
  68. data/lib/typus/string.rb +11 -0
  69. data/lib/typus/templates/index.html.erb +11 -0
  70. data/lib/typus/templates/resource_controller.rb.erb +15 -0
  71. data/lib/typus/templates/resource_controller_test.rb.erb +10 -0
  72. data/lib/typus/templates/resources_controller.rb.erb +37 -0
  73. data/lib/typus/user.rb +134 -0
  74. data/lib/vendor/active_record.rb +15 -0
  75. data/lib/vendor/paginator.rb +143 -0
  76. data/rails/init.rb +3 -0
  77. data/tasks/typus_tasks.rake +32 -0
  78. data/test/config/broken/application.yml +68 -0
  79. data/test/config/broken/application_roles.yml +20 -0
  80. data/test/config/broken/empty.yml +0 -0
  81. data/test/config/broken/empty_roles.yml +0 -0
  82. data/test/config/broken/undefined.yml +3 -0
  83. data/test/config/broken/undefined_roles.yml +6 -0
  84. data/test/config/default/typus.yml +14 -0
  85. data/test/config/default/typus_roles.yml +2 -0
  86. data/test/config/empty/empty_01.yml +0 -0
  87. data/test/config/empty/empty_01_roles.yml +0 -0
  88. data/test/config/empty/empty_02.yml +0 -0
  89. data/test/config/empty/empty_02_roles.yml +0 -0
  90. data/test/config/locales/es.yml +10 -0
  91. data/test/config/ordered/001_roles.yml +2 -0
  92. data/test/config/ordered/002_roles.yml +2 -0
  93. data/test/config/unordered/app_one_roles.yml +2 -0
  94. data/test/config/unordered/app_two_roles.yml +2 -0
  95. data/test/config/working/application.yml +68 -0
  96. data/test/config/working/application_roles.yml +22 -0
  97. data/test/config/working/typus.yml +14 -0
  98. data/test/config/working/typus_roles.yml +2 -0
  99. data/test/fixtures/app/controllers/admin/assets_controller.rb +2 -0
  100. data/test/fixtures/app/controllers/admin/categories_controller.rb +2 -0
  101. data/test/fixtures/app/controllers/admin/comments_controller.rb +2 -0
  102. data/test/fixtures/app/controllers/admin/pages_controller.rb +2 -0
  103. data/test/fixtures/app/controllers/admin/posts_controller.rb +2 -0
  104. data/test/fixtures/app/controllers/admin/status_controller.rb +6 -0
  105. data/test/fixtures/app/controllers/admin/typus_users_controller.rb +2 -0
  106. data/test/fixtures/app/controllers/admin/watch_dog_controller.rb +6 -0
  107. data/test/fixtures/app/views/admin/comments/_edit.html.erb +1 -0
  108. data/test/fixtures/app/views/admin/comments/_index.html.erb +1 -0
  109. data/test/fixtures/app/views/admin/comments/_new.html.erb +1 -0
  110. data/test/fixtures/app/views/admin/comments/_show.html.erb +1 -0
  111. data/test/fixtures/app/views/admin/comments/_sidebar.html.erb +1 -0
  112. data/test/fixtures/app/views/admin/dashboard/_content.html.erb +1 -0
  113. data/test/fixtures/app/views/admin/dashboard/_sidebar.html.erb +1 -0
  114. data/test/fixtures/app/views/admin/resources/_sidebar.html.erb +1 -0
  115. data/test/fixtures/app/views/admin/shared/_footer.html.erb +1 -0
  116. data/test/fixtures/app/views/admin/status/index.html.erb +1 -0
  117. data/test/fixtures/app/views/admin/templates/_datepicker.html.erb +1 -0
  118. data/test/fixtures/assets.yml +11 -0
  119. data/test/fixtures/categories.yml +14 -0
  120. data/test/fixtures/comments.yml +27 -0
  121. data/test/fixtures/pages.yml +41 -0
  122. data/test/fixtures/posts.yml +37 -0
  123. data/test/fixtures/typus_users.yml +54 -0
  124. data/test/functional/admin/assets_controller_test.rb +57 -0
  125. data/test/functional/admin/categories_controller_test.rb +106 -0
  126. data/test/functional/admin/comments_controller_test.rb +120 -0
  127. data/test/functional/admin/master_controller_test.rb +5 -0
  128. data/test/functional/admin/posts_controller_test.rb +261 -0
  129. data/test/functional/admin/status_controller_test.rb +43 -0
  130. data/test/functional/admin/typus_users_controller_test.rb +239 -0
  131. data/test/functional/typus_controller_test.rb +321 -0
  132. data/test/helper.rb +51 -0
  133. data/test/helpers/admin/form_helper_test.rb +337 -0
  134. data/test/helpers/admin/master_helper_test.rb +69 -0
  135. data/test/helpers/admin/public_helper_test.rb +26 -0
  136. data/test/helpers/admin/sidebar_helper_test.rb +335 -0
  137. data/test/helpers/admin/table_helper_test.rb +239 -0
  138. data/test/helpers/typus_helper_test.rb +117 -0
  139. data/test/lib/active_record_test.rb +382 -0
  140. data/test/lib/configuration_test.rb +94 -0
  141. data/test/lib/hash_test.rb +11 -0
  142. data/test/lib/routes_test.rb +71 -0
  143. data/test/lib/string_test.rb +25 -0
  144. data/test/lib/typus_test.rb +85 -0
  145. data/test/models.rb +51 -0
  146. data/test/schema.rb +64 -0
  147. data/test/unit/typus_mailer_test.rb +33 -0
  148. data/test/unit/typus_test.rb +17 -0
  149. data/test/unit/typus_user_roles_test.rb +90 -0
  150. data/test/unit/typus_user_test.rb +177 -0
  151. data/test/vendor/active_record_test.rb +18 -0
  152. data/test/vendor/paginator_test.rb +136 -0
  153. data/typus.gemspec +228 -0
  154. metadata +241 -0
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.swp
2
+ *.db
3
+ *.log
4
+ _dashboard*
5
+ rdoc/*
6
+ *~
7
+ *.gem
8
+ SPECDOC
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2007-2009 Francesc Esplugas Marti
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,86 @@
1
+ = Typus: Effortless admin interface for your Rails application
2
+
3
+ *Typus* is designed for a single activity:
4
+
5
+ Trusted users editing structured content.
6
+
7
+ *Typus* doesn't try to be all the things to all the people but it's
8
+ extensible enough to match lots of use cases.
9
+
10
+ - Project site and documentation http://intraducibles.com/projects/typus
11
+ - Plugin source http://github.com/fesplugas/typus/tree
12
+ - Google Group http://groups.google.es/group/typus
13
+ - Bugs http://typus.lighthouseapp.com/dashboard
14
+
15
+ == Impatients to see it working?
16
+
17
+ Step 1: Create a Rails application using a template.
18
+
19
+ $ rails example.com -m http://gist.github.com/86613.txt
20
+
21
+ Step 2: Start the server:
22
+
23
+ $ cd example.com && script/server
24
+
25
+ Step 3: Go to the admin area and enjoy it!
26
+
27
+ http://0.0.0.0:3000/admin
28
+
29
+ == Installing
30
+
31
+ Install from GitHub the latest version which it's compatible with Rails 2.3.2.
32
+
33
+ $ script/plugin install git://github.com/fesplugas/typus.git
34
+
35
+ Once *Typus* is installed, run the generator to create required files and migrate your
36
+ database. (<tt>typus_users</tt> table is created)
37
+
38
+ $ script/generate typus
39
+ $ rake db:migrate
40
+
41
+ To create the first user, start the application server, go to
42
+ http://0.0.0.0:3000/admin and follow the instructions.
43
+
44
+ == Support Typus
45
+
46
+ *Typus* is licensed under the MIT license. As an experiment we
47
+ encourage you to support this project by donating[http://intraducibles.com/projects/typus/donate]
48
+ 90 euros if you are a developer or studio. Donations do allow us to spend more
49
+ time working and supporting the project. All contributions are much appreciated!
50
+
51
+ Hire us to work on your next project. We build large and small websites.
52
+
53
+ Contribute your patches to the community & support people on the
54
+ mailing list.
55
+
56
+ Tell everybody about Typus, tell your friends and colleagues about
57
+ Typus and blog about Typus.
58
+
59
+ == Contributors
60
+
61
+ - Laia Gargallo (Lover and tea provider) http://azotacalles.net
62
+ - Isaac Feliu (Codereview on first public release) http://www.vesne.com
63
+ - Lluis Folch (Icons, feedback & crazy ideas) http://wet-floor.com
64
+ - Sergio Espeja (Code) http://github.com/spejman
65
+ - Eadz (Code) http://github.com/eadz
66
+ - Anthony Underwood (Code) http://github.com/aunderwo
67
+ - Felipe Talavera (Code) http://github.com/flype
68
+ - Erik Tigerholm (Code) http://github.com/eriktigerholm
69
+ - George Guimarães (Portuguese translation and code) http://github.com/georgeguimaraes
70
+ - José Valim (Code) http://github.com/josevalim
71
+ - Luqman Amjad (Code) http://github.com/snake
72
+ - Alexey Noskov (Russian translation and code) http://github.com/alno
73
+ - Andres Gutierres (Bugfixes & feedback) http://github.com/andresgutgon
74
+ - Komzák Nándor (Code, bugfixes & feedback) http://github.com/rubymood
75
+ - Michael Grunewalder (German translation) http://michael.grunewalder.com
76
+ - Tim Harvey (Code) http://www.timharvey.net/
77
+ - Ned Baldessin (Code) http://github.com/nedbaldessin
78
+ - Robert Rouse (Code) - Ruby 1.9 compatibility fixes.
79
+
80
+ == Acknowledgments
81
+
82
+ - *Typus* uses "Paginator" by Bruce Williams http://codefluency.com.
83
+ - *Typus* has been inspired by "Django Admin" http://www.djangoproject.com.
84
+
85
+ Copyright (c) 2007-2009 Francesc Esplugas Marti, released under the
86
+ MIT license
data/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+
5
+ desc 'Default: run unit tests.'
6
+ task :default => :test
7
+
8
+ desc 'Test the typus plugin.'
9
+ Rake::TestTask.new(:test) do |t|
10
+ t.libs << 'lib'
11
+ t.pattern = 'test/**/*_test.rb'
12
+ t.verbose = true
13
+ end
14
+
15
+ desc 'Generate documentation for the typus plugin.'
16
+ Rake::RDocTask.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_files.add ['README.rdoc', 'MIT-LICENSE', 'lib/**/*.rb']
18
+ rdoc.rdoc_dir = 'rdoc'
19
+ rdoc.title = 'Typus documentation'
20
+ rdoc.main = 'README.rdoc'
21
+ rdoc.options << '--charset=UTF-8'
22
+ rdoc.options << '--inline-source'
23
+ rdoc.options << '--line-numbers'
24
+ end
25
+
26
+ desc 'Generate specdoc-style documentation from tests'
27
+ task :specs do
28
+
29
+ puts 'Started'
30
+ timer, count = Time.now, 0
31
+
32
+ File.open('SPECDOC', 'w') do |file|
33
+ Dir.glob('test/**/*_test.rb').each do |test|
34
+ test =~ /.*\/([^\/].*)_test.rb$/
35
+ file.puts "#{$1.gsub('_', ' ').capitalize} should:" if $1
36
+ File.read(test).map { |line| /test_(.*)$/.match line }.compact.each do |spec|
37
+ file.puts "- #{spec[1].gsub('_', ' ')}"
38
+ sleep 0.001; print '.'; $stdout.flush; count += 1
39
+ end
40
+ file.puts
41
+ end
42
+ end
43
+
44
+ puts "\nFinished in #{Time.now - timer} seconds.\n"
45
+ puts "#{count} specifications documented"
46
+
47
+ end
48
+
49
+ begin
50
+ require 'jeweler'
51
+ Jeweler::Tasks.new do |gemspec|
52
+ gemspec.name = "typus"
53
+ gemspec.summary = "Effortless backend interface for Ruby on Rails applications. (Admin scaffold generator.)"
54
+ gemspec.email = "francesc@intraducibles.com"
55
+ gemspec.homepage = "http://intraducibles.com/projects/typus"
56
+ gemspec.description = "Effortless backend interface for Ruby on Rails applications. (Admin scaffold generator.)"
57
+ gemspec.authors = ["Francesc Esplugas"]
58
+ end
59
+ rescue LoadError
60
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
61
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.9.17
@@ -0,0 +1,354 @@
1
+ class Admin::MasterController < ApplicationController
2
+
3
+ unloadable
4
+
5
+ layout 'admin'
6
+
7
+ include Typus::Authentication
8
+ include Typus::Format
9
+ include Typus::Locale
10
+ include Typus::Reloader
11
+
12
+ if Typus::Configuration.options[:ssl]
13
+ include SslRequirement
14
+ ssl_required :index, :new, :create, :edit, :show, :update, :destroy, :toggle, :position, :relate, :unrelate
15
+ end
16
+
17
+ filter_parameter_logging :password
18
+
19
+ before_filter :reload_config_et_roles
20
+
21
+ before_filter :require_login
22
+
23
+ before_filter :set_locale
24
+
25
+ before_filter :set_resource
26
+ before_filter :find_item,
27
+ :only => [ :show, :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
28
+
29
+ before_filter :check_ownership_of_item,
30
+ :only => [ :edit, :update, :destroy, :toggle, :position, :relate, :unrelate ]
31
+
32
+ before_filter :check_if_user_can_perform_action_on_user,
33
+ :only => [ :edit, :update, :toggle, :destroy ]
34
+ before_filter :check_if_user_can_perform_action_on_resource
35
+
36
+ before_filter :set_order,
37
+ :only => [ :index ]
38
+ before_filter :set_fields,
39
+ :only => [ :index, :new, :edit, :create, :update, :show ]
40
+
41
+ before_filter :set_tiny_mce,
42
+ :only => [ :new, :edit, :create, :update ]
43
+
44
+ ##
45
+ # This is the main index of the model. With filters, conditions
46
+ # and more.
47
+ #
48
+ # By default application can respond_to html, csv and xml, but you
49
+ # can add your formats.
50
+ #
51
+ def index
52
+
53
+ @conditions, @joins = @resource[:class].build_conditions(params)
54
+
55
+ check_ownership_of_items if @resource[:class].typus_options_for(:only_user_items)
56
+
57
+ respond_to do |format|
58
+ format.html { generate_html }
59
+ @resource[:class].typus_export_formats.each do |f|
60
+ format.send(f) { send("generate_#{f}") }
61
+ end
62
+ end
63
+
64
+ rescue Exception => error
65
+ error_handler(error)
66
+ end
67
+
68
+ def new
69
+
70
+ item_params = params.dup
71
+ %w( controller action resource resource_id back_to selected ).each do |param|
72
+ item_params.delete(param)
73
+ end
74
+
75
+ @item = @resource[:class].new(item_params.symbolize_keys)
76
+
77
+ select_template :new
78
+
79
+ end
80
+
81
+ ##
82
+ # Create new items. There's an special case when we create an
83
+ # item from another item. In this case, after the item is
84
+ # created we also create the relationship between these items.
85
+ #
86
+ def create
87
+
88
+ @item = @resource[:class].new(params[:item])
89
+
90
+ if @item.attributes.include?(Typus.user_fk)
91
+ @item.attributes = { Typus.user_fk => session[:typus_user_id] }
92
+ end
93
+
94
+ if @item.valid?
95
+ create_with_back_to and return if params[:back_to]
96
+ @item.save
97
+ flash[:success] = _("{{model}} successfully created.", :model => @resource[:class].typus_human_name)
98
+ if @resource[:class].typus_options_for(:index_after_save)
99
+ redirect_to :action => 'index'
100
+ else
101
+ redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id
102
+ end
103
+ else
104
+ select_template :new
105
+ end
106
+
107
+ end
108
+
109
+ def edit
110
+ item_params = params.dup
111
+ %w( action controller model model_id back_to id resource resource_id page ).each { |p| item_params.delete(p) }
112
+ # We assign the params passed trough the url
113
+ @item.attributes = item_params
114
+ @previous, @next = @item.previous_and_next(item_params)
115
+ select_template :edit
116
+ end
117
+
118
+ def show
119
+
120
+ @previous, @next = @item.previous_and_next
121
+
122
+ respond_to do |format|
123
+ format.html { select_template :show }
124
+ format.xml do
125
+ fields = @resource[:class].typus_fields_for(:xml).collect { |i| i.first }
126
+ render :xml => @item.to_xml(:only => fields)
127
+ end
128
+ end
129
+
130
+ end
131
+
132
+ def update
133
+ if @item.update_attributes(params[:item])
134
+ flash[:success] = _("{{model}} successfully updated.", :model => @resource[:class].typus_human_name)
135
+ path = if @resource[:class].typus_options_for(:index_after_save)
136
+ params[:back_to] ? "#{params[:back_to]}##{@resource[:self]}" : { :action => 'index' }
137
+ else
138
+ { :action => @resource[:class].typus_options_for(:default_action_on_item), :id => @item.id, :back_to => params[:back_to] }
139
+ end
140
+ redirect_to path
141
+ else
142
+ @previous, @next = @item.previous_and_next
143
+ select_template :edit
144
+ end
145
+ end
146
+
147
+ def destroy
148
+ @item.destroy
149
+ flash[:success] = _("{{model}} successfully removed.", :model => @resource[:class].typus_human_name)
150
+ redirect_to :back
151
+ rescue Exception => error
152
+ error_handler(error, params.merge(:action => 'index', :id => nil))
153
+ end
154
+
155
+ def toggle
156
+ if @resource[:class].typus_options_for(:toggle)
157
+ @item.toggle!(params[:field])
158
+ flash[:success] = _("{{model}} {{attribute}} changed.",
159
+ :model => @resource[:class].typus_human_name,
160
+ :attribute => params[:field].humanize.downcase)
161
+ else
162
+ flash[:notice] = _("Toggle is disabled.")
163
+ end
164
+ redirect_to :back
165
+ end
166
+
167
+ ##
168
+ # Change item position. This only works if acts_as_list is
169
+ # installed. We can then move items:
170
+ #
171
+ # params[:go] = 'move_to_top'
172
+ #
173
+ # Available positions are move_to_top, move_higher, move_lower,
174
+ # move_to_bottom.
175
+ #
176
+ def position
177
+ @item.send(params[:go])
178
+ flash[:success] = _("Record moved {{to}}.", :to => params[:go].gsub(/move_/, '').humanize.downcase)
179
+ redirect_to :back
180
+ end
181
+
182
+ ##
183
+ # Relate a model object to another, this action is used only by the
184
+ # has_and_belongs_to_many relationships.
185
+ #
186
+ def relate
187
+
188
+ resource_class = params[:related][:model].constantize
189
+ resource_tableized = params[:related][:model].tableize
190
+
191
+ @item.send(resource_tableized) << resource_class.find(params[:related][:id])
192
+
193
+ flash[:success] = _("{{model_a}} related to {{model_b}}.",
194
+ :model_a => resource_class.typus_human_name,
195
+ :model_b => @resource[:class].typus_human_name)
196
+
197
+ redirect_to :action => @resource[:class].typus_options_for(:default_action_on_item),
198
+ :id => @item.id,
199
+ :anchor => resource_tableized
200
+
201
+ end
202
+
203
+ ##
204
+ # Remove relationship between models.
205
+ #
206
+ def unrelate
207
+
208
+ resource_class = params[:resource].classify.constantize
209
+ resource = resource_class.find(params[:resource_id])
210
+
211
+ case params[:association]
212
+ when 'has_and_belongs_to_many'
213
+ @item.send(resource_class.table_name).delete(resource)
214
+ message = "{{model_a}} unrelated from {{model_b}}."
215
+ when 'has_many', 'has_one'
216
+ resource.destroy
217
+ message = "{{model_a}} removed from {{model_b}}."
218
+ end
219
+
220
+ flash[:success] = _(message, :model_a => resource_class.typus_human_name, :model_b => @resource[:class].typus_human_name)
221
+
222
+ redirect_to :controller => @resource[:self],
223
+ :action => @resource[:class].typus_options_for(:default_action_on_item),
224
+ :id => @item.id,
225
+ :anchor => resource_class.table_name
226
+
227
+ end
228
+
229
+ private
230
+
231
+ def set_resource
232
+ resource = params[:controller].split('/').last
233
+ @resource = { :self => resource, :class => resource.classify.constantize }
234
+ rescue Exception => error
235
+ error_handler(error)
236
+ end
237
+
238
+ ##
239
+ # Find model when performing an edit, update, destroy, relate,
240
+ # unrelate ...
241
+ #
242
+ def find_item
243
+ @item = @resource[:class].find(params[:id])
244
+ end
245
+
246
+ ##
247
+ # If item is owned by another user, we only can perform a
248
+ # show action on the item. Updated item is also blocked.
249
+ #
250
+ # before_filter :check_ownership_of_item, :only => [ :edit, :update, :destroy ]
251
+ #
252
+ def check_ownership_of_item
253
+
254
+ # If current_user is a root user, by-pass.
255
+ return if @current_user.is_root?
256
+
257
+ # OPTIMIZE: `typus_users` is currently hard-coded. We should find a good name for this option.
258
+ if @item.respond_to?('typus_users') && !@item.send('typus_users').include?(@current_user) ||
259
+ @item.respond_to?(Typus.user_fk) && !(@item.send(Typus.user_fk) == session[:typus_user_id])
260
+ flash[:notice] = _("You don't have permission to access this item.")
261
+ redirect_to :back
262
+ end
263
+
264
+ end
265
+
266
+ def check_ownership_of_items
267
+
268
+ # By-pass if current_user is root.
269
+ return if @current_user.is_root?
270
+
271
+ # If current user is not root and @resource has a foreign_key which
272
+ # is related to the logged user (Typus.user_fk) we only show the user
273
+ # related items.
274
+ if @resource[:class].columns.map { |u| u.name }.include?(Typus.user_fk)
275
+ condition = { Typus.user_fk => @current_user }
276
+ @conditions = @resource[:class].merge_conditions(@conditions, condition)
277
+ end
278
+
279
+ end
280
+
281
+ def set_fields
282
+ @fields = case params[:action]
283
+ when 'index'
284
+ @resource[:class].typus_fields_for(:list)
285
+ when 'new', 'edit', 'create', 'update'
286
+ @resource[:class].typus_fields_for(:form)
287
+ else
288
+ @resource[:class].typus_fields_for(params[:action])
289
+ end
290
+ end
291
+
292
+ def set_order
293
+ params[:sort_order] ||= 'desc'
294
+ @order = params[:order_by] ? "#{@resource[:class].table_name}.#{params[:order_by]} #{params[:sort_order]}" : @resource[:class].typus_order_by
295
+ end
296
+
297
+ def set_tiny_mce
298
+ if !@resource[:class].typus_tiny_mce_fields.empty? && defined?(TinyMCE)
299
+ options = @resource[:class].typus_tiny_mce_options
300
+ self.class.class_eval { uses_tiny_mce :options => options }
301
+ end
302
+ end
303
+
304
+ def select_template(template, resource = @resource[:self])
305
+ folder = (File.exist?("app/views/admin/#{resource}/#{template}.html.erb")) ? resource : 'resources'
306
+ render "admin/#{folder}/#{template}"
307
+ end
308
+
309
+ ##
310
+ # When <tt>params[:back_to]</tt> is defined this action is used.
311
+ #
312
+ # - <tt>has_and_belongs_to_many</tt> relationships.
313
+ # - <tt>has_many</tt> relationships (polymorphic ones).
314
+ #
315
+ def create_with_back_to
316
+
317
+ if params[:resource] && params[:resource_id]
318
+ resource_class = params[:resource].classify.constantize
319
+ resource_id = params[:resource_id]
320
+ resource = resource_class.find(resource_id)
321
+ association = @resource[:class].reflect_on_association(params[:resource].to_sym).macro rescue :polymorphic
322
+ else
323
+ association = :has_many
324
+ end
325
+
326
+ case association
327
+ when :belongs_to
328
+ @item.save
329
+ when :has_and_belongs_to_many
330
+ @item.save
331
+ @item.send(params[:resource]) << resource
332
+ when :has_many
333
+ @item.save
334
+ message = _("{{model}} successfully created.", :model => @resource[:class].typus_human_name)
335
+ path = "#{params[:back_to]}?#{params[:selected]}=#{@item.id}"
336
+ when :polymorphic
337
+ resource.send(@item.class.name.tableize).create(params[:item])
338
+ path = "#{params[:back_to]}##{@resource[:self]}"
339
+ end
340
+
341
+ flash[:success] = message || _("{{model_a}} successfully assigned to {{model_b}}.",
342
+ :model_a => @item.class.typus_human_name,
343
+ :model_b => resource_class.name)
344
+ redirect_to path || params[:back_to]
345
+
346
+ end
347
+
348
+ def error_handler(error, path = admin_dashboard_path)
349
+ raise error unless Rails.env.production?
350
+ flash[:error] = "#{error.message} (#{@resource[:class]})"
351
+ redirect_to path
352
+ end
353
+
354
+ end