taweili-facebooker 1.0.37

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 (135) hide show
  1. data/.autotest +15 -0
  2. data/CHANGELOG.rdoc +24 -0
  3. data/COPYING.rdoc +19 -0
  4. data/Manifest.txt +133 -0
  5. data/README.rdoc +104 -0
  6. data/Rakefile +85 -0
  7. data/TODO.rdoc +4 -0
  8. data/examples/desktop_login.rb +14 -0
  9. data/facebooker.gemspec +38 -0
  10. data/generators/facebook/facebook_generator.rb +14 -0
  11. data/generators/facebook/templates/config/facebooker.yml +49 -0
  12. data/generators/facebook/templates/public/javascripts/facebooker.js +83 -0
  13. data/generators/facebook_controller/USAGE +33 -0
  14. data/generators/facebook_controller/facebook_controller_generator.rb +40 -0
  15. data/generators/facebook_controller/templates/controller.rb +7 -0
  16. data/generators/facebook_controller/templates/functional_test.rb +11 -0
  17. data/generators/facebook_controller/templates/helper.rb +2 -0
  18. data/generators/facebook_controller/templates/view.fbml.erb +2 -0
  19. data/generators/facebook_controller/templates/view.html.erb +2 -0
  20. data/generators/facebook_publisher/facebook_publisher_generator.rb +14 -0
  21. data/generators/facebook_publisher/templates/create_facebook_templates.rb +15 -0
  22. data/generators/facebook_publisher/templates/publisher.rb +3 -0
  23. data/generators/facebook_scaffold/USAGE +27 -0
  24. data/generators/facebook_scaffold/facebook_scaffold_generator.rb +118 -0
  25. data/generators/facebook_scaffold/templates/controller.rb +93 -0
  26. data/generators/facebook_scaffold/templates/facebook_style.css +2579 -0
  27. data/generators/facebook_scaffold/templates/functional_test.rb +89 -0
  28. data/generators/facebook_scaffold/templates/helper.rb +2 -0
  29. data/generators/facebook_scaffold/templates/layout.fbml.erb +6 -0
  30. data/generators/facebook_scaffold/templates/layout.html.erb +17 -0
  31. data/generators/facebook_scaffold/templates/style.css +74 -0
  32. data/generators/facebook_scaffold/templates/view_edit.fbml.erb +13 -0
  33. data/generators/facebook_scaffold/templates/view_edit.html.erb +18 -0
  34. data/generators/facebook_scaffold/templates/view_index.fbml.erb +24 -0
  35. data/generators/facebook_scaffold/templates/view_index.html.erb +24 -0
  36. data/generators/facebook_scaffold/templates/view_new.fbml.erb +12 -0
  37. data/generators/facebook_scaffold/templates/view_new.html.erb +17 -0
  38. data/generators/facebook_scaffold/templates/view_show.fbml.erb +10 -0
  39. data/generators/facebook_scaffold/templates/view_show.html.erb +10 -0
  40. data/generators/publisher/publisher_generator.rb +14 -0
  41. data/generators/xd_receiver/templates/xd_receiver.html +10 -0
  42. data/generators/xd_receiver/xd_receiver_generator.rb +10 -0
  43. data/init.rb +25 -0
  44. data/install.rb +12 -0
  45. data/lib/facebooker/adapters/adapter_base.rb +91 -0
  46. data/lib/facebooker/adapters/bebo_adapter.rb +77 -0
  47. data/lib/facebooker/adapters/facebook_adapter.rb +52 -0
  48. data/lib/facebooker/admin.rb +42 -0
  49. data/lib/facebooker/batch_request.rb +45 -0
  50. data/lib/facebooker/data.rb +57 -0
  51. data/lib/facebooker/feed.rb +78 -0
  52. data/lib/facebooker/logging.rb +44 -0
  53. data/lib/facebooker/mobile.rb +20 -0
  54. data/lib/facebooker/mock/service.rb +50 -0
  55. data/lib/facebooker/mock/session.rb +18 -0
  56. data/lib/facebooker/model.rb +139 -0
  57. data/lib/facebooker/models/affiliation.rb +10 -0
  58. data/lib/facebooker/models/album.rb +11 -0
  59. data/lib/facebooker/models/applicationproperties.rb +39 -0
  60. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  61. data/lib/facebooker/models/cookie.rb +10 -0
  62. data/lib/facebooker/models/education_info.rb +11 -0
  63. data/lib/facebooker/models/event.rb +28 -0
  64. data/lib/facebooker/models/friend_list.rb +16 -0
  65. data/lib/facebooker/models/group.rb +36 -0
  66. data/lib/facebooker/models/info_item.rb +10 -0
  67. data/lib/facebooker/models/info_section.rb +10 -0
  68. data/lib/facebooker/models/location.rb +8 -0
  69. data/lib/facebooker/models/notifications.rb +17 -0
  70. data/lib/facebooker/models/page.rb +28 -0
  71. data/lib/facebooker/models/photo.rb +19 -0
  72. data/lib/facebooker/models/tag.rb +12 -0
  73. data/lib/facebooker/models/user.rb +497 -0
  74. data/lib/facebooker/models/video.rb +9 -0
  75. data/lib/facebooker/models/work_info.rb +10 -0
  76. data/lib/facebooker/parser.rb +650 -0
  77. data/lib/facebooker/rails/backwards_compatible_param_checks.rb +31 -0
  78. data/lib/facebooker/rails/controller.rb +337 -0
  79. data/lib/facebooker/rails/cucumber/world.rb +46 -0
  80. data/lib/facebooker/rails/cucumber.rb +28 -0
  81. data/lib/facebooker/rails/extensions/action_controller.rb +48 -0
  82. data/lib/facebooker/rails/extensions/rack_setup.rb +6 -0
  83. data/lib/facebooker/rails/extensions/routing.rb +15 -0
  84. data/lib/facebooker/rails/facebook_form_builder.rb +112 -0
  85. data/lib/facebooker/rails/facebook_pretty_errors.rb +22 -0
  86. data/lib/facebooker/rails/facebook_request_fix.rb +30 -0
  87. data/lib/facebooker/rails/facebook_request_fix_2-3.rb +31 -0
  88. data/lib/facebooker/rails/facebook_session_handling.rb +68 -0
  89. data/lib/facebooker/rails/facebook_url_helper.rb +192 -0
  90. data/lib/facebooker/rails/facebook_url_rewriting.rb +60 -0
  91. data/lib/facebooker/rails/helpers/fb_connect.rb +118 -0
  92. data/lib/facebooker/rails/helpers.rb +780 -0
  93. data/lib/facebooker/rails/integration_session.rb +38 -0
  94. data/lib/facebooker/rails/profile_publisher_extensions.rb +42 -0
  95. data/lib/facebooker/rails/publisher.rb +554 -0
  96. data/lib/facebooker/rails/routing.rb +49 -0
  97. data/lib/facebooker/rails/test_helpers.rb +68 -0
  98. data/lib/facebooker/rails/utilities.rb +22 -0
  99. data/lib/facebooker/server_cache.rb +24 -0
  100. data/lib/facebooker/service.rb +102 -0
  101. data/lib/facebooker/session.rb +606 -0
  102. data/lib/facebooker/version.rb +9 -0
  103. data/lib/facebooker.rb +180 -0
  104. data/lib/net/http_multipart_post.rb +123 -0
  105. data/lib/rack/facebook.rb +77 -0
  106. data/lib/tasks/facebooker.rake +18 -0
  107. data/lib/tasks/tunnel.rake +46 -0
  108. data/rails/init.rb +1 -0
  109. data/setup.rb +1585 -0
  110. data/templates/layout.erb +24 -0
  111. data/test/facebooker/adapters_test.rb +96 -0
  112. data/test/facebooker/admin_test.rb +102 -0
  113. data/test/facebooker/batch_request_test.rb +83 -0
  114. data/test/facebooker/data_test.rb +86 -0
  115. data/test/facebooker/logging_test.rb +43 -0
  116. data/test/facebooker/mobile_test.rb +45 -0
  117. data/test/facebooker/model_test.rb +133 -0
  118. data/test/facebooker/models/event_test.rb +15 -0
  119. data/test/facebooker/models/photo_test.rb +16 -0
  120. data/test/facebooker/models/user_test.rb +343 -0
  121. data/test/facebooker/rails/facebook_request_fix_2-3_test.rb +24 -0
  122. data/test/facebooker/rails/facebook_url_rewriting_test.rb +39 -0
  123. data/test/facebooker/rails/publisher_test.rb +481 -0
  124. data/test/facebooker/rails_integration_test.rb +1398 -0
  125. data/test/facebooker/server_cache_test.rb +44 -0
  126. data/test/facebooker/session_test.rb +614 -0
  127. data/test/facebooker_test.rb +951 -0
  128. data/test/fixtures/multipart_post_body_with_only_parameters.txt +33 -0
  129. data/test/fixtures/multipart_post_body_with_single_file.txt +38 -0
  130. data/test/fixtures/multipart_post_body_with_single_file_that_has_nil_key.txt +38 -0
  131. data/test/net/http_multipart_post_test.rb +52 -0
  132. data/test/rack/facebook_test.rb +61 -0
  133. data/test/rails_test_helper.rb +27 -0
  134. data/test/test_helper.rb +74 -0
  135. metadata +232 -0
