facebooker 1.0.13 → 1.0.18

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 (51) hide show
  1. data/Manifest.txt +29 -16
  2. data/Rakefile +9 -2
  3. data/generators/facebook/templates/public/javascripts/facebooker.js +1 -8
  4. data/init.rb +3 -1
  5. data/lib/facebooker.rb +4 -2
  6. data/lib/facebooker/adapters/facebook_adapter.rb +4 -0
  7. data/lib/facebooker/admin.rb +2 -2
  8. data/lib/facebooker/mobile.rb +20 -0
  9. data/lib/facebooker/mock/service.rb +50 -0
  10. data/lib/facebooker/mock/session.rb +18 -0
  11. data/lib/facebooker/model.rb +3 -3
  12. data/lib/facebooker/models/applicationrestrictions.rb +10 -0
  13. data/lib/facebooker/models/user.rb +35 -3
  14. data/lib/facebooker/models/user.rb.orig +396 -0
  15. data/lib/facebooker/models/user.rb.rej +17 -0
  16. data/lib/facebooker/models/video.rb +9 -0
  17. data/lib/facebooker/parser.rb +22 -1
  18. data/lib/facebooker/rails/controller.rb +34 -12
  19. data/lib/facebooker/rails/cucumber.rb +28 -0
  20. data/lib/facebooker/rails/cucumber/world.rb +46 -0
  21. data/lib/facebooker/rails/facebook_pretty_errors.rb +19 -11
  22. data/lib/facebooker/rails/helpers.rb +203 -122
  23. data/lib/facebooker/rails/helpers/fb_connect.rb +56 -5
  24. data/lib/facebooker/rails/integration_session.rb +38 -0
  25. data/lib/facebooker/rails/publisher.rb +15 -2
  26. data/lib/facebooker/rails/test_helpers.rb +11 -26
  27. data/lib/facebooker/service.rb +6 -3
  28. data/lib/facebooker/session.rb +24 -2
  29. data/lib/facebooker/session.rb.orig +564 -0
  30. data/lib/facebooker/session.rb.rej +29 -0
  31. data/lib/facebooker/version.rb +1 -1
  32. data/lib/tasks/tunnel.rake +2 -2
  33. data/test/{adapters_test.rb → facebooker/adapters_test.rb} +2 -4
  34. data/test/{facebook_admin_test.rb → facebooker/admin_test.rb} +2 -2
  35. data/test/{batch_request_test.rb → facebooker/batch_request_test.rb} +3 -2
  36. data/test/{facebook_data_test.rb → facebooker/data_test.rb} +2 -2
  37. data/test/{logging_test.rb → facebooker/logging_test.rb} +3 -3
  38. data/test/facebooker/mobile_test.rb +45 -0
  39. data/test/{model_test.rb → facebooker/model_test.rb} +36 -4
  40. data/test/{event_test.rb → facebooker/models/event_test.rb} +2 -2
  41. data/test/{user_test.rb → facebooker/models/user_test.rb} +10 -5
  42. data/test/{publisher_test.rb → facebooker/rails/publisher_test.rb} +12 -18
  43. data/test/{rails_integration_test.rb → facebooker/rails_integration_test.rb} +347 -272
  44. data/test/{facebook_cache_test.rb → facebooker/server_cache_test.rb} +1 -1
  45. data/test/{session_test.rb → facebooker/session_test.rb} +3 -2
  46. data/test/facebooker_test.rb +19 -1
  47. data/test/{http_multipart_post_test.rb → net/http_multipart_post_test.rb} +2 -4
  48. data/test/rails_test_helper.rb +11 -0
  49. data/test/test_helper.rb +8 -2
  50. metadata +45 -32
  51. data/lib/facebooker/rails/facebook_asset_path.rb +0 -18
