radiant 0.6.3 → 0.6.4

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.

Potentially problematic release.


This version of radiant might be problematic. Click here for more details.

Files changed (197) hide show
  1. data/CHANGELOG +61 -7
  2. data/CONTRIBUTORS +15 -0
  3. data/app/controllers/admin/export_controller.rb +1 -1
  4. data/app/controllers/admin/page_controller.rb +1 -0
  5. data/app/controllers/admin/user_controller.rb +2 -1
  6. data/app/controllers/application.rb +7 -8
  7. data/app/helpers/admin/node_helper.rb +84 -0
  8. data/app/helpers/admin/page_helper.rb +1 -19
  9. data/app/helpers/application_helper.rb +15 -9
  10. data/app/models/file_not_found_page.rb +2 -2
  11. data/app/models/page.rb +22 -18
  12. data/app/models/page_context.rb +9 -0
  13. data/app/models/radiant/config.rb +4 -2
  14. data/app/models/response_cache.rb +18 -12
  15. data/app/models/standard_tags.rb +111 -50
  16. data/app/views/admin/extension/index.rhtml +2 -2
  17. data/app/views/admin/layout/edit.rhtml +2 -2
  18. data/app/views/admin/layout/remove.rhtml +2 -2
  19. data/app/views/admin/page/_node.rhtml +4 -26
  20. data/app/views/admin/page/_part.rhtml +9 -14
  21. data/app/views/admin/page/edit.rhtml +38 -121
  22. data/app/views/admin/page/index.rhtml +2 -6
  23. data/app/views/admin/page/remove.rhtml +2 -2
  24. data/app/views/admin/snippet/edit.rhtml +3 -3
  25. data/app/views/admin/snippet/index.rhtml +2 -2
  26. data/app/views/admin/snippet/remove.rhtml +2 -2
  27. data/app/views/admin/user/edit.rhtml +4 -4
  28. data/app/views/admin/user/preferences.rhtml +2 -2
  29. data/app/views/admin/welcome/login.rhtml +1 -1
  30. data/config/environment.rb +79 -78
  31. data/db/schema.rb +2 -0
  32. data/lib/local_time.rb +12 -0
  33. data/lib/plugins/extension_patches/lib/fixture_loading_extension.rb +1 -1
  34. data/lib/plugins/extension_patches/lib/mailer_view_paths_extension.rb +3 -3
  35. data/lib/radiant.rb +1 -1
  36. data/lib/radiant/extension.rb +9 -3
  37. data/lib/radiant/extension_loader.rb +2 -2
  38. data/lib/tasks/extensions.rake +23 -8
  39. data/public/javascripts/admin.js +89 -0
  40. data/public/javascripts/controls.js +486 -354
  41. data/public/javascripts/dragdrop.js +90 -58
  42. data/public/javascripts/effects.js +398 -364
  43. data/public/javascripts/pngfix.js +37 -37
  44. data/public/javascripts/prototype.js +2764 -1095
  45. data/public/javascripts/ruledtable.js +10 -25
  46. data/public/javascripts/sitemap.js +74 -112
  47. data/public/javascripts/string.js +1 -7
  48. data/public/javascripts/tabcontrol.js +71 -86
  49. data/public/javascripts/tag_reference_search.js +19 -26
  50. data/public/stylesheets/admin/main.css +11 -5
  51. data/test/fixtures/extensions/01_basic/lib/new_module.rb +2 -0
  52. data/test/fixtures/page_parts.yml +16 -1
  53. data/test/fixtures/pages.yml +47 -84
  54. data/test/functional/extension_initialization_test.rb +11 -0
  55. data/test/helpers/login_test_helper.rb +12 -1
  56. data/test/helpers/page_test_helper.rb +6 -0
  57. data/test/helpers/render_test_helper.rb +11 -8
  58. data/test/test_helper.rb +1 -12
  59. data/test/unit/file_not_found_page_test.rb +5 -1
  60. data/test/unit/local_time_test.rb +45 -0
  61. data/test/unit/page_context_test.rb +32 -1
  62. data/test/unit/page_test.rb +45 -11
  63. data/test/unit/radiant/config_test.rb +1 -1
  64. data/test/unit/response_cache_test.rb +27 -2
  65. data/test/unit/standard_tags_test.rb +60 -15
  66. data/vendor/extensions/archive/README +29 -0
  67. data/vendor/extensions/archive/Rakefile +25 -0
  68. data/{app → vendor/extensions/archive/app}/models/archive_day_index_page.rb +0 -0
  69. data/{app → vendor/extensions/archive/app}/models/archive_finder.rb +8 -6
  70. data/{app → vendor/extensions/archive/app}/models/archive_month_index_page.rb +0 -0
  71. data/{app → vendor/extensions/archive/app}/models/archive_page.rb +0 -0
  72. data/{app → vendor/extensions/archive/app}/models/archive_year_index_page.rb +0 -0
  73. data/vendor/extensions/archive/archive_extension.rb +19 -0
  74. data/{lib → vendor/extensions/archive/lib}/archive_index_tags_and_methods.rb +0 -0
  75. data/vendor/extensions/archive/lib/tasks/archive_extension_tasks.rake +28 -0
  76. data/vendor/extensions/archive/test/fixtures/pages.yml +397 -0
  77. data/vendor/extensions/archive/test/functional/archive_extension_test.rb +16 -0
  78. data/{test → vendor/extensions/archive/test}/helpers/archive_index_test_helper.rb +0 -0
  79. data/vendor/extensions/archive/test/test_helper.rb +19 -0
  80. data/{test → vendor/extensions/archive/test}/unit/archive_day_index_page_test.rb +0 -0
  81. data/{test → vendor/extensions/archive/test}/unit/archive_month_index_page_test.rb +0 -0
  82. data/{test → vendor/extensions/archive/test}/unit/archive_page_test.rb +7 -1
  83. data/{test → vendor/extensions/archive/test}/unit/archive_year_index_page_test.rb +0 -0
  84. data/vendor/rails/actionmailer/CHANGELOG +10 -0
  85. data/vendor/rails/actionmailer/Rakefile +1 -1
  86. data/vendor/rails/actionmailer/lib/action_mailer/version.rb +1 -1
  87. data/vendor/rails/actionpack/CHANGELOG +51 -2
  88. data/vendor/rails/actionpack/Rakefile +1 -1
  89. data/vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb +2 -2
  90. data/vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb +1 -1
  91. data/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb +3 -0
  92. data/vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb +1 -0
  93. data/vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb +2 -0
  94. data/vendor/rails/actionpack/lib/action_controller/base.rb +7 -1
  95. data/vendor/rails/actionpack/lib/action_controller/caching.rb +39 -38
  96. data/vendor/rails/actionpack/lib/action_controller/cgi_ext/pstore_performance_fix.rb +30 -0
  97. data/vendor/rails/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb +1 -1
  98. data/vendor/rails/actionpack/lib/action_controller/cgi_process.rb +13 -4
  99. data/vendor/rails/actionpack/lib/action_controller/cookies.rb +5 -3
  100. data/vendor/rails/actionpack/lib/action_controller/filters.rb +176 -77
  101. data/vendor/rails/actionpack/lib/action_controller/integration.rb +31 -21
  102. data/vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb +1 -1
  103. data/vendor/rails/actionpack/lib/action_controller/pagination.rb +7 -1
  104. data/vendor/rails/actionpack/lib/action_controller/resources.rb +117 -32
  105. data/vendor/rails/actionpack/lib/action_controller/routing.rb +56 -23
  106. data/vendor/rails/actionpack/lib/action_controller/test_process.rb +5 -2
  107. data/vendor/rails/actionpack/lib/action_controller/url_rewriter.rb +4 -1
  108. data/vendor/rails/actionpack/lib/action_controller/verification.rb +1 -0
  109. data/vendor/rails/actionpack/lib/action_pack/version.rb +1 -1
  110. data/vendor/rails/actionpack/lib/action_view/base.rb +25 -19
  111. data/vendor/rails/actionpack/lib/action_view/compiled_templates.rb +2 -2
  112. data/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb +18 -18
  113. data/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb +10 -0
  114. data/vendor/rails/actionpack/lib/action_view/helpers/deprecated_helper.rb +3 -0
  115. data/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb +33 -17
  116. data/vendor/rails/actionpack/test/activerecord/pagination_test.rb +9 -0
  117. data/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb +13 -0
  118. data/vendor/rails/actionpack/test/controller/addresses_render_test.rb +4 -1
  119. data/vendor/rails/actionpack/test/controller/base_test.rb +1 -1
  120. data/vendor/rails/actionpack/test/controller/caching_test.rb +3 -2
  121. data/vendor/rails/actionpack/test/controller/cookie_test.rb +11 -0
  122. data/vendor/rails/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb +18 -0
  123. data/vendor/rails/actionpack/test/controller/filter_params_test.rb +1 -0
  124. data/vendor/rails/actionpack/test/controller/filters_test.rb +149 -26
  125. data/vendor/rails/actionpack/test/controller/integration_test.rb +93 -8
  126. data/vendor/rails/actionpack/test/controller/resources_test.rb +215 -36
  127. data/vendor/rails/actionpack/test/controller/routing_test.rb +2 -2
  128. data/vendor/rails/actionpack/test/controller/test_test.rb +16 -0
  129. data/vendor/rails/actionpack/test/controller/url_rewriter_test.rb +66 -10
  130. data/vendor/rails/actionpack/test/controller/verification_test.rb +15 -0
  131. data/vendor/rails/actionpack/test/fixtures/test/hello_world.rxml +2 -1
  132. data/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb +5 -0
  133. data/vendor/rails/actionpack/test/template/compiled_templates_test.rb +29 -17
  134. data/vendor/rails/actionpack/test/template/javascript_helper_test.rb +4 -4
  135. data/vendor/rails/actionpack/test/template/number_helper_test.rb +1 -1
  136. data/vendor/rails/actionpack/test/template/prototype_helper_test.rb +13 -13
  137. data/vendor/rails/actionwebservice/CHANGELOG +14 -0
  138. data/vendor/rails/actionwebservice/Rakefile +2 -2
  139. data/vendor/rails/actionwebservice/lib/action_web_service/version.rb +1 -1
  140. data/vendor/rails/activerecord/CHANGELOG +34 -0
  141. data/vendor/rails/activerecord/Rakefile +1 -1
  142. data/vendor/rails/activerecord/lib/active_record/acts/list.rb +14 -2
  143. data/vendor/rails/activerecord/lib/active_record/acts/tree.rb +7 -0
  144. data/vendor/rails/activerecord/lib/active_record/associations.rb +29 -14
  145. data/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb +5 -1
  146. data/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb +2 -2
  147. data/vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb +10 -0
  148. data/vendor/rails/activerecord/lib/active_record/base.rb +12 -3
  149. data/vendor/rails/activerecord/lib/active_record/calculations.rb +2 -2
  150. data/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
  151. data/vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  152. data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +2 -2
  153. data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +54 -38
  154. data/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb +3 -3
  155. data/vendor/rails/activerecord/lib/active_record/fixtures.rb +1 -1
  156. data/vendor/rails/activerecord/lib/active_record/timestamp.rb +0 -9
  157. data/vendor/rails/activerecord/lib/active_record/version.rb +1 -1
  158. data/vendor/rails/activerecord/test/associations/eager_test.rb +13 -0
  159. data/vendor/rails/activerecord/test/associations/join_model_test.rb +10 -1
  160. data/vendor/rails/activerecord/test/associations_test.rb +36 -3
  161. data/vendor/rails/activerecord/test/base_test.rb +17 -4
  162. data/vendor/rails/activerecord/test/defaults_test.rb +15 -0
  163. data/vendor/rails/activerecord/test/fixtures/author.rb +1 -0
  164. data/vendor/rails/activerecord/test/fixtures/binaries.yml +437 -0
  165. data/vendor/rails/activerecord/test/fixtures/db_definitions/schema.rb +13 -0
  166. data/vendor/rails/activerecord/test/fixtures/developer.rb +10 -0
  167. data/vendor/rails/activerecord/test/fixtures_test.rb +9 -5
  168. data/vendor/rails/activerecord/test/migration_test.rb +9 -10
  169. data/vendor/rails/activerecord/test/mixin_test.rb +47 -0
  170. data/vendor/rails/activerecord/test/validations_test.rb +2 -2
  171. data/vendor/rails/activesupport/CHANGELOG +16 -0
  172. data/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb +9 -3
  173. data/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb +48 -3
  174. data/vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb +14 -0
  175. data/vendor/rails/activesupport/lib/active_support/dependencies.rb +3 -3
  176. data/vendor/rails/activesupport/lib/active_support/json/encoders/core.rb +5 -3
  177. data/vendor/rails/activesupport/lib/active_support/multibyte/chars.rb +6 -6
  178. data/vendor/rails/activesupport/lib/active_support/version.rb +1 -1
  179. data/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb +37 -0
  180. data/vendor/rails/activesupport/test/core_ext/module_test.rb +8 -0
  181. data/vendor/rails/activesupport/test/dependencies_test.rb +11 -0
  182. data/vendor/rails/activesupport/test/{json.rb → json_test.rb} +15 -5
  183. data/vendor/rails/railties/CHANGELOG +25 -1
  184. data/vendor/rails/railties/README +32 -3
  185. data/vendor/rails/railties/Rakefile +5 -5
  186. data/vendor/rails/railties/environments/boot.rb +12 -18
  187. data/vendor/rails/railties/environments/environment.rb +15 -15
  188. data/vendor/rails/railties/lib/dispatcher.rb +1 -2
  189. data/vendor/rails/railties/lib/initializer.rb +33 -9
  190. data/vendor/rails/railties/lib/rails/version.rb +1 -1
  191. data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +1 -1
  192. data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb +1 -0
  193. data/vendor/rails/railties/lib/railties_path.rb +1 -1
  194. data/vendor/rails/railties/lib/tasks/framework.rake +4 -4
  195. data/vendor/rails/railties/lib/tasks/routes.rake +17 -0
  196. data/vendor/rails/release.rb +2 -2
  197. metadata +1877 -1848
