facebooker 1.0.13 → 1.0.18

Sign up to get free protection for your applications and to get access to all the features.
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