@@ -0,0 +1,17 @@
1
+ ***************
2
+ *** 10,16 ****
3
+ include Model
4
+ attr_accessor :message, :time, :status_id
5
+ end
6
+ - FIELDS = [:status, :political, :pic_small, :name, :quotes, :is_app_user, :tv, :profile_update_time, :meeting_sex, :hs_info, :timezone, :relationship_status, :hometown_location, :about_me, :wall_count, :significant_other_id, :pic_big, :music, :uid, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email]
7
+ STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url]
8
+ attr_accessor :id, :session
9
+ populating_attr_accessor *FIELDS
10
+ --- 10,16 ----
11
+ include Model
12
+ attr_accessor :message, :time, :status_id
13
+ end
14
+ + FIELDS = [:status, :political, :pic_small, :name, :quotes, :is_app_user, :tv, :profile_update_time, :meeting_sex, :hs_info, :timezone, :relationship_status, :hometown_location, :about_me, :wall_count, :significant_other_id, :pic_big, :music, :uid, :work_history, :sex, :religion, :notes_count, :activities, :pic_square, :movies, :has_added_app, :education_history, :birthday, :first_name, :meeting_for, :last_name, :interests, :current_location, :pic, :books, :affiliations, :locale, :profile_url, :proxied_email, :email_hashes]
15
+ STANDARD_FIELDS = [:uid, :first_name, :last_name, :name, :timezone, :birthday, :sex, :affiliations, :locale, :profile_url]
16
+ attr_accessor :id, :session
17
+ populating_attr_accessor *FIELDS
@@ -0,0 +1,9 @@
1
+ require 'facebooker/model'
2
+ module Facebooker
3
+ class Video
4
+ include Model
5
+ attr_accessor :vid, :owner, :title,
6
+ :link, :description, :created,
7
+ :story_fbid
8
+ end
9
+ end
@@ -305,6 +305,12 @@ module Facebooker
305
305
  hashinate(element('photos_upload_response', data))
306
306
  end
307
307
  end
308
+
309
+ class UploadVideo < Parser#:nodoc:
310
+ def self.process(data)
311
+ hashinate(element('video_upload_response', data))
312
+ end
313
+ end
308
314
 
309
315
  class SendRequest < Parser#:nodoc:
310
316
  def self.process(data)
@@ -456,6 +462,18 @@ module Facebooker
456
462
  end
457
463
  end
458
464
 
465
+ class SmsSend < Parser#:nodoc:
466
+ def self.process(data)
467
+ element('sms_send_response', data).text_value == '0'
468
+ end
469
+ end
470
+
471
+ class SmsCanSend < Parser#:nodoc:
472
+ def self.process(data)
473
+ element('sms_canSend_response', data).text_value
474
+ end
475
+ end
476
+
459
477
  class Errors < Parser#:nodoc:
460
478
  EXCEPTIONS = {
461
479
  1 => Facebooker::Session::UnknownError,
@@ -562,7 +580,10 @@ module Facebooker
562
580
  'facebook.groups.getMembers' => GroupGetMembers,
563
581
  'facebook.notifications.sendEmail' => NotificationsSendEmail,
564
582
  'facebook.data.getUserPreference' => GetPreference,
565
- 'facebook.data.setUserPreference' => SetPreference
583
+ 'facebook.data.setUserPreference' => SetPreference,
584
+ 'facebook.video.upload' => UploadVideo,
585
+ 'facebook.sms.send' => SmsSend,
586
+ 'facebook.sms.canSend' => SmsCanSend
566
587
  }
567
588
  end
568
589
  end
@@ -6,8 +6,8 @@ module Facebooker
6
6
  include Facebooker::Rails::ProfilePublisherExtensions
7
7
  def self.included(controller)
8
8
  controller.extend(ClassMethods)
9
- controller.before_filter :set_adapter
10
- controller.before_filter :set_fbml_format
9
+ #controller.before_filter :set_adapter <-- security hole noted by vchu
10
+ controller.before_filter :set_facebook_request_format
11
11
  controller.helper_attr :facebook_session_parameters
12
12
  controller.helper_method :request_comes_from_facebook?
13
13
  end
@@ -21,16 +21,26 @@ module Facebooker
21
21
  {:fb_sig_session_key=>params[:fb_sig_session_key]}
22
22
  end
23
23
 
24
+ def create_facebook_session
25
+ secure_with_facebook_params! || secure_with_cookies! || secure_with_token!
26
+ end
24
27
 
25
28
  def set_facebook_session
26
- returning session_set = session_already_secured? || secure_with_facebook_params! || secure_with_cookies! || secure_with_token! do
27
- if session_set
28
- capture_facebook_friends_if_available!
29
- Session.current = facebook_session
30
- end
29
+ # first, see if we already have a session
30
+ session_set = session_already_secured?
31
+ # if not, see if we can load it from the environment
32
+ unless session_set
33
+ session_set = create_facebook_session
34
+ session[:facebook_session] = @facebook_session if session_set
35
+ end
36
+ if session_set
37
+ capture_facebook_friends_if_available!
38
+ Session.current = facebook_session
31
39
  end
40
+ return session_set
32
41
  end
33
42
 
43
+
34
44
  def facebook_params
35
45
  @facebook_params ||= verified_facebook_params
36
46
  end
@@ -101,7 +111,7 @@ module Facebooker
101
111
 
102
112
  @facebook_session = new_facebook_session
103
113
  @facebook_session.secure_with!(parsed['session_key'],parsed['user'],parsed['expires'],parsed['ss'])