@@ -62,9 +62,11 @@ module ActionController #:nodoc:
62
62
  end
63
63
 
64
64
  # Removes the cookie on the client machine by setting the value to an empty string
65
- # and setting its expiration date into the past
66
- def delete(name)
67
- set_cookie("name" => name.to_s, "value" => "", "expires" => Time.at(0))
65
+ # and setting its expiration date into the past. Like []=, you can pass in an options
66
+ # hash to delete cookies with extra data such as a +path+.
67
+ def delete(name, options = {})
68
+ options.stringify_keys!
69
+ set_cookie(options.merge("name" => name.to_s, "value" => "", "expires" => Time.at(0)))
68
70
  end
69
71
 
70
72
  private
@@ -214,9 +214,10 @@ module ActionController #:nodoc:
214
214
  # == Filter Chain Halting
215
215
  #
216
216
  # <tt>before_filter</tt> and <tt>around_filter</tt> may halt the request
217
- # before controller action is run. This is useful, for example, to deny
217
+ # before a controller action is run. This is useful, for example, to deny
218
218
  # access to unauthenticated users or to redirect from http to https.
219
219
  # Simply return false from the filter or call render or redirect.
220
+ # After filters will not be executed if the filter chain is halted.
220
221
  #
221
222
  # Around filters halt the request unless the action block is called.