@@ -0,0 +1,337 @@
1
+ require 'facebooker'
2
+ require 'facebooker/rails/profile_publisher_extensions'
3
+ module Facebooker
4
+ module Rails
5
+ module Controller
6
+ include Facebooker::Rails::BackwardsCompatibleParamChecks
7
+ include Facebooker::Rails::ProfilePublisherExtensions
8
+ def self.included(controller)
9
+ controller.extend(ClassMethods)
10
+ controller.before_filter :set_adapter
11
+ controller.before_filter :set_facebook_request_format
12
+ controller.helper_attr :facebook_session_parameters
13
+ controller.helper_method :request_comes_from_facebook?
14
+ end
15
+
16
+ def initialize *args
17
+ @facebook_session = nil
18
+ @installation_required = nil
19
+ super
20
+ end
21
+
22
+ def facebook_session
23
+ @facebook_session
24
+ end
25
+
26
+ def facebook_session_parameters
27
+ {:fb_sig_session_key=>params[:fb_sig_session_key]}
28
+ end
29
+
30
+ def create_facebook_session
31
+ secure_with_facebook_params! || secure_with_cookies! || secure_with_token!
32
+ end
33
+
34
+ def set_facebook_session
35
+ # first, see if we already have a session
36
+ session_set = session_already_secured?
37
+ # if not, see if we can load it from the environment
38
+ unless session_set
39
+ session_set = create_facebook_session
40
+ session[:facebook_session] = @facebook_session if session_set
41
+ end
42
+ if session_set
43
+ capture_facebook_friends_if_available!
44
+ Session.current = facebook_session
45
+ end
46
+ return session_set
47
+ end
48
+
49
+
50
+ def facebook_params
51
+ @facebook_params ||= verified_facebook_params
52
+ end
53
+
54
+ # Redirects the top window to the given url if the content is in an iframe, otherwise performs
55
+ # a normal redirect_to call.
56
+ def top_redirect_to(*args)
57
+ if request_is_facebook_iframe?
58
+ @redirect_url = url_for(*args)
59
+ render :layout => false, :inline => <<-HTML
60
+ <html><head>
61
+ <script type="text/javascript">
62
+ window.top.location.href = <%= @redirect_url.to_json -%>;
63
+ </script>
64
+ <noscript>
65
+ <meta http-equiv="refresh" content="0;url=<%=h @redirect_url %>" />
66
+ <meta http-equiv="window-target" content="_top" />
67
+ </noscript>
68
+ </head></html>
69
+ HTML
70
+ else
71
+ redirect_to(*args)
72
+ end
73
+ end
74
+
75
+ def redirect_to(*args)
76
+ if request_is_for_a_facebook_canvas? and !request_is_facebook_tab?
77
+ render :text => fbml_redirect_tag(*args)
78
+ else
79
+ super
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def session_already_secured?
86
+ (@facebook_session = session[:facebook_session]) && session[:facebook_session].secured? if valid_session_key_in_session?
87
+ end
88
+
89
+ def user_has_deauthorized_application?
90
+ # if we're inside the facebook session and there is no session key,
91
+ # that means the user revoked our access
92
+ # we don't want to keep using the old expired key from the cookie.
93
+ request_comes_from_facebook? and params[:fb_sig_session_key].blank?
94
+ end
95
+
96
+ def clear_facebook_session_information
97
+ session[:facebook_session] = nil
98
+ @facebook_session=nil
99
+ end
100
+
101
+ def valid_session_key_in_session?
102
+ #before we access the facebook_params, make sure we have the parameters
103
+ #otherwise we will blow up trying to access the secure parameters
104
+ if user_has_deauthorized_application?
105
+ clear_facebook_session_information
106
+ false
107
+ else
108
+ !session[:facebook_session].blank? && (params[:fb_sig_session_key].blank? || session[:facebook_session].session_key == facebook_params[:session_key])
109
+ end
110
+ end
111
+
112
+ def clear_fb_cookies!
113
+ domain_cookie_tag = "base_domain_#{Facebooker.api_key}"
114
+ cookie_domain = ".#{cookies[domain_cookie_tag]}" if cookies[domain_cookie_tag]
115
+ fb_cookie_names.each {|name| cookies.delete(name, :domain=>cookie_domain)}
116
+ cookies.delete Facebooker.api_key
117
+ end
118
+
119
+ def fb_cookie_prefix
120
+ Facebooker.api_key+"_"
121
+ end
122
+
123
+ def fb_cookie_names
124
+ fb_cookie_names = cookies.keys.select{|k| k.starts_with?(fb_cookie_prefix)}
125
+ end
126
+
127
+ def secure_with_cookies!
128
+ parsed = {}
129
+
130
+ fb_cookie_names.each { |key| parsed[key[fb_cookie_prefix.size,key.size]] = cookies[key] }
131
+
132
+ #returning gracefully if the cookies aren't set or have expired
133
+ return unless parsed['session_key'] && parsed['user'] && parsed['expires'] && parsed['ss']
134
+ return unless Time.at(parsed['expires'].to_s.to_f) > Time.now || (parsed['expires'] == "0")
135
+ #if we have the unexpired cookies, we'll throw an exception if the sig doesn't verify
136
+ verify_signature(parsed,cookies[Facebooker.api_key])
137
+
138
+ @facebook_session = new_facebook_session
139
+ @facebook_session.secure_with!(parsed['session_key'],parsed['user'],parsed['expires'],parsed['ss'])
140
+ @facebook_session
141
+ end
142
+
143
+ def secure_with_token!
144
+ if params['auth_token']
145
+ @facebook_session = new_facebook_session
146
+ @facebook_session.auth_token = params['auth_token']
147
+ @facebook_session.secure!
148
+ @facebook_session
149
+ end
150
+ end
151
+
152
+ def secure_with_facebook_params!
153
+ return unless request_comes_from_facebook?
154
+
155
+ if ['user', 'session_key'].all? {|element| facebook_params[element]}
156
+ @facebook_session = new_facebook_session
157
+ @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
158
+ @facebook_session
159
+ end
160
+ end
161
+
162
+ #override to specify where the user should be sent after logging in
163
+ def after_facebook_login_url
164
+ nil
165
+ end
166
+
167
+ def create_new_facebook_session_and_redirect!
168
+ session[:facebook_session] = new_facebook_session
169
+ url_params = after_facebook_login_url.nil? ? {} : {:next=>after_facebook_login_url}
170
+ top_redirect_to session[:facebook_session].login_url(url_params) unless @installation_required
171
+ false
172
+ end
173
+
174
+ def new_facebook_session
175
+ Facebooker::Session.create(Facebooker.api_key, Facebooker.secret_key)
176
+ end
177
+
178
+ def capture_facebook_friends_if_available!
179
+ return unless request_comes_from_facebook?
180
+ if friends = facebook_params['friends']
181
+ facebook_session.user.friends = friends.map do |friend_uid|
182
+ User.new(friend_uid, facebook_session)
183
+ end
184
+ end
185
+ end
186
+
187
+ def blank?(value)
188
+ (value == '0' || value.nil? || value == '')
189
+ end
190
+
191
+ def verified_facebook_params
192
+ facebook_sig_params = params.inject({}) do |collection, pair|
193
+ collection[pair.first.sub(/^fb_sig_/, '')] = pair.last if pair.first[0,7] == 'fb_sig_'
194
+ collection
195
+ end
196
+ verify_signature(facebook_sig_params,params['fb_sig'])
197
+
198
+ facebook_sig_params.inject(HashWithIndifferentAccess.new) do |collection, pair|
199
+ collection[pair.first] = facebook_parameter_conversions[pair.first].call(pair.last)
200
+ collection
201
+ end
202
+ end
203
+
204
+ def earliest_valid_session
205
+ 48.hours.ago
206
+ end
207
+
208
+ def verify_signature(facebook_sig_params,expected_signature)
209
+ # Don't verify the signature if rack has already done so.
210
+ if ::Rails.version >= "2.3"
211
+ return if ActionController::Dispatcher.middleware.include? Rack::Facebook
212
+ end
213
+ raw_string = facebook_sig_params.map{ |*args| args.join('=') }.sort.join
214
+ actual_sig = Digest::MD5.hexdigest([raw_string, Facebooker::Session.secret_key].join)
215
+ raise Facebooker::Session::IncorrectSignature if actual_sig != expected_signature
216
+ raise Facebooker::Session::SignatureTooOld if facebook_sig_params['time'] && Time.at(facebook_sig_params['time'].to_f) < earliest_valid_session
217
+ true
218
+ end
219
+
220
+ def facebook_parameter_conversions
221
+ @facebook_parameter_conversions ||= Hash.new do |hash, key|
222
+ lambda{|value| value}
223
+ end.merge(
224
+ 'time' => lambda{|value| Time.at(value.to_f)},
225
+ 'in_canvas' => lambda{|value| !blank?(value)},
226
+ 'added' => lambda{|value| !blank?(value)},
227
+ 'expires' => lambda{|value| blank?(value) ? nil : Time.at(value.to_f)},
228
+ 'friends' => lambda{|value| value.split(/,/)}
229
+ )
230
+ end
231
+
232
+ def fbml_redirect_tag(url)
233
+ "<fb:redirect url=\"#{url_for(url)}\" />"
234
+ end
235
+
236
+ def request_comes_from_facebook?
237
+ request_is_for_a_facebook_canvas? || request_is_facebook_ajax? || request_is_fb_ping?
238
+ end
239
+
240
+ def request_is_fb_ping?
241
+ !params['fb_sig'].blank?
242
+ end
243
+
244
+ def request_is_for_a_facebook_canvas?
245
+ !params['fb_sig_in_canvas'].blank?
246
+ end
247
+
248
+ def request_is_facebook_tab?
249
+ !params["fb_sig_in_profile_tab"].blank?
250
+ end
251
+
252
+ def request_is_facebook_iframe?
253
+ !params["fb_sig_in_iframe"].blank?
254
+ end
255
+
256
+ def request_is_facebook_ajax?
257
+ one_or_true(params["fb_sig_is_mockajax"]) || one_or_true(params["fb_sig_is_ajax"])
258
+ end
259
+
260
+ def xml_http_request?
261
+ request_is_facebook_ajax? || super
262
+ end
263
+
264
+ def application_is_installed?
265
+ facebook_params['added']
266
+ end
267
+
268
+ def ensure_has_status_update
269
+ has_extended_permission?("status_update") || application_needs_permission("status_update")
270
+ end
271
+ def ensure_has_photo_upload
272
+ has_extended_permission?("photo_upload") || application_needs_permission("photo_upload")
273
+ end
274
+ def ensure_has_video_upload
275
+ has_extended_permission?("video_upload") || application_needs_permission("video_upload")
276
+ end
277
+ def ensure_has_create_listing
278
+ has_extended_permission?("create_listing") || application_needs_permission("create_listing")
279
+ end
280
+
281
+ def application_needs_permission(perm)
282
+ top_redirect_to(facebook_session.permission_url(perm))
283
+ end
284
+
285
+ def has_extended_permission?(perm)
286
+ params["fb_sig_ext_perms"] and params["fb_sig_ext_perms"].include?(perm)
287
+ end
288
+
289
+ def ensure_authenticated_to_facebook
290
+ set_facebook_session || create_new_facebook_session_and_redirect!
291
+ end
292
+
293
+ def ensure_application_is_installed_by_facebook_user
294
+ @installation_required = true
295
+ returning ensure_authenticated_to_facebook && application_is_installed? do |authenticated_and_installed|
296
+ application_is_not_installed_by_facebook_user unless authenticated_and_installed
297
+ end
298
+ end
299
+
300
+ def application_is_not_installed_by_facebook_user
301
+ url_params = after_facebook_login_url.nil? ? {} : { :next => after_facebook_login_url }
302
+ top_redirect_to session[:facebook_session].install_url(url_params)
303
+ end
304
+
305
+ def set_facebook_request_format
306
+ if request_is_facebook_ajax?
307
+ request.format = :fbjs
308
+ elsif request_comes_from_facebook? && !request_is_facebook_iframe?
309
+ request.format = :fbml
310
+ end
311
+ end
312
+
313
+ def set_adapter
314
+ Facebooker.load_adapter(params) if(params[:fb_sig_api_key])
315
+ end
316
+
317
+
318
+ module ClassMethods
319
+ #
320
+ # Creates a filter which reqires a user to have already authenticated to
321
+ # Facebook before executing actions. Accepts the same optional options hash which
322
+ # before_filter and after_filter accept.
323
+ def ensure_authenticated_to_facebook(options = {})
324
+ before_filter :ensure_authenticated_to_facebook, options
325
+ end
326
+
327
+ def ensure_application_is_installed_by_facebook_user(options = {})
328
+ before_filter :ensure_application_is_installed_by_facebook_user, options
329
+ end
330
+
331
+ def request_comes_from_facebook?
332
+ request_is_for_a_facebook_canvas? || request_is_facebook_ajax?
333
+ end
334
+ end
335
+ end
336
+ end
337
+ end
@@ -0,0 +1,46 @@
1
+ require 'cucumber/rails/world'
2
+ require 'facebooker/rails/integration_session'
3
+
4
+ module Facebooker
5
+ module Rails
6
+ module Cucumber
7
+ class World < ::Cucumber::Rails::World
8
+ def open_session
9
+ session = Facebooker::Rails::IntegrationSession.new
10
+
11
+ # delegate the fixture accessors back to the test instance
12
+ extras = Module.new { attr_accessor :delegate, :test_result }
13
+ if self.class.respond_to?(:fixture_table_names)
14
+ self.class.fixture_table_names.each do |table_name|
15
+ name = table_name.tr(".", "_")
16
+ next unless respond_to?(name)
17
+ extras.__send__(:define_method, name) { |*args| delegate.send(name, *args) }
18
+ end
19
+ end
20
+
21
+ # delegate add_assertion to the test case
22
+ extras.__send__(:define_method, :add_assertion) { test_result.add_assertion }
23
+ session.extend(extras)
24
+ session.delegate = self
25
+ session.test_result = @_result
26
+
27
+ yield session if block_given?
28
+ session
29
+ end
30
+
31
+ def without_canvas
32
+ in_canvas = @integration_session.canvas
33
+ @integration_session.canvas = false
34
+ yield
35
+ @integration_session.canvas = in_canvas
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ World do
43
+ w = Facebooker::Rails::Cucumber::World.new
44
+ w.reset!
45
+ w
46
+ end
@@ -0,0 +1,28 @@
1
+ require 'facebooker/rails/cucumber/world'
2
+ require 'facebooker/mock/session'
3
+ require 'facebooker/mock/service'
4
+
5
+ Facebooker::MockService.fixture_path = File.join(RAILS_ROOT, 'features', 'support', 'facebook')
6
+
7
+ module Facebooker
8
+ class << self
9
+ # prevent Facebooker from adding canvas name as prefix to URLs
10
+ def request_for_canvas(arg)
11
+ yield
12
+ end
13
+ end
14
+
15
+ module Rails
16
+ module Controller
17
+ # prevent Facebooker from rendering fb:redirect
18
+ def redirect_to(*args)
19
+ super
20
+ end
21
+
22
+ # Return the mock session
23
+ def new_facebook_session
24
+ Facebooker::MockSession.create
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ module ::ActionController
2
+ class Base
3
+ def self.inherited_with_facebooker(subclass)
4
+ inherited_without_facebooker(subclass)
5
+ if subclass.to_s == "ApplicationController"
6
+ subclass.send(:include,Facebooker::Rails::Controller)
7
+ subclass.helper Facebooker::Rails::Helpers
8
+ end
9
+ end
10
+ class << self
11
+ alias_method_chain :inherited, :facebooker
12
+ end
13
+ end
14
+ end
15
+
16
+
17
+ # When making get requests, Facebook sends fb_sig parameters both in the query string
18
+ # and also in the post body. We want to ignore the query string ones because they are one
19
+ # request out of date
20
+ # We only do thise when there are POST parameters so that IFrame linkage still works
21
+ if Rails.version < '2.3'
22
+ class ActionController::AbstractRequest
23
+ def query_parameters_with_facebooker
24
+ if request_parameters.blank?
25
+ query_parameters_without_facebooker
26
+ else
27
+ (query_parameters_without_facebooker||{}).reject {|key,value| key.to_s =~ /^fb_sig/}
28
+ end
29
+ end
30
+
31
+ alias_method_chain :query_parameters, :facebooker
32
+ end
33
+ else
34
+ class ActionController::Request
35
+ def query_parameters_with_facebooker
36
+ if request_parameters.blank?
37
+ query_parameters_without_facebooker
38
+ else
39
+ (query_parameters_without_facebooker||{}).reject {|key,value| key.to_s =~ /^fb_sig/}
40
+ end
41
+ end
42
+
43
+ alias_method_chain :query_parameters, :facebooker
44
+ end
45
+ end
46
+
47
+ Mime::Type.register_alias "text/html", :fbml
48
+ Mime::Type.register_alias "text/javascript", :fbjs
@@ -0,0 +1,6 @@
1
+ # Somewhere in 2.3 RewindableInput was removed- rack supports it natively
2
+ require 'rack/facebook'
3
+ ActionController::Dispatcher.middleware.insert_before(
4
+ ActionController::ParamsParser,
5
+ Rack::Facebook,
6
+ Facebooker.secret_key )
@@ -0,0 +1,15 @@
1
+ class ActionController::Routing::Route
2
+ def recognition_conditions_with_facebooker
3
+ defaults = recognition_conditions_without_facebooker
4
+ defaults << " env[:canvas] == conditions[:canvas] " if conditions[:canvas]
5
+ defaults
6
+ end
7
+ alias_method_chain :recognition_conditions, :facebooker
8
+ end
9
+
10
+ # We turn off route optimization to make named routes use our code for figuring out if they should go to the session
11
+ ActionController::Base::optimise_named_routes = false
12
+
13
+ # pull :canvas=> into env in routing to allow for conditions
14
+ ActionController::Routing::RouteSet.send :include, Facebooker::Rails::Routing::RouteSetExtensions
15
+ ActionController::Routing::RouteSet::Mapper.send :include, Facebooker::Rails::Routing::MapperExtensions
@@ -0,0 +1,112 @@
1
+ module Facebooker
2
+ module Rails
3
+ class FacebookFormBuilder < ActionView::Helpers::FormBuilder
4
+
5
+
6
+ second_param = %w(password_field file_field check_box date_select datetime_select time_select)
7
+ third_param = %w(radio_button country_select select time_zone_select)
8
+ fifth_param = %w(collection_select)
9
+
10
+ def self.create_with_offset(name,offset)
11
+ define_method name do |field,*args|
12
+ options = args[offset] || {}
13
+ build_shell(field,options) do
14
+ super
15
+ end
16
+ end
17
+ end
18
+
19
+ second_param.each do |name|
20
+ create_with_offset(name,0)
21
+ end
22
+ third_param.each do |name|
23
+ create_with_offset(name,1)
24
+ end
25
+ fifth_param.each do |name|
26
+ create_with_offset(name,3)
27
+ end
28
+
29
+ def build_shell(field,options)
30
+ @template.content_tag "fb:editor-custom", :label=>label_for(field,options) do
31
+ yield
32
+ end
33
+ end
34
+
35
+ def label_for(field,options)
36
+ options[:label] || field.to_s.humanize
37
+ end
38
+
39
+ def text(string,options={})
40
+ @template.content_tag "fb:editor-custom",string, :label=>label_for("",options)
41
+ end
42
+
43
+
44
+ def text_field(method, options = {})
45
+ options[:label] ||= label_for(method,options)
46
+ add_default_name_and_id(options,method)
47
+ options["value"] ||= value_before_type_cast(object,method)
48
+ @template.content_tag("fb:editor-text","",options)
49
+ end
50
+
51
+
52
+ def text_area(method, options = {})
53
+ options[:label] ||= label_for(method,options)
54
+ add_default_name_and_id(options,method)
55
+ @template.content_tag("fb:editor-textarea",value_before_type_cast(object,method),options)
56
+ end
57
+
58
+ #
59
+ # Build a text input area that uses typeahed
60
+ # options are like collection_select
61
+ def collection_typeahead(method,collection,value_method,text_method,options={})
62
+ build_shell(method,options) do
63
+ collection_typeahead_internal(method,collection,value_method,text_method,options)
64
+ end
65
+ end
66
+
67
+ def collection_typeahead_internal(method,collection,value_method,text_method,options={})
68
+ option_values = collection.map do |item|
69
+ value=item.send(value_method)
70
+ text=item.send(text_method)
71
+ @template.content_tag "fb:typeahead-option",text,:value=>value
72
+ end.join
73
+ add_default_name_and_id(options,method)
74
+ options["value"] ||= value_before_type_cast(object,method)
75
+ @template.content_tag("fb:typeahead-input",option_values,options)
76
+ end
77
+
78
+ def value_before_type_cast(object,method)
79
+ unless object.nil?
80
+ method_name = method.to_s
81
+ object.respond_to?(method_name + "_before_type_cast") ?
82
+ object.send(method_name + "_before_type_cast") :
83
+ object.send(method_name)
84
+ end
85
+ end
86
+
87
+ def multi_friend_input(options={})
88
+ build_shell(:friends,options) do
89
+ @template.content_tag("fb:multi-friend-input","",options)
90
+ end
91
+ end
92
+
93
+ def buttons(*names)
94
+ buttons=names.map do |name|
95
+ create_button(name)
96
+ end.join
97
+
98
+ @template.content_tag "fb:editor-buttonset",buttons
99
+ end
100
+
101
+ def create_button(name)
102
+ @template.content_tag("fb:editor-button","",:value=>name,:name=>"commit")
103
+ end
104
+
105
+ def add_default_name_and_id(options,method)
106
+ options[:name] ||= "#{object.class.name.underscore}[#{method}]"
107
+ options[:id] ||= "#{object.class.name.underscore}_#{method}"
108
+ end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,22 @@
1
+ class ActionController::Base
2
+ def rescues_path_with_facebooker(template_name)
3
+ t = "#{RAILS_ROOT}/vendor/plugins/facebooker/templates/#{template_name}.erb"
4
+ if pretty_facebook_errors? && File.exist?(t)
5
+ t
6
+ else
7
+ rescues_path_without_facebooker(template_name)
8
+ end
9
+ end
10
+ alias_method_chain :rescues_path, :facebooker
11
+
12
+ def response_code_for_rescue_with_facebooker(exception)
13
+ pretty_facebook_errors? ? 200 : response_code_for_rescue_without_facebooker(exception)
14
+ end
15
+ alias_method_chain :response_code_for_rescue, :facebooker
16
+
17
+
18
+ def pretty_facebook_errors?
19
+ Facebooker.facebooker_config['pretty_errors'] ||
20
+ (Facebooker.facebooker_config['pretty_errors'].nil? && RAILS_ENV=="development")
21
+ end
22
+ end
@@ -0,0 +1,30 @@
1
+ module ::ActionController
2
+ class AbstractRequest
3
+ include Facebooker::Rails::BackwardsCompatibleParamChecks
4
+
5
+ def request_method_with_facebooker
6
+ if parameters[:_method].blank?
7
+ if %w{GET HEAD}.include?(parameters[:fb_sig_request_method])
8
+ parameters[:_method] = parameters[:fb_sig_request_method]
9
+ end
10
+ end
11
+ request_method_without_facebooker
12
+ end
13
+
14
+ if new.methods.include?("request_method")
15
+ alias_method_chain :request_method, :facebooker
16
+ end
17
+
18
+ def xml_http_request_with_facebooker?
19
+ one_or_true(parameters["fb_sig_is_mockajax"]) ||
20
+ one_or_true(parameters["fb_sig_is_ajax"]) ||
21
+ xml_http_request_without_facebooker?
22
+ end
23
+ alias_method_chain :xml_http_request?, :facebooker
24
+ # we have to re-alias xhr? since it was pointing to the old method
25
+ unless defined? :xhr?
26
+ alias xhr? :xml_http_request?
27
+ end
28
+
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module ::ActionController
2
+
3
+ class Request
4
+
5
+ include Facebooker::Rails::BackwardsCompatibleParamChecks
6
+
7
+ def request_method_with_facebooker
8
+ if parameters[:_method].blank?
9
+ if %w{GET HEAD}.include?(parameters[:fb_sig_request_method])
10
+ parameters[:_method] = parameters[:fb_sig_request_method]
11
+ end
12
+ end
13
+ request_method_without_facebooker
14
+ end
15
+
16
+ if new({}).methods.include?("request_method")
17
+ alias_method_chain :request_method, :facebooker
18
+ end
19
+
20
+ def xml_http_request_with_facebooker?
21
+ one_or_true(parameters["fb_sig_is_mockajax"]) ||
22
+ one_or_true(parameters["fb_sig_is_ajax"]) ||
23
+ xml_http_request_without_facebooker?
24
+ end
25
+ alias_method_chain :xml_http_request?, :facebooker
26
+
27
+ # we have to re-alias xhr? since it was pointing to the old method
28
+ alias xhr? :xml_http_request?
29
+
30
+ end
31
+ end