104
- session[:facebook_session] = @facebook_session
114
+ @facebook_session
105
115
  end
106
116
 
107
117
  def secure_with_token!
@@ -109,7 +119,7 @@ module Facebooker
109
119
  @facebook_session = new_facebook_session
110
120
  @facebook_session.auth_token = params['auth_token']
111
121
  @facebook_session.secure!
112
- session[:facebook_session] = @facebook_session
122
+ @facebook_session
113
123
  end
114
124
  end
115
125
 
@@ -119,7 +129,7 @@ module Facebooker
119
129
  if ['user', 'session_key'].all? {|element| facebook_params[element]}
120
130
  @facebook_session = new_facebook_session
121
131
  @facebook_session.secure_with!(facebook_params['session_key'], facebook_params['user'], facebook_params['expires'])
122
- session[:facebook_session] = @facebook_session
132
+ @facebook_session
123
133
  end
124
134
  end
125
135
 
@@ -228,6 +238,9 @@ module Facebooker
228
238
  def ensure_has_photo_upload
229
239
  has_extended_permission?("photo_upload") || application_needs_permission("photo_upload")
230
240
  end
241
+ def ensure_has_video_upload
242
+ has_extended_permission?("video_upload") || application_needs_permission("video_upload")
243
+ end
231
244
  def ensure_has_create_listing
232
245
  has_extended_permission?("create_listing") || application_needs_permission("create_listing")
233
246
  end
@@ -256,9 +269,14 @@ module Facebooker
256
269
  redirect_to session[:facebook_session].install_url(url_params)
257
270
  end
258
271
 
259
- def set_fbml_format
260
- params[:format]="fbml" if request_comes_from_facebook?
272
+ def set_facebook_request_format
273
+ if request_is_facebook_ajax?
274
+ params[:format] = 'fbjs'
275
+ elsif request_comes_from_facebook?
276
+ params[:format] = 'fbml'
277
+ end
261
278
  end
279
+
262
280
  def set_adapter
263
281
  Facebooker.load_adapter(params) if(params[:fb_sig_api_key])
264
282
  end
@@ -276,6 +294,10 @@ module Facebooker
276
294
  def ensure_application_is_installed_by_facebook_user(options = {})
277
295
  before_filter :ensure_application_is_installed_by_facebook_user, options
278
296
  end
297
+
298
+ def request_comes_from_facebook?
299
+ request_is_for_a_facebook_canvas? || request_is_facebook_ajax?
300
+ end
279
301
  end
280
302
  end
281
303
  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,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
@@ -1,14 +1,22 @@
1
- if Facebooker.facebooker_config['pretty_errors'] || (Facebooker.facebooker_config['pretty_errors'].nil? && RAILS_ENV=="development")
2
- class ActionController::Base
3
- def rescues_path_with_facebooker(template_name)
4
- t="#{RAILS_ROOT}/vendor/plugins/facebooker/templates/#{template_name}.erb"
5
- File.exist?(t) ? t : rescues_path_without_facebooker(template_name)
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)
6
8
  end
9
+ end
10
+ alias_method_chain :rescues_path, :facebooker
7
11
 
8
- alias_method_chain :rescues_path,:facebooker
9
-
10
- def response_code_for_rescue(exception)
11
- 200
12
- end
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")
13
21
  end
14
- end
22
+ end
@@ -1,3 +1,4 @@
1
+ require 'action_pack'
1
2
  module Facebooker
2
3
  module Rails
3
4
 
@@ -15,7 +16,11 @@ module Facebooker
15
16
  # cancel_button is true or false
16
17
  def fb_dialog( id, cancel_button, &block )
17
18
  content = capture(&block)
18
- concat( content_tag("fb:dialog", content, {:id => id, :cancel_button => cancel_button}), block.binding )
19
+ if ignore_binding?
20
+ concat( content_tag("fb:dialog", content, {:id => id, :cancel_button => cancel_button}) )
21
+ else
22
+ concat( content_tag("fb:dialog", content, {:id => id, :cancel_button => cancel_button}), block.binding )
23
+ end
19
24
  end
20
25
 
21
26
  def fb_dialog_title( title )
@@ -23,8 +28,12 @@ module Facebooker
23
28
  end
24
29
 
25
30
  def fb_dialog_content( &block )
26
- content = capture(&block)
27
- concat( content_tag("fb:dialog-content", content), block.binding )
31
+ content = capture(&block)
32
+ if ignore_binding?
33
+ concat( content_tag("fb:dialog-content", content) )
34
+ else
35
+ concat( content_tag("fb:dialog-content", content), block.binding )
36
+ end
28
37
  end