222
223
  # Given these filters
@@ -238,12 +239,12 @@ module ActionController #:nodoc:
238
239
  # . . /
239
240
  # . #around (code after yield)
240
241
  # . /
241
- # #after (actual filter code is run)
242
+ # #after (actual filter code is run, unless the around filter does not yield)
242
243
  #
243
- # If #around returns before yielding, only #after will be run. The #before
244
- # filter and controller action will not be run. If #before returns false,
245
- # the second half of #around and all of #after will still run but the
246
- # action will not.
244
+ # If #around returns before yielding, #after will still not be run. The #before
245
+ # filter and controller action will not be run. If #before returns false,
246
+ # the second half of #around and will still run but #after and the
247
+ # action will not. If #around does not yield, #after will not be run.
247
248
  module ClassMethods
248
249
  # The passed <tt>filters</tt> will be appended to the filter_chain and
249
250
  # will execute before the action on this controller is performed.
@@ -263,13 +264,13 @@ module ActionController #:nodoc:
263
264
  # The passed <tt>filters</tt> will be appended to the array of filters
264
265
  # that run _after_ actions on this controller are performed.
265
266
  def append_after_filter(*filters, &block)
266
- prepend_filter_to_chain(filters, :after, &block)
267
+ append_filter_to_chain(filters, :after, &block)
267
268
  end
