File Coverage

blib/lib/WWW/Facebook/API.pm
Criterion Covered Total %
statement 756 804 94.0
branch 192 272 70.5
condition 29 60 48.3
subroutine 175 180 97.2
pod 126 128 98.4
total 1278 1444 88.5


line stmt bran cond sub pod time code
1             #########################################################################
2             # ex: set ts=8 sw=4 et
3             #########################################################################
4             package WWW::Facebook::API;
5              
6 34     34   1058780 use warnings;
  34     1   93  
  34         1259  
  1         1147  
  1         27837  
  1         8  
7 34     34   503 use strict;
  34         65  
  34         1440  
8 34     34   181 use Carp;
  34         62  
  34         3550  
9              
10 34     34   32028 use version; our $VERSION = qv('0.4.18');
  34         87717  
  34         229  
11              
12 34     34   70258 use LWP::UserAgent;
  34         3310198  
  34         1871  
13 34     34   44105 use Time::HiRes qw(time);
  34         97959  
  34         537  
14 34     34   13636 use Digest::MD5 qw(md5_hex);
  34         79  
  34         2561  
15 34     34   41692 use Encode qw(encode_utf8 is_utf8);
  34         526929  
  34         4379  
16 34     34   78154 use CGI;
  34         653353  
  34         313  
17 34     34   2747 use CGI::Util qw(escape);
  34         63  
  34         2192  
18              
19 34     34   25497 use WWW::Facebook::API::Exception;
  34         91  
  34         142738  