29
38
 
30
39
  def fb_dialog_button( type, value, options={} )
@@ -52,27 +61,32 @@ module Facebooker
52
61
  # <% end %>
53
62
  def fb_request_form(type,message_param,url,options={},&block)
54
63
  content = capture(&block)
55
- message = @template.instance_variable_get("@content_for_#{message_param}")
56
- concat(content_tag("fb:request-form", content + token_tag,
57
- {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>message}.merge(options)),
58
- block.binding)
64
+ message = @template.instance_variable_get("@content_for_#{message_param}")
65
+ if ignore_binding?
66
+ concat(content_tag("fb:request-form", content + token_tag,
67
+ {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>message}.merge(options)))
68
+ else
69
+ concat(content_tag("fb:request-form", content + token_tag,
70
+ {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>message}.merge(options)),
71
+ block.binding)
72
+ end
59
73
  end
60
74
 
61
- # Create a submit button for an <fb:request-form>
62
- # If the request is for an individual user you can optionally
63
- # Provide the user and a label for the request button.
64
- # For example
65
- # <% content_for("invite_user") do %>
66
- # This gets sent in the invite. <%= fb_req_choice("Come join us!",new_invite_path) %>
67
- # <% end %>
68
- # <% fb_request_form("Invite","invite_user",create_invite_path) do %>
69
- # Invite <%= fb_name(@facebook_user.friends.first.id)%> to the party <br />
70
- # <%= fb_request_form_submit(@facebook_user.friends.first.id,"Invite %n") %>
71
- # <% end %>
72
- # <em>See:</em> http://wiki.developers.facebook.com/index.php/Fb:request-form-submit for options
73
- def fb_request_form_submit(options={})
74
- tag("fb:request-form-submit",stringify_vals(options))
75
- end
75
+ # Create a submit button for an <fb:request-form>
76
+ # If the request is for an individual user you can optionally
77
+ # Provide the user and a label for the request button.
78
+ # For example
79
+ # <% content_for("invite_user") do %>
80
+ # This gets sent in the invite. <%= fb_req_choice("Come join us!",new_invite_path) %>
81
+ # <% end %>
82
+ # <% fb_request_form("Invite","invite_user",create_invite_path) do %>
83
+ # Invite <%= fb_name(@facebook_user.friends.first.id)%> to the party <br />
84
+ # <%= fb_request_form_submit(:uid => @facebook_user.friends.first.id, :label => "Invite %n") %>
85
+ # <% end %>
86
+ # <em>See:</em> http://wiki.developers.facebook.com/index.php/Fb:request-form-submit for options
87
+ def fb_request_form_submit(options={})
88
+ tag("fb:request-form-submit",stringify_vals(options))
89
+ end
76
90
 
77
91
 
78
92
  # Create an fb:request-form with an fb_multi_friend_selector inside
@@ -86,11 +100,18 @@ module Facebooker
86
100
  # <% end %>
87
101
  def fb_multi_friend_request(type,friend_selector_message,url,&block)
88
102
  content = capture(&block)
89
- concat(content_tag("fb:request-form",
90
- fb_multi_friend_selector(friend_selector_message) + token_tag,
91
- {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>content}
92
- ),
93
- block.binding)
103
+ if ignore_binding?
104
+ concat(content_tag("fb:request-form",
105
+ fb_multi_friend_selector(friend_selector_message) + token_tag,
106
+ {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>content}
107
+ ))
108
+ else
109
+ concat(content_tag("fb:request-form",
110
+ fb_multi_friend_selector(friend_selector_message) + token_tag,
111
+ {:action=>url,:method=>"post",:invite=>true,:type=>type,:content=>content}
112
+ ),
113
+ block.binding)
114
+ end
94
115
  end
95
116
 
96
117
  # Render an <fb:friend-selector> element
@@ -130,45 +151,45 @@ module Facebooker
130
151
  def fb_req_choice(label,url)
131
152
  tag "fb:req-choice",:label=>label,:url=>url
132
153
  end