268
269
 
269
270
  # The passed <tt>filters</tt> will be prepended to the array of filters
270
271
  # that run _after_ actions on this controller are performed.
271
272
  def prepend_after_filter(*filters, &block)
272
- append_filter_to_chain(filters, :after, &block)
273
+ prepend_filter_to_chain(filters, :after, &block)
273
274
  end
274
275
 
275
276
  # Shorthand for append_after_filter since it's the most common.
@@ -362,12 +363,12 @@ module ActionController #:nodoc:
362
363
 
363
364
  # Returns a mapping between filters and the actions that may run them.
364
365
  def included_actions #:nodoc:
365
- read_inheritable_attribute("included_actions") || {}
366
+ @included_actions ||= read_inheritable_attribute("included_actions") || {}
366
367
  end
367
368
 
368
369
  # Returns a mapping between filters and actions that may not run them.
369
370
  def excluded_actions #:nodoc:
370
- read_inheritable_attribute("excluded_actions") || {}
371
+ @excluded_actions ||= read_inheritable_attribute("excluded_actions") || {}
371
372
  end
372
373
 
373
374
  # Find a filter in the filter_chain where the filter method matches the _filter_ param
@@ -381,10 +382,11 @@ module ActionController #:nodoc:
381
382
 
382
383
  # Returns true if the filter is excluded from the given action
383
384
  def filter_excluded_from_action?(filter,action) #:nodoc:
