Newer
Older
Dave Cohen
committed
<?php
/**
* @file
*
* Helpers for Facebook feeds (http://wiki.developers.facebook.com/index.php/New_Design_Feed_Wall)
*/
define('FB_FEED_LINES_PER_BUNDLE', 3);
define('FB_FEED_SHORTS_PER_BUNDLE', 3);
define('FB_FEED_FULLS_PER_BUNDLE', 1); // Facebook allows only 1
define('FB_FEED_NODE_TYPE_TEMPLATE', 'fb_feed_template');
define('FB_FEED_HOOK', 'fb_feed');
define('FB_FEED_OP_TOKEN_ALTER', 'fb_feed_token_alter');
function fb_feed_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array('path' => 'fb_feed/register',
'title' => t('Register template'),
'type' => MENU_CALLBACK,
'access' => user_access('administer fb apps'),
'callback' => 'fb_feed_register_cb',
);
$items[] = array('path' => 'fb_feed/deactivate',
'title' => t('Deactivate template'),
'type' => MENU_CALLBACK,
'access' => user_access('administer fb apps'),
'callback' => 'drupal_get_form',
'callback arguments' => array('fb_feed_deactivate_confirm'),
);
Dave Cohen
committed
}
else {
if (arg(0) == 'node' && is_numeric(arg(1))) {
$node = node_load(arg(1));
if ($node->type == 'fb_app') {
$fb_app_data = fb_app_get_data($node->fb_app);
$items[] = array('path' => "node/$node->nid/fb_feed/templates",
'title' => t('Feed Templates'),
'type' => MENU_LOCAL_TASK,
'access' => node_access('update', $node),
'callback' => 'fb_feed_template_page',
'callback arguments' => array($node->nid),
);
}
}
}
return $items;
}
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
function fb_feed_deactivate_confirm($fb_app_nid, $bundle_id) {
$result = db_query("SELECT n.nid, n.title FROM {node} n LEFT JOIN {fb_feed_template} fft ON fft.nid = n.nid WHERE fft.fb_app_nid = %d AND fft.bundle_id = %d",
$fb_app_nid, $bundle_id);
$data = db_fetch_object($result);
if ($data->nid) {
$form['nid'] = array('#type' => 'hidden', '#value' => $data->nid);
$description = t('This will deactivate the template on Facebook. The template node will not be deleted.');
$question = t('Really deactivate the !template_link template?',
array('!template_link' => l($data->title, 'node/'.$data->nid)));
}
else
$question = t('Really deactivate template bundle %bundle_id?',
array('%bundle_id' => $bundle_id));
$form['bundle_id'] = array('#type' => 'hidden',
'#value' => $bundle_id);
$form['fb_app_nid'] = array('#type' => 'hidden',
'#value' => $fb_app_nid);
return confirm_form($form, $question, 'node/'.$fb_app_nid.'/fb_feed/templates',
$description);
}
function fb_feed_deactivate_confirm_submit($form_id, $values) {
$success = fb_feed_deactivate_template($values['fb_app_nid'], $values['bundle_id']);
if ($success && $values['nid'])
db_query("UPDATE {fb_feed_template} SET bundle_id=0 WHERE nid=%d",
$values['nid']);
if ($success) {
drupal_set_message(t('The template %bundle_id has been deactivated.',
array('%bundle_id' => $values['bundle_id'])));
}
else {
drupal_set_message(t('The template %bundle_id could not be deactivated.',
array('%bundle_id' => $values['bundle_id'])), 'error');
}
return 'node/'.$values['fb_app_nid'].'/fb_feed/templates';
}
function fb_feed_deactivate_template($fb_app_nid, $bundle_id) {
Dave Cohen
committed
$fb_app = fb_get_app(array('nid' => $fb_app_nid));
$fb = fb_api_init($fb_app, FB_FBU_ANY);
if (!$fb) {
drupal_set_message(t('Facebook API failed to connect. Template could not be deactivated.', 'error'));
return FALSE;
}
else {
$result = $fb->api_client->feed_deactivateTemplateBundleByID($bundle_id);
fb_report_errors($fb, 'Error while deactivating template.');
}
return $result;
}
function fb_feed_register_cb($nid) {
$node = node_load($nid);
$bundle_id = fb_feed_register_template($node);
drupal_goto('node/'.$node->fb_app_nid.'/fb_feed/templates');
}
Dave Cohen
committed
function fb_feed_template_page($fb_app_nid) {
$registered = array();
$unregistered = array();
// Query all known templates
$result = db_query("SELECT n.nid, n.title, n.status, fft.bundle_id FROM {node} n LEFT JOIN {fb_feed_template} fft ON fft.nid = n.nid WHERE fft.nid IS NOT NULL");
while ($data = db_fetch_object($result)) {
if ($data->bundle_id) {
$registered[$data->bundle_id] = $data;
}
else {
$unregistered[] = $data;
}
}
Dave Cohen
committed
// Query facebook for a list of registered templates we know nothing about.
$fb_app = fb_get_app(array('nid' => $fb_app_nid));
$fb = fb_api_init($fb_app, FB_FBU_ANY);
if ($fb) {
$all = $fb->api_client->feed_getRegisteredTemplateBundles();
if (is_array($all))
foreach ($all as $data) {
if (isset($registered[$data['template_bundle_id']])) {
$registered[$data['template_bundle_id']]->confirmed = $data;
}
else
$registered[$data['template_bundle_id']] = $data;
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
}
}
else {
drupal_set_message("Facebook API not available. Some options will not be shown. Possible infinite session configuration problem.", 'error');
}
// Display one table of registered templates and another of unregistered.
if (count($unregistered)) {
$rows = array();
foreach ($unregistered as $data) {
$ops = array(l(t('register'), 'fb_feed/register/'.$data->nid));
$row = array(l($data->title, 'node/'.$data->nid),
implode(' | ', $ops));
$rows[] = $row;
}
$header = array(t('Unregistered Template'), t('Operations'));
$output .= theme('table', $header, $rows);
}
if (count($registered)) {
$rows = array();
foreach ($registered as $data) {
$ops = array();
if ($data->confirmed)
$ops[] = l(t('deactivate'), 'fb_feed/deactivate/'.$fb_app->nid.'/'.$data->bundle_id);
else if ($data->nid && $fb && is_array($all))
$ops = array(l(t('re-register'), 'fb_feed/register/'.$data->nid));
else if ($data['template_bundle_id'])
$ops[] = l(t('deactivate'), 'fb_feed/deactivate/'.$fb_app->nid.'/'.$data['template_bundle_id']);
if ($data->nid)
$title = l($data->title, 'node/'.$data->nid);
else
// Use a template learned from facebook.
$title = $data['one_line_story_templates'][0];
if ($data->bundle_id)
$bundle_id = $data->bundle_id;
else
$bundle_id = $data['template_bundle_id'];
$row = array($title,
$bundle_id,
implode(' | ', $ops),
);
$rows[] = $row;
}
$header = array(t('Registered Template'), t('Bundle ID'), t('Operations'));
$output .= theme('table', $header, $rows);
}
return $output;
Dave Cohen
committed
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
}
/**
* hook_node_info.
*/
function fb_feed_node_info() {
return array(FB_FEED_NODE_TYPE_TEMPLATE =>
array('name' => t('Facebook Template Bundle'),
'module' => 'fb_feed',
'description' => t('Templates for posting information to Facebook feeds.'),
'help' => t('Configure the feed stories of your Facebook Application.'),
),
);
}
/**
* Use same permissions as fb_app module.
*/
function fb_feed_access($op, $node) {
if (user_access('administer fb apps'))
return TRUE;
if ($op == 'create' && user_access('create fb apps'))
return TRUE;
else if ($op == 'update' || $op == 'delete') {
if ($node->uid == $user->uid &&
user_access('edit own fb apps'))
return TRUE;
}
}
function fb_feed_form(&$node, &$param) {
$form = array();
$type = node_get_types('type', $node);
// We need to define form elements for the node's title and body.
$form['title'] = array('#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5,
'#description' => t('Identifies the template bundle to site administrators.'),
);
if ($type->body_label) {
$form['body_filter']['body'] =
array('#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => $node->body,
'#required' => FALSE,
'#description' => 'Not sure yet how this will be used.',
);
$form['body_filter']['filter'] = filter_form($node->format);
}
Dave Cohen
committed
// Now we define the form elements specific to our node type.
$options = fb_get_app_options(FALSE);
$form['fb_app_nid'] =
array('#type' => 'select',
'#title' => t('Application'),
'#default_value' => $values['fb_app_nid'],
'#options' => $options,
'#description' => t('Which application will use these templates?<br />'),
Dave Cohen
committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
'#weight' => -5,
'#required' => TRUE,
);
$form['fb_feed_data'] = array('#tree' => TRUE,
'#weight' => -4,
);
$form['fb_feed_data']['description'] =
array('#type' => 'markup',
'#value' => t('Read <a target=_blank href="!url">about template bundles</a> for more information.',
array('!url' => 'http://wiki.developers.facebook.com/index.php/Feed.registerTemplateBundle')),
);
$form['fb_feed_data']['example'] =
array('#type' => 'markup',
'#value' => t('Here\'s an example that produces a message like "<em>User Name</em> wrote about <em>something</em> on <em>application</em>," where <em>something</em> is the title of a node:<br/><em>{*actor*} wrote about {*title*} on {*fb-app-title*}</em>'),
);
$form['fb_feed_data']['line'] = array('#type' => 'fieldset',
'#title' => t('One-line templates'),
'#description' => t('Note that all one-line templates must begin with the {*actor*} token.'),
'#collapsible' => TRUE,
);
$i = 0;
while ($i < FB_FEED_LINES_PER_BUNDLE) {
$form['fb_feed_data']['line'][$i] =
array('#type' => 'textfield',
'#title' => t('Additional one-line template'),
'#default_value' => $node->fb_feed_data['line'][$i],
);
$i++;
}
$form['fb_feed_data']['line'][0]['#title'] = t('Primary one-line template');
$form['fb_feed_data']['line'][0]['#required'] = TRUE;
$form['fb_feed_data']['short'] = array('#type' => 'fieldset',
'#title' => t('Short templates'),
'#description' => t('Note that each title must begin with the {*actor*} token.'),
'#collapsible' => TRUE,
);
$i = 0;
while ($i < FB_FEED_SHORTS_PER_BUNDLE) {
$form['fb_feed_data']['short'][$i]['template_title'] =
array('#type' => 'textfield',
'#title' => t('Additional short template title'),
'#default_value' => $node->fb_feed_data['short'][$i]['template_title'],
);
$form['fb_feed_data']['short'][$i]['template_body'] =
array('#type' => 'textarea',
'#title' => t('Additional short template body'),
'#default_value' => $node->fb_feed_data['short'][$i]['template_body'],
'#rows' => 2,
);
$i++;
}
$form['fb_feed_data']['short'][0]['template_title']['#title'] = t('Primary short template title');
$form['fb_feed_data']['short'][0]['template_body']['#title'] = t('Primary short template body');
$form['fb_feed_data']['full'] = array('#type' => 'fieldset',
'#title' => t('Full template'),
'#description' => t(''),
'#collapsible' => TRUE,
);
$form['fb_feed_data']['full']['template_title'] =
array('#type' => 'textfield',
'#title' => t('Full template title'),
'#default_value' => $node->fb_feed_data['full']['template_title'],
);
$form['fb_feed_data']['full']['template_body'] =
array('#type' => 'textarea',
'#title' => t('Full template body'),
'#default_value' => $node->fb_feed_data['full']['template_body'],
Dave Cohen
committed
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
'#rows' => 8,
);
// TODO: If token module enabled
$form['token_help'] = array('#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t("Token help"),
'#description' => t('Facebook uses the special token {*actor*} for the user performing an action, and {*target*} when the action applies to one (or more) of actor\'s friends. Otherwise, It is recommended to name your tokens as you would with the token module. Remember that in Facebook templates you use {*<em>token</em>*} syntax.'),
);
foreach (array('node', 'comment', 'user', 'fb_app') as $type) {
$form['token_help'][$type] =
array('#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t("!type tokens", array('!type' => $type)),
'#description' => theme('token_help', $type, "{*", "*}"),
);
}
return $form;
}
function fb_feed_validate($node) {
// TODO
}
function fb_feed_register_template($node) {
$fb_app = fb_get_app(array('nid' => $node->fb_app_nid));
// Login to facebook as either the current user or the infinite session
Dave Cohen
committed
$fb = fb_api_init($fb_app, FB_FBU_ANY);
if ($fb) {
// Clean up the data before sending to facebook. Send no empty templates.
$lines = array();
foreach ($node->fb_feed_data['line'] as $line) {
if ($line)
$lines[] = $line;
}
$shorts = array();
foreach ($node->fb_feed_data['short'] as $item) {
if ($item['template_title'])
$shorts[] = $item;
}
$full = array();
if ($node->fb_feed_data['full']['template_title'])
$full = $node->fb_feed_data['full'];
// TODO: wrap in try-catch
$bundle_id =
$fb->api_client->feed_registerTemplateBundle($lines, $shorts, $full);
fb_report_errors($fb, t('Error attempting to register template bundle.'));
drupal_set_message(t('Registered template bundle %bundle_id with Facebook.',
array('%bundle_id' => $bundle_id)));
if ($bundle_id && $node->nid)
db_query("UPDATE {fb_feed_template} fft SET bundle_id=%d WHERE nid=%d",
$bundle_id, $node->nid);
return $bundle_id;
}
}
Dave Cohen
committed
}
// TODO: report failure to connect to facebook api
drupal_set_message(t('Failed to connect to Facebook for application %app.',
array('%app' => $fb_app->title)), 'error');
Dave Cohen
committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
}
function fb_feed_insert($node) {
// Register the new template with facebook.
$bundle_id = fb_feed_register_template($node);
if (!$bundle_id)
// Show an error, but save the node anyway.
drupal_set_message(t('Failed to register template bundle with Facebook. This template bundle may not be used.'), 'error');
$data = serialize($node->fb_feed_data);
// We're going to save the apikey, although it may be redundant with the
// fb_app_nid, so that we can detect any inconsistencies (i.e. the apikey
// has changed on us).
$fb_app = fb_get_app(array('nid' => $node->fb_app_nid));
db_query("INSERT INTO {fb_feed_template} (nid, fb_app_nid, apikey, bundle_id, fb_feed_data) VALUES (%d, %d, '%s', %d, '%s')",
$node->nid, $node->fb_app_nid, $fb_app->apikey, $bundle_id, $data);
if ($bundle_id)
watchdog('fb_feed', t('Registered Facebook feed template bundle %id for application %app',
array('%id' => $bundle_id,
'%app' => $fb_app->title,
)));
}
function fb_feed_update($node) {
//dpm($node, "fb_feed_update");
// deactivate the previously registered bundle
if ($node->bundle_id) {
fb_feed_deactivate_template($node->fb_app_nid, $node->bundle_id);
unset($node->bundle_id);
}
Dave Cohen
committed
// Register the new template with facebook.
$bundle_id = fb_feed_register_template($node);
if (!$bundle_id)
// Show an error, but save the node anyway.
drupal_set_message(t('Failed to register template bundle with Facebook. This template bundle may not be used.'), 'error');
$data = serialize($node->fb_feed_data);
// We're going to save the apikey, although it may be redundant with the
// fb_app_nid, so that we can detect any inconsistencies (i.e. the apikey
// has changed on us).
$fb_app = fb_get_app(array('nid' => $node->fb_app_nid));
Dave Cohen
committed
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
db_query("UPDATE {fb_feed_template} SET fb_app_nid=%d, apikey='%s', bundle_id=%d, fb_feed_data='%s' WHERE nid=%d",
$node->fb_app_nid, $fb_app->apikey, $bundle_id, $data, $node->nid);
if ($bundle_id)
watchdog('fb_feed', t('Updated Facebook feed template bundle %id for application %app',
array('%id' => $bundle_id,
'%app' => $fb_app->title,
)));
}
function fb_feed_delete($node) {
// TODO: deactivate the previously registered bundle
db_query('DELETE FROM {fb_feed_template} WHERE nid=%d',
$node->nid);
}
function fb_feed_load($node) {
$data = db_fetch_array(db_query('SELECT fb_app_nid, apikey, bundle_id, fb_feed_data FROM {fb_feed_template} WHERE nid=%d',
$node->nid));
$data['fb_feed_data'] = unserialize($data['fb_feed_data']);
return $data;
}
// TODO: hook_nodeapi. React appropriately if fb_app apikey changes or is deleted.
function fb_feed_view($node, $teaser=FALSE, $page=FALSE) {
$node = node_prepare($node, $teaser);
$fb_app = fb_get_app(array('nid' => $node->fb_app_nid));
if (!$node->bundle_id)
drupal_set_message(t('The template shown must be registered with Facebook before it can be used.'), 'error');
Dave Cohen
committed
$items = array(t('Application') => l($fb_app->title, 'node/'.$fb_app->nid),
t('Template Bundle ID') => $node->bundle_id ? $node->bundle_id : '<em>'.t('Template bundle not registered') . '</em>',
Dave Cohen
committed
);
$items[t('One-line templates')] = implode("<br />\n", $node->fb_feed_data['line']);
foreach ($node->fb_feed_data['short'] as $key => $template) {
if (is_array($template))
$items[t('Short template %num', array('%num' => $key +1))] =
implode("<br />\n", $node->fb_feed_data['short'][$key]);
Dave Cohen
committed
}
Dave Cohen
committed
if ($node->fb_feed_data['full']['template_title']) {
$items[t('Full template')] =
implode("<br />\n", $node->fb_feed_data['full']);
}
$node->content['fb_feed'] = array('#value' => theme('dl', $items));
return $node;
}
//// Feed Actions
function fb_feed_action_info() {
$items = array();
$items['fb_feed_action_publish'] = array(
'type' => 'fb_feed_action',
'description' => t('Facebook Feed: publishUserAction'),
'configurable' => TRUE,
// Include 'custom' so third-party modules can define their own triggers.
'hooks' => array(
'nodeapi' => array('delete', 'insert', 'update', 'view', 'custom'),
'comment' => array('delete', 'insert', 'update', 'view', 'custom'),
'user' => array('insert', 'update', 'delete', 'login', 'logout', 'custom'),
),
);
Dave Cohen
committed
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
return $items;
}
function fb_feed_get_template_options() {
$options = array(0 => t('<please choose>'));
$result = db_query(db_rewrite_sql("SELECT DISTINCT n.nid, n.title FROM {node} n WHERE n.type='%s' AND n.status=1"), FB_FEED_NODE_TYPE_TEMPLATE);
while ($data = db_fetch_object($result)) {
$options[$data->nid] = $data->title;
}
return $options;
}
function fb_feed_action_publish_form($values) {
// Allow user to choose amoung all available templates.
$options = fb_feed_get_template_options();
$form['description'] = array('#value' => t('Note that this action will only succeed when executed from a Facebook canvas page when the user is logged in, or on non-canvas pages when the local user has authorized offline access. These are privacy restrictions enforced by the Facebook API.'));
$form['fb_feed_template_nid'] =
array('#type' => 'select',
'#title' => t('Template'),
'#default_value' => $values['fb_feed_template_nid'],
'#options' => $options,
'#description' => t('Which template will we be using?'),
'#required' => TRUE,
);
$form['token_enable'] =
array('#type' => 'checkbox',
'#title' => t('Use token replacement'),
'#default_value' => $values['token_enable'],
'#description' => t('Use token module for template substitution.'),
);
$form['hook_help'] =
array('#type' => 'markup',
'#value' => t('In addition to token replacement, <em>hook_fb_feed</em> will be called before Feed.publishUserAction is called. This hook gives you an oportunity to customize the parameters that will be passed to Facebook, for example to provide values for custom tokens in your template. Until further documentation is provided, you should look in the code for exactly how these functions are called.'),
'#prefix' => '<p>',
'#suffix' => '</p>',
);
return $form;
}
function fb_feed_action_publish_validate($form_id, $values) {
// TODO
}
function fb_feed_action_publish_submit($form_id, $values) {
$items = array();
foreach (array('fb_feed_template_nid', 'token_enable') as $key) {
$items[$key] = $values[$key];
}
return $items;
}
function fb_feed_action_publish(&$context, $values = array()) {
Dave Cohen
committed
//dpm(func_get_args(), 'fb_actions_minifeed');
// Get the objects we're acting upon.
Dave Cohen
committed
if ($values['hook'] == 'nodeapi') {
$objects['node'] = $values['node'];
Dave Cohen
committed
}
else if ($values['hook'] == 'comment') {
$objects['comment'] = $values['comment'];
$objects['node'] = node_load($values['comment']->nid);
Dave Cohen
committed
}
else if ($values['hook'] == 'user') {
$account = $values['user'];
Dave Cohen
committed
}
// Get the template
$template = node_load($values['fb_feed_template_nid']);
// TODO: Sanity check that bundle has been registered with Facebook.
// And the app
$fb_app = fb_get_app(array('nid' => $template->fb_app_nid));
Dave Cohen
committed
// TODO: Sanity check that apikeys match.
Dave Cohen
committed
// Log into facebook as the current user.
if ($GLOBALS['fb_app'] && ($fb_app->nid = $GLOBALS['fb_app']->nid))
// We're in a canvas page for the desired app. We're already logged in.
$fb = $GLOBALS['fb'];
else {
global $user;
// Must log in to publish user action. This will only work if the user
// have authorized us for offline access.
$fbu = fb_get_fbu($user->uid, $fb_app);
if ($fbu) {
$fb = fb_api_init($fb_app, $fbu);
}
}
// It's possible we have an $fb, but session may not be valid. TODO: find a
// way to test this?
if ($fb) {
// We need to pass a bunch of parameters to Feed.publishUserAction.
$params = array('bundle_id' => $template->bundle_id,
'tokens' => array(),
Dave Cohen
committed
'body_general' => '',
Dave Cohen
committed
);
$options = array('fb_feed_template' => $template);
if ($values['token_enable']) {
// Use tokens for every kind of object we know about
foreach (array('node', 'comment', 'user', 'fb_app') as $type) {
if ($objects[$type]) {
$toks = token_get_values($type, $objects[$type], FALSE, $options);
//watchdog('fb_feed_debug', "token_get_values($type) returned " . dprint_r($toks, 1));
if ($toks && is_array($toks->tokens)) {
foreach ($toks->tokens as $i => $key)
$params['tokens'][$key] = $toks->values[$i];
}
}
Dave Cohen
committed
}
}
// Use naming conventions to allow tokens to provide every parameter.
if ($params['tokens']['target_ids'])
$params['target_ids'][] = $params['tokens']['target_ids'];
Dave Cohen
committed
if ($params['tokens']['body_general'])
$params['target_ids'] = $params['tokens']['body_general'];
// Invoke a hook so that other modules have a chance to modify the params before we pass them to facebook.
$params = fb_feed_invoke($fb_app, FB_FEED_OP_TOKEN_ALTER,
$params, array('fb_feed_template' => $template,
'objects' => $objects,
'context' => $context));
Dave Cohen
committed
if (fb_verbose()) {
watchdog('fb_feed', t("Publish user action, app is %app, bundle is %bundle_id, params are !params.",
array('%app' => $fb_app->title,
'%bundle_id' => $template->bundle_id,
'!params' => dprint_r($params, 1))));
}
if (is_array($params['tokens']) && $params['do_publish']) {
if (is_array($params['target_ids']))
$target_ids = implode(',', $params['target_ids']);
else
$target_ids = $params['target_ids'];
try {
// http://wiki.developers.facebook.com/index.php/Feed.publishUserAction
//if (FALSE) // disabled for debugging
$fb->api_client->feed_publishUserAction($template->bundle_id,
json_encode($params['tokens']),
$target_ids,
$params['body_general']);
} catch (Exception $e) {
// We can get a lot of "Feed action limit reached" exceptions. So
// only log if fb_verbose is true.
if ($e->getCode() != 341 || fb_verbose())
fb_log_exception($e, t('Failed to publish user action'));
}
Dave Cohen
committed
}
}
}
function fb_feed_fb_feed($fb_app, $op, &$return, $data) {
if ($op == FB_FEED_OP_TOKEN_ALTER) {
Dave Cohen
committed
// In this hook, we have a chance to add tokens before a user action is
// published.
if ($return['tokens']['nid'] && $return['tokens']['title'] &&
$return['tokens']['fb-app-url']) {
// Add a link to a canvas page
$return['tokens']['fb-feed-node-link'] = l($return['tokens']['title-raw'],
$return['tokens']['fb-app-url'].'/node/'.$return['tokens']['nid'],
array(), NULL, NULL, NULL, TRUE);
Dave Cohen
committed
}
if ($return['tokens']['fb-app-title'] && $return['tokens']['fb-app-url']) {
$return['tokens']['fb-feed-app-link'] = l($return['tokens']['fb-app-title'],
$return['tokens']['fb-app-url'],
array(), NULL, NULL, NULL, TRUE);
Dave Cohen
committed
}
}
}
/**
* Invoke hook_fb.
*/
function fb_feed_invoke($fb_app, $op, $return = NULL, $data = NULL) {
foreach (module_implements(FB_FEED_HOOK) as $name) {
$function = $name . '_' . FB_FEED_HOOK;
$function($fb_app, $op, $return, $data);
}
return $return;
}
?>