133
-
134
- # Create a facebook form using <fb:editor>
135
- #
136
- # It yields a form builder that will convert the standard rails form helpers
137
- # into the facebook specific version.
138
- #
139
- # Example:
140
- # <% facebook_form_for(:poke,@poke,:url => create_poke_path) do |f| %>
141
- # <%= f.text_field :message, :label=>"message" %>
142
- # <%= f.buttons "Save Poke" %>
143
- # <% end %>
144
- #
145
- # will generate
146
- #
147
- # <fb:editor action="/pokes/create">
148
- # <fb:editor-text name="poke[message]" id="poke_message" value="" label="message" />
149
- # <fb:editor-buttonset>
150
- # <fb:editor-button label="Save Poke"
151
- # </fb:editor-buttonset>
152
- # </fb:editor>
154
+
155
+ # Create a facebook form using <fb:editor>
156
+ #
157
+ # It yields a form builder that will convert the standard rails form helpers
158
+ # into the facebook specific version.
159
+ #
160
+ # Example:
161
+ # <% facebook_form_for(:poke,@poke,:url => create_poke_path) do |f| %>
162
+ # <%= f.text_field :message, :label=>"message" %>
163
+ # <%= f.buttons "Save Poke" %>
164
+ # <% end %>
165
+ #
166
+ # will generate
167
+ #
168
+ # <fb:editor action="/pokes/create">
169
+ # <fb:editor-text name="poke[message]" id="poke_message" value="" label="message" />
170
+ # <fb:editor-buttonset>
171
+ # <fb:editor-button label="Save Poke"
172
+ # </fb:editor-buttonset>
173
+ # </fb:editor>
153
174
  def facebook_form_for( record_or_name_or_array,*args, &proc)
154
175
 
155
176
  raise ArgumentError, "Missing block" unless block_given?
156
177
  options = args.last.is_a?(Hash) ? args.pop : {}
157
178
 
158
- case record_or_name_or_array
159
- when String, Symbol
160
- object_name = record_or_name_or_array
161
- when Array
162
- object = record_or_name_or_array.last
163
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
164
- apply_form_for_options!(record_or_name_or_array, options)
165
- args.unshift object
166
- else
167
- object = record_or_name_or_array
168
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
169
- apply_form_for_options!([object], options)
170
- args.unshift object
171
- end
179
+ case record_or_name_or_array
180
+ when String, Symbol
181
+ object_name = record_or_name_or_array
182
+ when Array
183
+ object = record_or_name_or_array.last
184
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
185
+ apply_form_for_options!(record_or_name_or_array, options)
186
+ args.unshift object
187
+ else
188
+ object = record_or_name_or_array
189
+ object_name = ActionController::RecordIdentifier.singular_class_name(object)
190
+ apply_form_for_options!([object], options)
191
+ args.unshift object
192
+ end
172
193
  method = (options[:html]||{})[:method]
173
194
  options[:builder] ||= Facebooker::Rails::FacebookFormBuilder
174
195
  editor_options={}
@@ -180,12 +201,20 @@ module Facebooker
180
201
  width=options.delete(:labelwidth)
181
202
  editor_options[:labelwidth]=width unless width.blank?
182
203
 
183
- concat(tag("fb:editor",editor_options,true) , proc.binding)
184
- concat(tag(:input,{:type=>"hidden",:name=>:_method, :value=>method},false), proc.binding) unless method.blank?
185
- concat(token_tag, proc.binding)
186
- fields_for( object_name,*(args << options), &proc)
187
- concat("</fb:editor>",proc.binding)
188
- end
204
+ if ignore_binding?
205
+ concat(tag("fb:editor",editor_options,true))
206
+ concat(tag(:input,{:type=>"hidden",:name=>:_method, :value=>method},false)) unless method.blank?
207
+ concat(token_tag)
208
+ fields_for( object_name,*(args << options), &proc)
209
+ concat("</fb:editor>")
210
+ else
211
+ concat(tag("fb:editor",editor_options,true) , proc.binding)
212
+ concat(tag(:input,{:type=>"hidden",:name=>:_method, :value=>method},false), proc.binding) unless method.blank?
213
+ concat(token_tag, proc.binding)
214
+ fields_for( object_name,*(args << options), &proc)
215
+ concat("</fb:editor>",proc.binding)
216
+ end
217
+ end
189
218
 
190
219
  # Render an fb:name tag for the given user
191
220
  # This renders the name of the user specified. You can use this tag as both subject and object of
@@ -284,17 +313,21 @@ module Facebooker
284
313
  VALID_FB_SHARED_PHOTO_SIZES = [:thumb, :small, :normal, :square]
285
314
  VALID_FB_PHOTO_SIZES = VALID_FB_SHARED_PHOTO_SIZES
286
315
  VALID_FB_PROFILE_PIC_SIZES = VALID_FB_SHARED_PHOTO_SIZES
287
- VALID_PERMISSIONS=[:email, :offline_access, :status_update, :photo_upload, :create_listing, :create_event, :rsvp_event, :sms]
316
+ VALID_PERMISSIONS=[:email, :offline_access, :status_update, :photo_upload, :create_listing, :create_event, :rsvp_event, :sms, :video_upload]
288
317
 
289
318
  # Render an fb:tabs tag containing some number of fb:tab_item tags.