384
- if (ia = included_actions[filter]) && !ia.empty?
385
+ case
386
+ when ia = included_actions[filter]
385
387
  !ia.include?(action)
386
- else
387
- (excluded_actions[filter] || []).include?(action)
388
+ when ea = excluded_actions[filter]
389
+ ea.include?(action)
388
390
  end
389
391
  end
390
392
 
@@ -397,20 +399,28 @@ module ActionController #:nodoc:
397
399
  @filter = filter
398
400
  end
399
401
 
402
+ def type
403
+ :around
404
+ end
405
+
400
406
  def before?
401
- false
407
+ type == :before
402
408
  end
403
409
 
404
410
  def after?
405
- false
411
+ type == :after
406
412
  end
407
413
 
408
414
  def around?
409
- true
415
+ type == :around
416
+ end
417
+
418
+ def run(controller)
419
+ raise ActionControllerError, 'No filter type: Nothing to do here.'
410
420
  end
411
421
 
412
422
  def call(controller, &block)
413
- raise(ActionControllerError, 'No filter type: Nothing to do here.')
423
+ run(controller)
414
424
  end
415
425
  end
416
426
 
@@ -420,35 +430,38 @@ module ActionController #:nodoc:
420
430
  def filter
421
431
  @filter.filter
422
432
  end
423
-
424
- def around?
425
- false
426
- end
427
433
  end
428
434
 
429
435
  class BeforeFilterProxy < FilterProxy #:nodoc:
430
- def before?
431
- true
436
+ def type
437
+ :before
432
438
  end
433
439
 
434
- def call(controller, &block)
435
- if false == @filter.call(controller) # must only stop if equal to false. only filters returning false are halted.
436
- controller.halt_filter_chain(@filter, :returned_false)
437
- else
438
- yield
440
+ def run(controller)
441
+ # only filters returning false are halted.
442
+ if false == @filter.call(controller)
443
+ controller.send :halt_filter_chain, @filter, :returned_false
439
444
  end
440
445
  end
446
+
447
+ def call(controller)
448
+ yield unless run(controller)
449
+ end
441
450
  end
442
451
 
443
452
  class AfterFilterProxy < FilterProxy #:nodoc:
444
- def after?
445
- true
453
+ def type
454
+ :after
446
455
  end
447
456
 
448
- def call(controller, &block)
449
- yield
457
+ def run(controller)
450
458
  @filter.call(controller)
451
459
  end
460
+
461
+ def call(controller)
462
+ yield
463
+ run(controller)
464
+ end
452
465
  end
453
466
 
454
467
  class SymbolFilter < Filter #:nodoc:
@@ -485,29 +498,72 @@ module ActionController #:nodoc:
485
498
  end
486
499
  end
487
500
 
501
+ class ClassBeforeFilter < Filter #:nodoc:
502
+ def call(controller, &block)
503
+ @filter.before(controller)
504
+ end
505
+ end
506
+
507
+ class ClassAfterFilter < Filter #:nodoc:
508
+ def call(controller, &block)
509
+ @filter.after(controller)
510
+ end
511
+ end
512
+
488
513
  protected
489
- def append_filter_to_chain(filters, position = :around, &block)
490
- write_inheritable_array('filter_chain', create_filters(filters, position, &block) )
514
+ def append_filter_to_chain(filters, filter_type = :around, &block)
515
+ pos = find_filter_append_position(filters, filter_type)
516
+ update_filter_chain(filters, filter_type, pos, &block)
491
517
  end
492
518
 
493
- def prepend_filter_to_chain(filters, position = :around, &block)
494
- write_inheritable_attribute('filter_chain', create_filters(filters, position, &block) + filter_chain)
519
+ def prepend_filter_to_chain(filters, filter_type = :around, &block)
520
+ pos = find_filter_prepend_position(filters, filter_type)
521
+ update_filter_chain(filters, filter_type, pos, &block)
495
522
  end
496
523
 
497
- def create_filters(filters, position, &block) #:nodoc:
524
+ def update_filter_chain(filters, filter_type, pos, &block)
525
+ new_filters = create_filters(filters, filter_type, &block)
526
+ new_chain = filter_chain.insert(pos, new_filters).flatten
527
+ write_inheritable_attribute('filter_chain', new_chain)
528
+ end
529
+
530
+ def find_filter_append_position(filters, filter_type)
531
+ # appending an after filter puts it at the end of the call chain
532
+ # before and around filters go before the first after filter in the chain
533
+ unless filter_type == :after
534
+ filter_chain.each_with_index do |f,i|
535
+ return i if f.after?
536
+ end
537
+ end
538
+ return -1
539
+ end
540
+
541
+ def find_filter_prepend_position(filters, filter_type)
542
+ # prepending a before or around filter puts it at the front of the call chain
543
+ # after filters go before the first after filter in the chain
544
+ if filter_type == :after
545
+ filter_chain.each_with_index do |f,i|
546
+ return i if f.after?
547
+ end
548
+ return -1
549
+ end
550
+ return 0
551
+ end
552
+
553
+ def create_filters(filters, filter_type, &block) #:nodoc:
498
554
  filters, conditions = extract_conditions(filters, &block)