20              
21             our @namespaces = qw(
22             Admin Application Auth
23             Canvas Comments Connect
24             Data Events FBML
25             Feed FQL Friends
26             Groups Intl Links
27             LiveMessage Message Notes
28             Notifications Pages Permissions
29             Photos Profile SMS
30             Status Stream Users
31             Video
32             );
33              
34             for (@namespaces) {
35             my $package = __PACKAGE__ . "::$_";
36             my $name = "\L$_";
37             ## no critic
38 34 100   34 1 25210 my $namespace = eval qq(
  34 100   34 1 103  
  34 50   34 1 8544  
  34 100   34 1 26806  
  34 50   34 1 93  
  34 50   34 1 7411  
  34 50   34 1 20847  
  34 100   34 1 102  
  34 100   34 1 7794  
  34 100   34 1 24941  
  34 50   34 1 98  
  34 100   34 1 8107  
  34 50   34 1 22828  
  34 100   34 1 101  
  34 100   34 1 7788  
  34 100   34 1 21775  
  34 100   34 1 196  
  34 100   34 1 32607  
  34 100   34 1 96356  
  34 100   34 1 91  
  34 100   34 1 7680  
  34 100   34 1 22611  
  34 50   34 1 92  
  34 100   34 1 8689  
  34 100   34 1 35411  
  34 100   34 1 96  
  34 100   34 1 17005  
  34 100   34 1 22656  
  34     31 1 88  
  34     28 1 7234  
  34     27 1 22100  
  34     35 1 94  
  34     32 1 7242  
  34     27 1 29146  
  34     38 1 97  
  34     27 1 19031  
  34     27 1 22388  
  34     33 1 89  
  34     37 1 6843  
  34     28 1 21380  
  34     28 1 85  
  34     27 1 6814  
  34     35 1 31284  
  34     27 0 95  
  34     31 1 7428  
  34     27 1 38725  
  34     27 1 96  
  34     38 1 7499  
  34     27 1 2252340  
  34     27 1 97  
  34     36 1 7998  
  34     33 1 24330  
  34     27 1 107  
  34     27 1 8801  
  34     27 1 33380  
  34     31 1 89  
  34     28 1 8482  
  34     27 1 24258  
  34     29 1 88  
  34     29 1 7252  
  34     27 1 23548  
  34     27 1 95  
  34     27 1 7178  
  34     33 1 25861  
  34     33 1 97  
  34     32 1 8220  
  34     27 1 27421  
  34     32 1 97  
  34     27 1 7958  
  34     28 1 22346  
  34     29 1 96  
  34     28 1 7458  
  34     28 1 22005  
  34     28 1 94  
  34     28 1 7419  
  34     28 1 30120  
  34     28 1 161  
  34     28 1 7866  
  34     28 1 22419  
  34     28 1 105  
  34     28 1 7119  
  34     28 1 33363  
  34     28 1 96  
  34     28 1 7578  
  31     28   3969  
  31     28   174  
  27     28   299  
  31     28   930  
  28     28   114  
  28     28   149  
  27     28   251  
  28     28   963  
  27     28   81  
  27     28   177  
  27     28   247  
  27     28   884  
  35     28   336  
  32     28   143  
  27     28   107  
  38     28   138  
  27     28   105  
  27     31   96  
  33     32   155  
  37     31   216  
  28     31   144  
  28     33   116  
  27     27   117  
  35     29   785  
  27     29   103  
  31     37   163  
  27     33   105  
  27     31   95  
  38         153  
  27         103  
  27         98  
  36         213  
  33         123  
  27         99  
  27         101  
  27         96  
  31         382  
  28         108  
  27         86  
  29         116  
  29         89  
  29         147  
  27         254  
  29         980  
  27         71  
  27         143  
  27         261  
  27         879  
  27         70  
  27         136  
  27         467  
  27         1011  
  27         72  
  27         141  
  27         234  
  27         882  
  33         4444  
  33         163  
  27         234  
  33         954  
  33         3968  
  33         231  
  27         232  
  33         987  
  32         3736  
  32         167  
  27         230  
  32         876  
  27         73  
  27         283  
  27         237  
  27         872  
  32         3158  
  32         217  
  27         233  
  32         883  
  27         68  
  27         127  
  27         219  
  27         870  
  28         103  
  28         141  
  27         305  
  28         892  
  29         1361  
  29         143  
  27         216  
  29         939  
  28         119  
  28         137  
  27         233  
  28         1170  
  28         170  
  28         158  
  27         254  
  28         915  
  28         114  
  28         103  
  28         65  
  28         216  
  28         161  
  28         93  
  28         183  
  28         150  
  28         102  
  28         118  
  28         76  
  28         166  
  28         162  
  28         65  
  28         202  
  28         144  
  28         113  
  28         115  
  28         68  
  28         168  
  28         169  
  28         81  
  28         183  
  28         141  
  28         127  
  28         117  
  28         69  
  28         177  
  28         396  
  28         75  
  28         183  
  28         135  
  28         114  
  28         110  
  28         70  
  28         153  
  28         431  
  28         64  
  28         175  
  28         140  
  28         106  
  28         98  
  28         79  
  28         159  
  28         253  
  28         65  
  28         190  
  28         159  
  28         96  
  28         108  
  28         64  
  28         154  
  28         158  
  28         69  
  28         205  
  28         150  
  28         107  
  28         107  
  28         64  
  28         162  
  28         160  
  28         69  
  28         193  
  28         155  
  28         124  
  28         107  
  28         67  
  28         240  
  28         175  
  28         72  
  28         195  
  28         192  
  28         111  
  28         108  
  28         76  
  28         191  
  28         182  
  28         65  
  28         211  
  28         172  
  28         101  
  28         175  
  28         68  
  28         175  
  28         324  
  28         74  
  28         195  
  28         231  
  28         98  
  28         180  
  28         105  
  28         198  
  28         195  
  28         67  
  28         175  
  28         149  
  28         106  
  28         113  
  28         74  
  28         176  
  28         195  
  28         66  
  28         219  
  28         142  
  28         110  
  28         121  
  28         66  
  28         152  
  28         161  
  28         81  
  28         202  
  28         143  
  28         110  
  28         117  
  28         70  
  28         157  
  28         243  
  28         69  
  28         180  
  28         150  
  28         114  
  28         105  
  28         77  
  28         166  
  28         176  
  28         72  
  28         185  
  28         147  
  28         102  
  28         145  
  28         72  
  28         167  
  28         178  
  28         69  
  28         210  
  28         141  
  28         114  
  28         104  
  28         66  
  28         172  
  28         176  
  28         67  
  28         184  
  28         150  
  28         114  
  28         99  
  28         69  
  28         166  
  28         168  
  28         66  
  28         194  
  28         220  
  28         175  
  28         115  
  28         81  
  28         161  
  28         167  
  28         91  
  28         202  
  28         142  
  28         115  
  28         99  
  28         165  
  28         244  
  28         266  
  28         76  
  28         195  
  28         143  
  28         111  
  28         104  
  28         61  
  28         161  
  28         159  
  28         65  
  28         194  
  28         140  
  28         106  
  28         118  
  28         63  
  28         156  
  28         180  
  28         73  
  28         176  
  28         136  
  28         97  
  28         178  
  28         67  
  28         196  
  28         158  
  28         67  
  28         173  
  28         151  
  28         97  
  28         113  
  28         66  
  28         172  
  28         173  
  28         77  
  28         182  
  28         140  
  28         118  
  28         106  
  28         72  
  28         164  
  28         190  
  28         70  
  28         285  
  28         143  
  28         110  
  28         110  
  28         87  
  28         163  
  28         255  
  28         73  
  28         198  
  28         140  
  28         109  
  28         104  
  28         66  
  28         160  
  28         175  
  28         65  
  28         199  
  28         147  
  31         3729  
  31         186  
  27         303  
  31         937  
  32         4447  
  32         175  
  27         237  
  32         1111  
  31         1799  
  31         139  
  27         233  
  31         917  
  31         2663  
  31         147  
  27         295  
  31         924  
  33         4206  
  33         197  
  27         257  
  33         907  
  27         84  
  27         163  
  27         252  
  27         962  
  29         1348  
  29         137  
  27         309  
  29         24046  
  29         1320  
  29         151  
  27         302  
  29         893  
  37         6795  
  37         182  
  27         224  
  37         1242  
  33         4008  
  33         219  
  27         304  
  33         929  
  31         1103  
  31         148  
  27         219  
  31         164  
39             use $package;
40              
41             sub $name {
42             my \$self = shift;
43             unless ( \$self->{'_$name'} ) {
44             \$self->{'_$name'} = $package->new( base => \$self );
45             }
46             return \$self->{'_$name'};
47             }
48              
49             package $package;
50             sub base { return shift->{'base'}; };
51             sub new {
52             my ( \$class, \%args ) = \@_;
53             my \$self = bless \\\%args, \$class;
54              
55             delete \$self->{\$_} for grep { !/base/xms } keys %{\$self};
56             \$self->\$_ for keys %{\$self};
57              
58             return \$self;
59             };
60             1;
61              
62             );
63             croak "Cannot create namespace $name: $@\n" if not $namespace;
64             }
65              
66             our %attributes = (
67             parse => 1,
68             format => 'JSON',
69             debug => 0,
70             throw_errors => 1,
71             api_version => '1.0',
72             apps_uri => 'http://apps.facebook.com/',
73             server_uri => 'http://api.facebook.com/restserver.php',
74             ( map { $_ => q{} }
75             qw(
76             api_key secret desktop
77             last_call_success last_error skipcookie
78             popup next session_key
79             session_expires session_uid callback
80             app_path ua query
81             config app_id call_as_apikey
82             )
83             ),
84             );
85              
86             for ( keys %attributes ) {
87             ## no critic
88 49 50   49 1 189 my $attribute = eval qq(
  49 100   35 1 190  
  49 50   27 1 774  
  22 100   39 1 650  
  35 50   29 1 70  
  35 50   31 0 133  
  35 100   36 1 204  
  27 100   27 1 1145  
  27 50   35 1 56  
  27 100   45 1 250  
  27 50   42 1 278  
  27 100   35 1 809  
  39 100   31 1 93  
  39 100   27 1 193  
  38 50   39 1 1339  
  6 100   27 1 42  
  29 50   35 1 217  
  29 100   39 1 188  
  29 100   33 1 304  
  27 100   29 1 985  
  31 50   37 1 69  
  31 100   29 1 127  
  31 100   27 1 154  
  27 100   27 1 867  
  36 50   27 1 265  
  36 100       153  
  35 50       204  
  27 50       1121  
  27 50       198  
  27 100       140  
  27 50       150  
  26 50       1146  
  35 50       418  
  35 100       324  
  35 100       172  
  27 100       1153  
  45 100       479  
  45 50       369  
  43 50       583  
  25 100       942  
  42 50       235  
  42 100       154  
  42 50       250  
  27 100       1040  
  35 50       86  
  35 50       165  
  31 50       325  
  27 50       844  
  31 50       71  
  31 50       170  
  31         139  
  27         925  
  27         82  
  27         140  
  27         140  
  27         824  
  39         98  
  39         160  
  39         327  
  27         1198  
  27         71  
  27         114  
  27         129  
  27         931  
  35         247  
  35         198  
  35         350  
  27         1019  
  39         694  
  39         157  
  36         336  
  22         617  
  33         69  
  33         143  
  27         111  
  27         838  
  29         1219  
  29         142  
  29         183  
  26         737  
  37         1658  
  37         146  
  37         274  
  25         958  
  29         764  
  29         116  
  29         159  
  26         683  
  27         73  
  27         131  
  27         135  
  27         844  
  27         350  
  27         116  
  27         6732  
  27         1590  
  27         76  
  27         367  
  27         1433  
  0         0  
89             sub $_ {
90             my \$self = shift;
91             return \$self->{$_} = shift if defined \$_[0];
92             return \$self->{$_} if defined \$self->{$_};
93             return \$self->{$_} = '$attributes{$_}';
94             }
95             1;
96             );
97             croak "Cannot create attribute $_: $@\n" if not $attribute;
98             }
99              
100             sub _set_from_outside {
101 27     27   72 my $self = shift;
102              
103 27   66     505 my $app_path = '_' . ( $self->{'app_path'} || $self->app_path );
104 27         90 $app_path =~ tr/a-z/A-Z/;
105 27         83 $app_path =~ tr/A-Za-z0-9_/_/c;
106              
107 27         201 my %ENV_VARS = qw(
108             WFA_API_KEY api_key
109             WFA_SECRET secret
110             WFA_DESKTOP desktop
111             WFA_SESSION_KEY session_key
112             );
113              
114 27 100       126 $self->_set_from_file( $app_path, %ENV_VARS ) if $self->{'config'};
115 27         207 $self->_set_from_env( $app_path, %ENV_VARS );
116              
117 27         86 return;
118             }
119              
120             sub _set_from_file {
121 1     1   2 my $self = shift;
122 1         2 my $app_path = shift;
123 1         4 my %ENV_VARS = @_;
124              
125 1 50       43 open my $config, '<', $self->{'config'} ## no critic
126             or croak "Cannot open $self->{'config'}";
127              
128 1         19 while (<$config>) {
129 4 50       11 carp "Config line: $_" if $self->{'debug'};
130 4         6 chomp;
131 4         14 my ( $key, $val ) = split m/=/xms, $_, 2;
132 4 50       10 next if !$key;
133 4 50       11 carp "Key/Val pair: $key -> $val" if $self->{'debug'};
134 4         8 for ( $key, $val ) {
135 8         15 s/\A\s+//xms;
136 8         22 s/\s+\Z//xms;
137             }
138 4   33     42 $ENV{$key} ||= $val;
139             }
140              
141 1 50       13 close $config or croak "Cannot close $self->{'config'}";
142              
143 1         6 return;
144             }
145              
146             sub _set_from_env {
147 27     27   95 my $self = shift;
148 27         68 my $app_path = shift;
149 27         122 my %ENV_VARS = @_;
150              
151 27         112 for ( keys %ENV_VARS ) {
152 108 100       516 if ( exists $ENV{ $_ . $app_path } ) {
    100          
153 3   33     24 $self->{ $ENV_VARS{$_} } ||= $ENV{ $_ . $app_path };
154             }
155             elsif ( exists $ENV{$_} ) {
156 4   33     19 $self->{ $ENV_VARS{$_} } ||= $ENV{$_};
157             }
158             }
159              
160 27         116 return;
161             }
162              
163             sub new {
164 26     26 1 1408 my ( $self, %args ) = @_;
165 26   33     282 my $class = ref $self || $self;
166 26         111 $self = bless \%args, $class;
167 26         159 $self->_set_from_outside(); # set api_key etc. if needed
168              
169 26   33     711094 $self->{'ua'} ||=
170             LWP::UserAgent->new( agent => "Perl-WWW-Facebook-API/$VERSION" );
171 26         107068 my $is_attribute = join q{|}, keys %attributes;
172 26         115 delete $self->{$_} for grep { !/^ $is_attribute $/xms } keys %{$self};
  66         5103  
  26         128  
173              
174             # set up default namespaces
175 26         136 $self->$_($self) for map {"\L$_"} @namespaces;
  728         2463  
176              
177             # set up default attributes
178 26         1056 $self->$_ for keys %attributes;
179              
180 26         203 return $self;
181             }
182              
183             sub log_string {
184 0     0 1 0 my ( $self, $params, $response ) = @_;
185 0         0 my $string = "\nparams = \n";
186              
187 0         0 $string .= "\t$_:$params->{$_}\n" for sort keys %{$params};
  0         0  
188 0         0 $string .= "response =\n$response\n";
189              
190 0         0 return $string;
191             }
192              
193             sub call_success {
194 4     4 1 5 my $self = shift;
195 4 50       136 $self->last_call_success(shift) if @_;
196 4 50       10 $self->last_error(shift) if @_;
197 4         110 return [ $self->last_call_success, $self->last_error ];
198             }
199              
200             sub call {
201 4     4 1 511 my ( $self, $method, %args ) = @_;
202 4         6 my ( $response, $params, $sig, $raw_data, $filename );
203 4         13 $self->call_success(1);
204              
205 4 50       117 if ( $self->call_as_apikey ) {
206 0         0 $args{'call_as_apikey'} = $self->call_as_apikey;
207             }
208              
209 4         17 ( $params, $raw_data, $filename ) =
210             $self->_format_and_check_params( $method, %args );
211 4         14 $sig = $self->generate_sig(
212             params => $params,
213             secret => delete $params->{'secret'},
214             );
215              
216 4         18 $response = $self->_post_request( $params, $sig, $raw_data, $filename );
217              
218 4 50       136 carp $self->log_string( $params, $response ) if $self->debug;
219 4 50       19 if ( $self->_has_error_response($response) ) {
220 0 0       0 if ( $self->throw_errors ) {
221 0         0 warn WWW::Facebook::API::Exception->new(
222             $method, $params, $response
223             );
224             }
225             }
226              
227 4         12 return $self->_reformat_response( $params, $response );
228             }
229              
230             sub generate_sig {
231 10     10 1 38 my ( $self, %args ) = @_;
232 10         15 my %params = %{ $args{'params'} };
  10         241  
233 10         87 return md5_hex( ( map {"$_=$params{$_}"} sort keys %params ),
  41         220  
234             $args{'secret'} );
235             }
236              
237             sub verify_sig {
238 4     4 1 19 my ( $self, %args ) = @_;
239 4   100     107 return $args{'sig'} eq $self->generate_sig(
240             params => $args{'params'},
241             secret => $args{'secret'} || $self->secret,
242             );
243             }
244              
245             sub session {
246 1     1 1 541 my ( $self, %args ) = @_;
247 1         10 $self->{"session_$_"} = $args{$_} for keys %args;
248 1         4 return;
249             }
250              
251             sub redirect {
252 0     0 1 0 my $self = shift;
253 0         0 my $url = shift;
254 0         0 $self->query(shift);
255              
256 0 0 0     0 if ( $self->canvas->in_fb_canvas ) {
    0          
257 0         0 return qq{};
258             }
259             elsif ($url =~ m{^https?://([^/]*\.)?facebook\.com(:\d+)?}ixms
260             && $self->session_uid )
261             {
262 0         0 return join q{},
263 0         0 map {"$_\n"}
264             '';
267             }
268              
269 0         0 print CGI->new->redirect(
270             $self->get_app_url( next => $self->get_login_url ) );
271 0         0 return 1;
272             }
273              
274 0     0 1 0 sub require_add { return shift->require( 'add', @_ ); }
275 1     1 1 889 sub require_frame { return shift->require( 'frame', @_ ); }
276 1     1 1 647 sub require_login { return shift->require( 'login', @_ ); }
277              
278             sub require { ## no critic
279 2     2 1 5 my $self = shift;
280 2         4 my $what = shift;
281 2         68 $self->query(shift);
282              
283 2 100       7 if ( $what eq 'login' ) {
284 1 0       33 unshift @_, qw( canvas ) if $self->canvas->in_frame;
285             }
286 1 50       7 if ( $what eq 'frame' ) {
287 1 0       33 return if $self->canvas->in_frame;
288 0         0 unshift @_, qw( canvas );
289 0         0 $what = 'login';
290             }
291              
292 0         0 my $user = $self->canvas->get_fb_params->{'user'};
293 0 0       0 if ( $what eq 'add' ) {
294 0 0       0 if ( !$self->canvas->get_fb_params->{'added'} ) {
295 0         0 $user = undef;
296             }
297             }
298 0 0       0 return if $user;
299              
300 0         0 return $self->redirect( $self->get_url( $what, @_ ) );
301             }
302              
303 2     2 1 9 sub get_facebook_url { return shift->get_url( 'facebook', @_ ); }
304 1     1 1 6 sub get_add_url { return shift->get_url( 'add', @_ ); }
305 0     0 1 0 sub get_infinite_session_url { return shift->get_url('infinite_session'); }
306 1     1 1 6 sub get_login_url { return shift->get_url( 'login', @_ ); }
307 1     1 1 5 sub get_app_url { return shift->get_url( 'app', @_ ); }
308              
309             sub get_url {
310 7     7 1 12 my $self = shift;
311 7         44 my $type = shift;
312              
313 7 100       20 if ( $type eq 'facebook' ) {
314 4   100     17 my $site = shift || 'www';
315 4         32 return "http://$site.facebook.com";
316             }
317              
318 3 100       10 if ( $type eq 'app' ) {
319 1         33 return $self->apps_uri . $self->app_path . q{/};
320             }
321              
322 2 50       8 if ( $type eq 'custom' ) {
323 0         0 return (shift) . $self->_add_url_params(@_);
324             }
325              
326 2 50       10 return $self->get_url('facebook')
    50          
    100          
327             . (
328             $type eq 'add' ? '/add.php'
329             : $type eq 'infinite_session' ? '/code_gen.php'
330             : $type eq 'login' ? '/login.php'
331             : q{}
332             ) . $self->_add_url_params(@_);
333             }
334              
335             sub unescape_string {
336 1     1 1 522 my $self = shift;
337 1         3 my $string = shift;
338 1         7 $string =~ s/(?
  5         230  
339 1         9 return $string;
340             }
341              
342             sub _add_url_params {
343 9     9   25 my $self = shift;
344 9         290 my $params = q{?api_key=} . $self->api_key . q{&v=1.0};
345 9 100       27 if (@_) {
346 6 100       22 if ( @_ % 2 ) {
347              
348             # Odd number of elelemts, so didn't pass in canvas => 1
349 1 50       3 $params .= q{&canvas} if grep { $_ eq 'canvas' } @_; ## no critic
  5         12  
350 1         2 @_ = grep { $_ ne 'canvas' } @_;
  5         11  
351             }
352 6         25 my %params = @_;
353 6 100       19 $params .= q{&canvas} if delete $params{'canvas'};
354              
355 6         31 for ( sort keys %params ) {
356 10 100       33 next if not defined $params{$_};
357 6 100       31 $params{$_} = escape( $params{$_} ) if $_ eq 'next';
358 6         106 $params .= "&$_=$params{$_}";
359             }
360             }
361 9         51 return $params;
362             }
363              
364             sub _parser {
365 6     6   47 my $parser = JSON::Any->new;
366              
367 5         342 $parser->handler->allow_nonref;
368 5         41 return $parser;
369             }
370              
371             sub _parse {
372 13     13   7743 my ( $self, $response ) = @_;
373              
374             # Some shortcuts
375 13 100       74 return q{} if $response =~ /\A"?"?\Z/xms;
376 8 100       35 return 1 if $response =~ /\A"?true"?\Z/xms;
377 6 100       27 return 0 if $response =~ /\A"?false"?\Z/xms;
378              
379 4         5 my $parser;
380 4 100       8 eval { $parser = _parser(); 1; } or do {
  4         8  
  3         9  
381              
382             # Only load JSON::Any if we haven't already. Lets the developers
383             # pick their choice of JSON modules (JSON::DWIW, for example)
384             ## no critic
385 1         88 eval q{use JSON::Any};
386 1 50       7007 croak "Unable to load JSON module for parsing:$@\n" if $@;
387 1         5 $parser = _parser();
388             };
389 4 50       129 carp 'JSON::Any is parsing with ' . $parser->handlerType if $self->debug;
390              
391 4         17 return $parser->decode($response);
392             }
393              
394             sub _check_values_of {
395 8     8   15 my ( $self, $params ) = @_;
396              
397 8 100       237 if ( $self->desktop ) {
398 1 50       30 $params->{'call_id'} = time if $self->desktop;
399             }
400              
401 8 100       34 if ( $params->{'method'} !~ m/^auth/xms ) {
402 7   100     191 $params->{'session_key'} ||= $self->session_key;
403 7 100 66     225 if ( !$params->{'callback'} && $self->callback ) {
404 1         37 $params->{'callback'} = $self->callback;
405             }
406             }
407              
408 8         27 $params->{'method'} = "facebook.$params->{'method'}";
409 8   33     260 $params->{'v'} ||= $self->api_version;
410              
411 8   33     273 $params->{$_} ||= $self->$_ for qw(api_key format);
412 8         19 return;
413             }
414              
415             sub _format_and_check_params {
416 4     4   9 my ( $self, $method, %args ) = @_;
417              
418 4   100     31 my $params = delete $args{'params'} || {};
419 4         18 $params->{$_} = $args{$_} for keys %args;
420 4   66     94 $params->{'secret'} ||= $self->secret;
421 4   66     18 $params->{'method'} ||= $method;
422              
423 4         12 $self->_check_values_of($params);
424              
425             # reformat arrays and add each param to digest
426 4         6 for ( keys %{$params} ) {
  4         15  
427 27 100       67 if ( ref $params->{$_} eq 'ARRAY' ) {
428 1         2 $params->{$_} = join q{,}, @{ $params->{$_} };
  1         5  
429             }
430              
431 27 100       89 if ( is_utf8( $params->{$_} ) ) {
432 1         8 $params->{$_} = encode_utf8( $params->{$_} );
433             }
434             }
435              
436 4 50       13 croak '_format_and_check_params must be called in list context!'
437             if !wantarray;
438              
439 4         18 return ( $params, delete $params->{'data'}, delete $params->{'filename'} );
440             }
441              
442             sub _has_error_response {
443 4     4   6 my $self = shift;
444 4         7 my $response = shift;
445              
446             # The different type of error responses
447 4         6 my $json = q{ \{ "error_code" \D+ (\d+) .* "error_msg" [^"]+ "([^"]+)" };
448 4         5 my $xml = q{ (\d+) .* ([^<]+)};
449              
450 4         8 for ( $json, $xml ) {
451 8 50       213 if ( $response =~ m/$_/xms ) {
452 0         0 $self->call_success( 0, "$1: $2" );
453 0         0 return 1;
454             }
455             }
456              
457 4         13 return;
458             }
459              
460             sub _reformat_response {
461 4     4   7 my ( $self, $params, $response ) = @_;
462              
463             # get actual response when web app
464 4 50       13 if ( $params->{'callback'} ) {
465 0         0 $response =~ s/^$params->{'callback'} [^(]* [(](.+) [)];$/$1/xms;
466             }
467 4         8 undef $params;
468              
469             # ... and unescape it if it's not going to be parsed
470 4 50 33     122 if ( !$self->desktop && !$self->parse ) {
471 0         0 $response = $self->unescape_string($response);
472             }
473              
474 4 50 33     130 if ( $self->parse && $self->format eq 'XML' ) {
475 0         0 $self->parse(0);
476 0 0       0 carp q{format is XML: setting parse to 0} if $self->debug;
477             }
478 4 50       114 return $response if !$self->parse;
479              
480 4         12 $response = $self->_parse($response);
481 4 50       11 return if $self->_is_empty_response($response);
482 4         20 return $response;
483             }
484              
485             sub _is_empty_response {
486 4     4   6 my ( $self, $response ) = @_;
487              
488 4 50 33     14 return 1 if ref $response eq 'HASH' && !keys %{$response};
  0         0  
489 4 50 33     11 return 1 if ref $response eq 'ARRAY' && @{$response} == 0;
  0         0  
490 4         11 return;
491             }
492              
493             sub _post_request {
494 0     0   0 my ( $self, $params, $sig, $raw_data, $filename ) = @_;
495              
496 0         0 my $post_params = [ map { $_ => $params->{$_} } sort keys %{$params} ];
  0         0  
  0         0  
497 0         0 push @{$post_params}, 'sig' => $sig;
  0         0  
498              
499 0 0       0 if ($raw_data) {
500 0   0     0 push @{$post_params}, data => [
  0         0  
501             undef, ( $filename || 'filename'),
502             'Content-Type' => 'application/octet-stream',
503             'Content' => $raw_data,
504             ];
505             }
506 0         0 return $self->ua->post(
507             $self->server_uri,
508             'Content_type' => 'form-data',
509             'Content' => $post_params,
510             )->content;
511             }
512              
513             1; # Magic true value required at end of module
514             __END__