290
319
  # Example:
291
- # <% fb_tabs do %>
292
- # <%= fb_tab_item("Home", "home") %>
293
- # <%= fb_tab_item("Office", "office") %>
294
- # <% end %>
320
+ # <% fb_tabs do %>
321
+ # <%= fb_tab_item("Home", "home") %>
322
+ # <%= fb_tab_item("Office", "office") %>
323
+ # <% end %>
295
324
  def fb_tabs(&block)
296
- content = capture(&block)
297
- concat(content_tag("fb:tabs", content), block.binding)
325
+ content = capture(&block)
326
+ if ignore_binding?
327
+ concat(content_tag("fb:tabs", content))
328
+ else
329
+ concat(content_tag("fb:tabs", content), block.binding)
330
+ end
298
331
  end
299
332
 
300
333
  # Render an fb:tab_item tag.
@@ -304,7 +337,7 @@ module Facebooker
304
337
  def fb_tab_item(title, url, options={})
305
338
  options= options.dup
306
339
  options.assert_valid_keys(FB_TAB_ITEM_VALID_OPTION_KEYS)
307
- options.merge!(:title => title, :href => url)
340
+ options.merge!(:title => title, :href => url)
308
341
  validate_fb_tab_item_align_value(options)
309
342
  tag("fb:tab-item", stringify_vals(options))
310
343
  end
@@ -313,13 +346,13 @@ module Facebooker
313
346
 
314
347
  def validate_fb_tab_item_align_value(options)
315
348
  if options.has_key?(:align) && !VALID_FB_TAB_ITEM_ALIGN_VALUES.include?(options[:align].to_sym)
316
- raise(ArgumentError, "Unkown value for align: #{options[:align]}")
349
+ raise(ArgumentError, "Unknown value for align: #{options[:align]}")
317
350
  end
318
351
  end
319
352
 
320
353
  def validate_fb_photo_align_value(options)
321
354
  if options.has_key?(:align) && !VALID_FB_PHOTO_ALIGN_VALUES.include?(options[:align].to_sym)
322
- raise(ArgumentError, "Unkown value for align: #{options[:align]}")
355
+ raise(ArgumentError, "Unknown value for align: #{options[:align]}")
323
356
  end
324
357
  end
325
358
 
@@ -336,8 +369,12 @@ module Facebooker
336
369
  # <%= fb_wall_post(@otheruser,"This is another message") %>
337
370
  # <% end %>
338
371
  def fb_wall(&proc)
339
- content = capture(&proc)
340
- concat(content_tag("fb:wall",content,{}),proc.binding)
372
+ content = capture(&proc)
373
+ if ignore_binding?
374
+ concat(content_tag("fb:wall",content,{}))
375
+ else
376
+ concat(content_tag("fb:wall",content,{}),proc.binding)
377
+ end
341
378
  end
342
379
 
343
380
  # Render an <fb:wallpost> tag
@@ -396,8 +433,12 @@ module Facebooker
396
433
  # <% end %>
397
434
  def fb_dashboard(&proc)
398
435
  if block_given?
399
- content = capture(&proc)
400
- concat(content_tag("fb:dashboard",content,{}),proc.binding)
436
+ content = capture(&proc)
437
+ if ignore_binding?
438
+ concat(content_tag("fb:dashboard",content,{}))
439
+ else
440
+ concat(content_tag("fb:dashboard",content,{}),proc.binding)
441
+ end
401
442
  else
402
443
  content_tag("fb:dashboard",content,{})
403
444
  end
@@ -406,13 +447,21 @@ module Facebooker
406
447
  # Content for the wide profile box goes in this tag
407
448
  def fb_wide(&proc)
408
449
  content = capture(&proc)
409
- concat(content_tag("fb:wide", content, {}), proc.binding)
450
+ if ignore_binding?
451
+ concat(content_tag("fb:wide", content, {}))
452
+ else
453
+ concat(content_tag("fb:wide", content, {}), proc.binding)
454
+ end
410
455
  end
411
456
 
412
457
  # Content for the narrow profile box goes in this tag
413
458
  def fb_narrow(&proc)
414
459
  content = capture(&proc)
415
- concat(content_tag("fb:narrow", content, {}), proc.binding)
460
+ if ignore_binding?
461
+ concat(content_tag("fb:narrow", content, {}))
462
+ else
463
+ concat(content_tag("fb:narrow", content, {}), proc.binding)
464
+ end
416
465
  end
417
466
 
418
467
  # Renders an action using the <fb:action> tag
@@ -428,27 +477,27 @@ module Facebooker
428
477
 
429
478
  # Render a <fb:create-button> tag