499
- filters.map! { |filter| find_or_create_filter(filter,position) }
555
+ filters.map! { |filter| find_or_create_filter(filter, filter_type) }
500
556
  update_conditions(filters, conditions)
501
557
  filters
502
558
  end
503
559
 
504
- def find_or_create_filter(filter,position)
505
- if found_filter = find_filter(filter) { |f| f.send("#{position}?") }
560
+ def find_or_create_filter(filter, filter_type)
561
+ if found_filter = find_filter(filter) { |f| f.type == filter_type }
506
562
  found_filter
507
563
  else
508
- f = class_for_filter(filter).new(filter)
564
+ f = class_for_filter(filter, filter_type).new(filter)
509
565
  # apply proxy to filter if necessary
510
- case position
566
+ case filter_type
511
567
  when :before
512
568
  BeforeFilterProxy.new(f)
513
569
  when :after
@@ -520,7 +576,7 @@ module ActionController #:nodoc:
520
576
 
521
577
  # The determination of the filter type was once done at run time.
522
578
  # This method is here to extract as much logic from the filter run time as possible
523
- def class_for_filter(filter) #:nodoc:
579
+ def class_for_filter(filter, filter_type) #:nodoc:
524
580
  case
525
581
  when filter.is_a?(Symbol)
526
582
  SymbolFilter
@@ -534,8 +590,12 @@ module ActionController #:nodoc:
534
590
  end
535
591
  when filter.respond_to?(:filter)
536
592
  ClassFilter
593
+ when filter.respond_to?(:before) && filter_type == :before
594
+ ClassBeforeFilter
595
+ when filter.respond_to?(:after) && filter_type == :after
596
+ ClassAfterFilter
537
597
  else
538
- raise(ActionControllerError, 'A filters must be a Symbol, Proc, Method, or object responding to filter.')
598
+ raise(ActionControllerError, 'A filter must be a Symbol, Proc, Method, or object responding to filter, after or before.')
539
599
  end
540
600
  end
541
601
 
@@ -550,8 +610,8 @@ module ActionController #:nodoc:
550
610
  return if conditions.empty?
551
611
  if conditions[:only]
552
612
  write_inheritable_hash('included_actions', condition_hash(filters, conditions[:only]))
553
- else
554
- write_inheritable_hash('excluded_actions', condition_hash(filters, conditions[:except])) if conditions[:except]
613
+ elsif conditions[:except]
614
+ write_inheritable_hash('excluded_actions', condition_hash(filters, conditions[:except]))
555
615
  end
556
616
  end
557
617
 
@@ -576,9 +636,9 @@ module ActionController #:nodoc:
576
636
 
577
637
  def remove_actions_from_included_actions!(filters,*actions)
578
638
  actions = actions.flatten.map(&:to_s)
579
- updated_hash = filters.inject(included_actions) do |hash,filter|
639
+ updated_hash = filters.inject(read_inheritable_attribute('included_actions')||{}) do |hash,filter|
580
640
  ia = (hash[filter] || []) - actions
581
- ia.blank? ? hash.delete(filter) : hash[filter] = ia
641
+ ia.empty? ? hash.delete(filter) : hash[filter] = ia
582
642
  hash
583
643
  end
584
644
  write_inheritable_attribute('included_actions', updated_hash)
@@ -595,7 +655,9 @@ module ActionController #:nodoc:
595
655
  def proxy_before_and_after_filter(filter) #:nodoc:
596
656
  return filter unless filter_responds_to_before_and_after(filter)
597
657
  Proc.new do |controller, action|
598
- unless filter.before(controller) == false
658
+ if filter.before(controller) == false
659
+ controller.send :halt_filter_chain, filter, :returned_false
660
+ else
599
661
  begin
600
662
  action.call
601
663
  ensure
@@ -615,53 +677,90 @@ module ActionController #:nodoc:
615
677
  end
616
678
  end
617
679
 
618
- def perform_action_with_filters
619
- call_filter(self.class.filter_chain, 0)
620
- end
680
+ protected
621
681
 
622
682
  def process_with_filters(request, response, method = :perform_action, *arguments) #:nodoc:
623
683
  @before_filter_chain_aborted = false
624
684
  process_without_filters(request, response, method, *arguments)
625
685
  end
626
686
 
627
- def filter_chain
628
- self.class.filter_chain
687
+ def perform_action_with_filters
688
+ call_filters(self.class.filter_chain, 0, 0)
629
689
  end
630
690
 
631
- def call_filter(chain, index)
632
- return (performed? || perform_action_without_filters) if index >= chain.size
633
- filter = chain[index]
634
- return call_filter(chain, index.next) if self.class.filter_excluded_from_action?(filter,action_name)
691
+ private
635
692
 
636
- halted = false
637
- filter.call(self) do
638
- halted = call_filter(chain, index.next)
693
+ def call_filters(chain, index, nesting)
694
+ index = run_before_filters(chain, index, nesting)
695
+ aborted = @before_filter_chain_aborted
696
+ perform_action_without_filters unless performed? || aborted
697
+ return index if nesting != 0 || aborted
698
+ run_after_filters(chain, index)
699
+ end
700
+
701
+ def skip_excluded_filters(chain, index)
702
+ while (filter = chain[index]) && self.class.filter_excluded_from_action?(filter, action_name)
703
+ index = index.next
639
704
  end
640
- halt_filter_chain(filter.filter, :no_yield) if halted == false unless @before_filter_chain_aborted
641
- halted
705
+ [filter, index]
642
706
  end
643
707
 
644
- def halt_filter_chain(filter, reason)
645
- if logger
646
- case reason
647
- when :no_yield
648
- logger.info "Filter chain halted as [#{filter.inspect}] did not yield."
649
- when :returned_false
650
- logger.info "Filter chain halted as [#{filter.inspect}] returned false."
708
+ def run_before_filters(chain, index, nesting)
709
+ while chain[index]
710
+ filter, index = skip_excluded_filters(chain, index)
711
+ break unless filter # end of call chain reached
712
+ case filter.type
713
+ when :before
714
+ filter.run(self) # invoke before filter
715
+ index = index.next
716
+ break if @before_filter_chain_aborted
717
+ when :around
718
+ yielded = false
719
+ filter.call(self) do
720
+ yielded = true
721
+ # all remaining before and around filters will be run in this call
722
+ index = call_filters(chain, index.next, nesting.next)
723
+ end
724
+ halt_filter_chain(filter, :did_not_yield) unless yielded
725
+ break
726
+ else
727
+ break # no before or around filters left
651
728
  end
652
729
  end
653
- @before_filter_chain_aborted = true
654
- return false
730
+ index
655
731
  end
656
732
 
657
- private
658
- def process_cleanup_with_filters
659
- if @before_filter_chain_aborted
660
- close_session
733
+ def run_after_filters(chain, index)
734
+ seen_after_filter = false
735
+ while chain[index]
736
+ filter, index = skip_excluded_filters(chain, index)
737
+ break unless filter # end of call chain reached
738
+ case filter.type
739
+ when :after
740
+ seen_after_filter = true
741
+ filter.run(self) # invoke after filter
661
742
  else
662
- process_cleanup_without_filters
743
+ # implementation error or someone has mucked with the filter chain
744
+ raise ActionControllerError, "filter #{filter.inspect} was in the wrong place!" if seen_after_filter
663
745
  end
746
+ index = index.next
747
+ end
748
+ index.next
749
+ end
750
+
751
+ def halt_filter_chain(filter, reason)
752
+ @before_filter_chain_aborted = true
753
+ logger.info "Filter chain halted as [#{filter.inspect}] #{reason}." if logger
754
+ false
755
+ end
756
+
757
+ def process_cleanup_with_filters
758
+ if @before_filter_chain_aborted
759
+ close_session
760
+ else
761
+ process_cleanup_without_filters
664
762
  end
763
+ end
665
764
  end
666
765
  end
667
766
  end
@@ -67,7 +67,7 @@ module ActionController
67
67
  @https = false
68
68
  @cookies = {}
69
69
  @controller = @request = @response = nil
70
-
70
+
71
71
  self.host = "www.example.com"
72
72
  self.remote_addr = "127.0.0.1"
73
73
  self.accept = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
@@ -89,7 +89,7 @@ module ActionController
89
89
  # session.https!
90
90
  # session.https!(false)
91
91
  def https!(flag=true)
92
- @https = flag
92
+ @https = flag
93
93
  end
94
94
 
95
95
  # Return +true+ if the session is mimicing a secure HTTPS request.