430
479
  # For use inside <fb:dashboard>
431
- def fb_create_button(name, url)
432
- "<fb:create-button href=\"#{url_for(url)}\">#{name}</fb:create-button>"
433
- end
434
-
435
- # Create a comment area
436
- # All the data for this content area is stored on the facebook servers.
437
- # <em>See:</em> http://wiki.developers.facebook.com/index.php/Fb:comments for full details
438
- def fb_comments(xid,canpost=true,candelete=false,numposts=5,options={})
439
- options = options.dup
480
+ def fb_create_button(name, url)
481
+ "<fb:create-button href=\"#{url_for(url)}\">#{name}</fb:create-button>"
482
+ end
483
+
484
+ # Create a comment area
485
+ # All the data for this content area is stored on the facebook servers.
486
+ # <em>See:</em> http://wiki.developers.facebook.com/index.php/Fb:comments for full details
487
+ def fb_comments(xid,canpost=true,candelete=false,numposts=5,options={})
488
+ options = options.dup
440
489
  title = (title = options.delete(:title)) ? fb_title(title) : nil
441
- content_tag "fb:comments",title,stringify_vals(options.merge(:xid=>xid,:canpost=>canpost.to_s,:candelete=>candelete.to_s,:numposts=>numposts))
442
- end
443
-
444
- # Adds a title to the title bar
445
- #
446
- # Facebook | App Name | This is the canvas page window title
447
- #
490
+ content_tag "fb:comments",title,stringify_vals(options.merge(:xid=>xid,:canpost=>canpost.to_s,:candelete=>candelete.to_s,:numposts=>numposts))
491
+ end
492
+
493
+ # Adds a title to the title bar
494
+ #
495
+ # Facebook | App Name | This is the canvas page window title
496
+ #
448
497
  # +title+: This is the canvas page window
449
- def fb_title(title)
450
- "<fb:title>#{title}</fb:title>"
451
- end
498
+ def fb_title(title)
499
+ "<fb:title>#{title}</fb:title>"
500
+ end
452
501
 
453
502
  # Create a Google Analytics tag
454
503
  #
@@ -463,16 +512,20 @@ module Facebooker
463
512
  # Use fb_if_user_has_added_app to determine wether the user has added the app.
464
513
  # Example:
465
514
  # <% fb_if_is_app_user(@facebook_user) do %>
466
- # Thanks for accepting our terms of service!
467
- # <% fb_else do %>
468
- # Hey you haven't agreed to our terms. <%= link_to("Please accept our terms of service.", :action => "terms_of_service") %>
469
- # <% end %>
515
+ # Thanks for accepting our terms of service!
516
+ # <% fb_else do %>
517
+ # Hey you haven't agreed to our terms. <%= link_to("Please accept our terms of service.", :action => "terms_of_service") %>
518
+ # <% end %>
470
519
  #<% end %>
471
520
  def fb_if_is_app_user(user=nil,options={},&proc)
472
521
  content = capture(&proc)
473
522
  options = options.dup
474
523
  options.merge!(:uid=>cast_to_facebook_id(user)) if user
475
- concat(content_tag("fb:if-is-app-user",content,stringify_vals(options)),proc.binding)
524
+ if ignore_binding?
525
+ concat(content_tag("fb:if-is-app-user",content,stringify_vals(options)))
526
+ else
527
+ concat(content_tag("fb:if-is-app-user",content,stringify_vals(options)),proc.binding)
528
+ end
476
529
  end
477
530
 
478
531
  # Render if-user-has-added-app tag
@@ -480,15 +533,19 @@ module Facebooker
480
533
  #
481
534
  # Example:
482
535
  # <% fb_if_user_has_added_app(@facebook_user) do %>
483
- # Hey you are an app user!
484
- # <% fb_else do %>
485
- # Hey you aren't an app user. <%= link_to("Add App and see the other side.", :action => "added_app") %>
486
- # <% end %>
536
+ # Hey you are an app user!
537
+ # <% fb_else do %>
538
+ # Hey you aren't an app user. <%= link_to("Add App and see the other side.", :action => "added_app") %>
539
+ # <% end %>
487
540
  #<% end %>
488
541
  def fb_if_user_has_added_app(user,options={},&proc)
489
542
  content = capture(&proc)
490
543
  options = options.dup
491
- concat(content_tag("fb:if-user-has-added-app",content,stringify_vals(options.merge(:uid=>cast_to_facebook_id(user)))),proc.binding)
544
+ if ignore_binding?
545
+ concat(content_tag("fb:if-user-has-added-app", content, stringify_vals(options.merge(:uid=>cast_to_facebook_id(user)))))
546
+ else
547
+ concat(content_tag("fb:if-user-has-added-app", content, stringify_vals(options.merge(:uid=>cast_to_facebook_id(user)))),proc.binding)
548
+ end
492
549
  end