@@ -143,10 +143,10 @@ module ActionController
143
143
  # Performs a GET request with the given parameters. The parameters may
144
144
  # be +nil+, a Hash, or a string that is appropriately encoded
145
145
  # (application/x-www-form-urlencoded or multipart/form-data). The headers
146
- # should be a hash. The keys will automatically be upcased, with the
146
+ # should be a hash. The keys will automatically be upcased, with the
147
147
  # prefix 'HTTP_' added if needed.
148
148
  #
149
- # You can also perform POST, PUT, DELETE, and HEAD requests with #post,
149
+ # You can also perform POST, PUT, DELETE, and HEAD requests with #post,
150
150
  # #put, #delete, and #head.
151
151
  def get(path, parameters=nil, headers=nil)
152
152
  process :get, path, parameters, headers
@@ -161,31 +161,41 @@ module ActionController
161
161
  def put(path, parameters=nil, headers=nil)
162
162
  process :put, path, parameters, headers
163
163
  end
164
-
164
+
165
165
  # Performs a DELETE request with the given parameters. See get() for more details.
166
166
  def delete(path, parameters=nil, headers=nil)
167
167
  process :delete, path, parameters, headers
168
168
  end
169
-
169
+
170
170
  # Performs a HEAD request with the given parameters. See get() for more details.
171
171
  def head(path, parameters=nil, headers=nil)
172
172
  process :head, path, parameters, headers
173
173
  end
174
174
 
175
- # Performs an XMLHttpRequest request with the given parameters, mimicing
176
- # the request environment created by the Prototype library. The parameters
177
- # may be +nil+, a Hash, or a string that is appropriately encoded
178
- # (application/x-www-form-urlencoded or multipart/form-data). The headers
179
- # should be a hash. The keys will automatically be upcased, with the
180
- # prefix 'HTTP_' added if needed.
181
- def xml_http_request(path, parameters=nil, headers=nil)
182
- headers = (headers || {}).merge(
183
- "X-Requested-With" => "XMLHttpRequest",
184
- "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
185
- )
175
+ # Performs an XMLHttpRequest request with the given parameters, mirroring
176
+ # a request from the Prototype library.
177
+ #
178
+ # The request_method is :get, :post, :put, :delete or :head; the
179
+ # parameters are +nil+, a hash, or a url-encoded or multipart string;
180
+ # the headers are a hash. Keys are automatically upcased and prefixed
181
+ # with 'HTTP_' if not already.
182
+ #
183
+ # This method used to omit the request_method parameter, assuming it
184
+ # was :post. This was deprecated in Rails 1.2.4. Always pass the request
185
+ # method as the first argument.
186
+ def xml_http_request(request_method, path, parameters = nil, headers = nil)
187
+ unless request_method.is_a?(Symbol)
188
+ ActiveSupport::Deprecation.warn 'xml_http_request now takes the request_method (:get, :post, etc.) as the first argument. It used to assume :post, so add the :post argument to your existing method calls to silence this warning.'
189
+ request_method, path, parameters, headers = :post, request_method, path, parameters
190
+ end
191
+
192
+ headers ||= {}
193
+ headers['X-Requested-With'] = 'XMLHttpRequest'
194
+ headers['Accept'] = 'text/javascript, text/html, application/xml, text/xml, */*'
186
195
 
187
- post(path, parameters, headers)
196
+ process(request_method, path, parameters, headers)
188
197
  end
198
+ alias xhr :xml_http_request
189
199
 
190
200
  # Returns the URL for the given options, according to the rules specified
191
201
  # in the application's routes.
@@ -292,7 +302,7 @@ module ActionController
292
302
  @status = @status.to_i
293
303
  end
294
304
 
295
- # Encode the cookies hash in a format suitable for passing to a
305
+ # Encode the cookies hash in a format suitable for passing to a
296
306
  # request.
297
307
  def encode_cookies
298
308
  cookies.inject("") do |string, (name, value)|
@@ -450,7 +460,7 @@ module ActionController
450
460
  # without any test methods.
451
461
  def run(*args) #:nodoc:
452
462
  return if @method_name == "default_test"
453
- super
463
+ super
454
464
  end
455
465
 
456
466
  # Because of how use_instantiated_fixtures and use_transactional_fixtures
@@ -490,7 +500,7 @@ module ActionController
490
500
  @integration_session = open_session
491
501
  end
492
502
 
493
- %w(get post cookies assigns xml_http_request).each do |method|
503
+ %w(get post put head delete cookies assigns xml_http_request).each do |method|
494
504
  define_method(method) do |*args|
495
505
  reset! unless @integration_session
496
506
  # reset the html_document variable, but only for new get/post calls