493
550
 
494
551
  # Render fb:if-is-user tag
@@ -496,24 +553,32 @@ module Facebooker
496
553
  # user can be a single user or an Array of users
497
554
  # Example:
498
555
  # <% fb_if_is_user(@check_user) do %>
499
- # <%= fb_name(@facebook_user) %> are one of the users. <%= link_to("Check the other side", :action => "friend") %>
500
- # <% fb_else do %>
501
- # <%= fb_name(@facebook_user) %> are not one of the users <%= fb_name(@check_user) %>
502
- # <%= link_to("Check the other side", :action => "you") %>
503
- # <% end %>
556
+ # <%= fb_name(@facebook_user) %> are one of the users. <%= link_to("Check the other side", :action => "friend") %>
557
+ # <% fb_else do %>
558
+ # <%= fb_name(@facebook_user) %> are not one of the users <%= fb_name(@check_user) %>
559
+ # <%= link_to("Check the other side", :action => "you") %>
560
+ # <% end %>
504
561
  # <% end %>
505
562
  def fb_if_is_user(user,&proc)
506
563
  content = capture(&proc)
507
564
  user = [user] unless user.is_a? Array
508
565
  user_list=user.map{|u| cast_to_facebook_id(u)}.join(",")
509
- concat(content_tag("fb:if-is-user",content,{:uid=>user_list}),proc.binding)
566
+ if ignore_binding?
567
+ concat(content_tag("fb:if-is-user",content,{:uid=>user_list}))
568
+ else
569
+ concat(content_tag("fb:if-is-user",content,{:uid=>user_list}),proc.binding)
570
+ end
510
571
  end
511
572
 
512
573
  # Render fb:else tag
513
574
  # Must be used within if block such as fb_if_is_user or fb_if_is_app_user . See example in fb_if_is_app_user
514
575
  def fb_else(&proc)
515
- content = capture(&proc)
516
- concat(content_tag("fb:else",content),proc.binding)
576
+ content = capture(&proc)
577
+ if ignore_binding?
578
+ concat(content_tag("fb:else",content))
579
+ else
580
+ concat(content_tag("fb:else",content),proc.binding)
581
+ end
517
582
  end
518
583
 
519
584
  #
@@ -559,6 +624,7 @@ module Facebooker
559
624
  # * offline_access
560
625
  # * status_update
561
626
  # * photo_upload
627
+ # * video_upload
562
628
  # * create_listing
563
629
  # * create_event
564
630
  # * rsvp_event
@@ -610,6 +676,17 @@ module Facebooker
610
676
  concat(content_tag("fb:container",inner,options),&proc.binding)
611
677
  end
612
678
 
679
+ # Renders an fb:time element
680
+ #
681
+ # Example:
682
+ # <%= fb_time(Time.now, :tz => 'America/New York', :preposition => true) %>
683
+ #
684
+ # See http://wiki.developers.facebook.com/index.php/Fb:time for
685
+ # more details
686
+ def fb_time(time, options={})
687
+ tag "fb:time",stringify_vals({:t => time.to_i}.merge(options))
688
+ end
689
+
613
690
  protected
614
691
 
615
692
  def cast_to_facebook_id(object)
@@ -618,13 +695,13 @@ module Facebooker
618
695
 
619
696
  def validate_fb_profile_pic_size(options)
620
697
  if options.has_key?(:size) && !VALID_FB_PROFILE_PIC_SIZES.include?(options[:size].to_sym)
621
- raise(ArgumentError, "Unkown value for size: #{options[:size]}")
698
+ raise(ArgumentError, "Unknown value for size: #{options[:size]}")
622
699
  end
623
700
  end
624
701
 
625
702
  def validate_fb_photo_size(options)
626
703
  if options.has_key?(:size) && !VALID_FB_PHOTO_SIZES.include?(options[:size].to_sym)
627
- raise(ArgumentError, "Unkown value for size: #{options[:size]}")
704
+ raise(ArgumentError, "Unknown value for size: #{options[:size]}")
628
705
  end
629
706
  end
630
707
 
@@ -652,6 +729,10 @@ module Facebooker
652
729
  tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => form_authenticity_token)
653
730
  end
654
731
  end
732
+
733
+ def ignore_binding?
734
+ ActionPack::VERSION::MAJOR >= 2 && ActionPack::VERSION::MINOR >= 2
735
+ end
655
736
  end
656
737
  end
657
738
  end