| Commit | Line | Data |
|---|---|---|
| 67523320 | 1 | <?php |
| 456be90c DC |
2 | /** |
| 3 | * @file | |
| 4 | * Admin pages and forms for facebook applications. | |
| 19092d2f | 5 | * |
| 456be90c | 6 | */ |
| 67523320 DC |
7 | |
| 8 | include drupal_get_path('module', 'fb') . '/fb.admin.inc'; | |
| 9 | ||
| 10 | /** | |
| 3cf45120 | 11 | * Implements hook_fb_admin(). |
| 67523320 DC |
12 | */ |
| 13 | function fb_app_fb_admin($op, $data, &$return) { | |
| 14 | $fb = isset($data['fb']) ? $data['fb'] : NULL; | |
| 15 | $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL; | |
| 19092d2f | 16 | |
| 67523320 DC |
17 | if ($op == FB_ADMIN_OP_SET_PROPERTIES) { |
| 18 | // URLs for Facebook events we support. | |
| 7afb2a55 | 19 | $return['uninstall_url'] = url(FB_APP_PATH_EVENT . '/' . $fb_app->label . "/" . FB_APP_EVENT_POST_REMOVE . '/', |
| f54b3a2b | 20 | array('absolute' => TRUE)); |
| 7afb2a55 | 21 | $return['authorize_url'] = url(FB_APP_PATH_EVENT . '/' . $fb_app->label . "/" . FB_APP_EVENT_POST_AUTHORIZE . '/', |
| f54b3a2b | 22 | array('absolute' => TRUE)); |
| 67523320 | 23 | } |
| 456be90c | 24 | elseif ($op == FB_ADMIN_OP_LIST_PROPERTIES) { |
| 67523320 DC |
25 | $return[t('Application Name')] = 'application_name'; |
| 26 | $return[t('About URL')] = 'about_url'; | |
| 27 | $return[t('Post-Authorize Callback URL')] = 'authorize_url'; | |
| 28 | $return[t('Post-Remove Callback URL')] = 'uninstall_url'; | |
| 29 | // Learn canvas name regardless of whether fb_canvas is enabled. | |
| 30 | $return[t('Canvas Name')] = 'canvas_name'; | |
| 31 | } | |
| 29be740a | 32 | elseif (($op == FB_ADMIN_OP_LOCAL_LINKS) && isset($fb_app->fba_id)) { |
| 67523320 | 33 | // Path to edit this app. |
| 29be740a | 34 | $return[t('edit')] = FB_PATH_ADMIN_APPS . '/' . $fb_app->label . '/fb_app'; |
| 67523320 DC |
35 | } |
| 36 | } | |
| 37 | ||
| 38 | /** | |
| 39 | * Builds the form used to edit an application. | |
| f77127b5 DC |
40 | * |
| 41 | * This form supports both create and edit. | |
| 67523320 | 42 | */ |
| 3cf45120 | 43 | function fb_app_edit_form($form, $form_state, $fb_app = NULL) { |
| f77127b5 DC |
44 | // If app is managed by this module, it has fba_id. |
| 45 | if (isset($fb_app) && !$fb_app->fba_id) { | |
| 29be740a | 46 | drupal_set_message(t('Application %label not found.', array( |
| fa767fc5 | 47 | '%label' => $fb_app->label)), |
| 6178c18c | 48 | 'warning'); |
| f77127b5 DC |
49 | drupal_not_found(); |
| 50 | exit(); | |
| 67523320 | 51 | } |
| 19092d2f | 52 | |
| 67523320 | 53 | if (!isset($fb_app)) { |
| 29be740a DC |
54 | // Defaults for new app. |
| 55 | $fb_app = (object) array( | |
| 56 | 'label' => NULL, | |
| b3adf089 | 57 | 'apikey' => NULL, // deprecated. |
| 29be740a DC |
58 | 'canvas' => NULL, |
| 59 | 'fba_id' => NULL, | |
| 60 | 'id' => NULL, | |
| 61 | 'status' => 1, | |
| 62 | 'data' => serialize(array('fb_app' => array('set_app_props' => TRUE))), | |
| 63 | ); | |
| 64 | //drupal_set_title(t('Create Facebook Application')); | |
| 67523320 DC |
65 | } |
| 66 | else { | |
| f77127b5 | 67 | //drupal_set_title(t('Edit %label', array('%label' => $fb_app->label))); |
| 67523320 | 68 | } |
| 19092d2f DC |
69 | |
| 70 | $form['#fb_app'] = $fb_app; // Similar to #node | |
| 71 | ||
| f77127b5 | 72 | //$form['#node'] = (object) array('fb_app' => $fb_app); // deprecated! backward compatibility! |
| 19092d2f | 73 | |
| f77127b5 | 74 | if (!$fb_app->label) { |
| 67523320 DC |
75 | // Helpful link |
| 76 | // http://wiki.developers.facebook.com/index.php/How_To_Write_A_Good_Connect_Plugin | |
| 77 | $helptext = '<ol> | |
| 78 | <li>Visit the Facebook application creation page: <a target="_blank" href="http://www.facebook.com/developers/createapp.php">http://www.facebook.com/developers/createapp.php</a>.</li> | |
| 79 | <li>Enter a descriptive name in the Application Name field. Users will see this when signing up for your site.</li> | |
| 80 | <li>Accept the Facebook Terms of Service.</li> | |
| 81 | <li>If building a Canvas Page App, specify a Canvas Path.</li> | |
| 82 | <li>Upload icon and logo images. The icon appears in News Feed stories and the logo appears in the Connect dialog when the user connects with your site.</li> | |
| 83 | <li>Click Submit.</li> | |
| b3adf089 | 84 | <li>Copy the displayed App ID and Application Secret into this form.</li> |
| 67523320 DC |
85 | </ol>'; |
| 86 | ||
| 87 | $form['helptext'] = array( | |
| 3cf45120 | 88 | '#markup' => t($helptext), |
| 67523320 DC |
89 | '#weight' => -10, |
| 90 | ); | |
| 1240cc5f DC |
91 | $form['helptext2'] = array( |
| 92 | '#markup' => t('It is recommended to administer drupal in one browser (this one) and log into facebook in another browser, so no cookies are shared. So for example if using Chrome, follow the create app link above in an incognito window.'), | |
| 93 | '#prefix' => '<p><em>', '#suffix' => '</em></p>', | |
| 94 | ); | |
| 95 | ||
| 67523320 | 96 | } |
| 19092d2f | 97 | |
| 67523320 DC |
98 | $form['label'] = array( |
| 99 | '#type' => 'textfield', | |
| 100 | '#title' => t('Label'), | |
| 101 | '#required' => TRUE, | |
| 102 | '#default_value' => $fb_app->label, | |
| f17f7dff | 103 | '#description' => t('A short name for this application. Use letters and numerals only (no spaces, etc). <br/>Module code may refer to this label, in order to customize the behavior of this app.<br/>When working with multiple copies of an application (i.e. development, staging, production), use the <strong>same label</strong> on all servers. Apikey, secret and ID will change from server to server, but <strong>the label remains the same</strong>.'), |
| 67523320 DC |
104 | ); |
| 105 | $form['status'] = array( | |
| 106 | '#type' => 'checkbox', | |
| 107 | '#title' => t('Enabled'), | |
| 108 | '#default_value' => $fb_app->status, | |
| f17f7dff | 109 | '#description' => t('Uncheck if this server no longer hosts this application, but you prefer not to delete the settings.'), |
| 67523320 | 110 | ); |
| 0c4a9f92 DC |
111 | |
| 112 | // ID, apikey and secret are shown on facebook. User copies and pastes values. | |
| f7e75cc6 DC |
113 | $form['id'] = array( |
| 114 | '#type' => 'textfield', | |
| 115 | '#title' => t('Facebook App ID'), | |
| 49c58876 | 116 | '#required' => TRUE, |
| f7e75cc6 DC |
117 | '#default_value' => $fb_app->id, |
| 118 | '#description' => t('Facebook will generate this value when you create the application.'), | |
| 119 | ); | |
| 67523320 DC |
120 | $form['secret'] = array( |
| 121 | '#type' => 'textfield', | |
| 122 | '#title' => t('Secret'), | |
| 123 | '#required' => TRUE, | |
| d8f85b06 | 124 | '#default_value' => isset($fb_app->secret) ? $fb_app->secret : NULL, |
| 67523320 DC |
125 | '#description' => t('Facebook will generate this value when you create the application.'), |
| 126 | ); | |
| 19092d2f | 127 | |
| 67523320 | 128 | // fb_app_data is a placeholder where other modules can attach settings. |
| 19092d2f DC |
129 | $form['fb_app_data'] = array('#tree' => TRUE); |
| 130 | ||
| 67523320 DC |
131 | // Add our own fields to fb_app_data. Other modules use hook_form_alter to do this. |
| 132 | ||
| 133 | $data = fb_get_app_data($fb_app); | |
| 134 | $form['fb_app_data']['fb_app']['set_app_props'] = array( | |
| f7951091 | 135 | '#type' => 'checkbox', |
| 038f3ecf | 136 | '#title' => t('Set application properties automatically'), |
| f17f7dff | 137 | '#default_value' => isset($data['fb_app']) ? $data['fb_app']['set_app_props'] : NULL, |
| f404514e | 138 | '#description' => t('Synchronize Facebook settings for this application when you save this form. Disable this if you have customized your callback URL, or other settings on facebook.com. Also disable if another Drupal instance hosts the same application (i.e. with shared subdomain).'), |
| 67523320 | 139 | ); |
| 09898fe2 DC |
140 | |
| 141 | $form['buttons'] = array(); | |
| 142 | $form['buttons']['submit'] = array( | |
| 67523320 DC |
143 | '#type' => 'submit', |
| 144 | '#value' => t('Save'), | |
| 09898fe2 | 145 | '#weight' => 5, |
| 3cf45120 | 146 | '#submit' => array('fb_app_admin_form_submit'), |
| 67523320 | 147 | ); |
| 19092d2f | 148 | |
| 09898fe2 DC |
149 | if ($fb_app->fba_id) { |
| 150 | $form['buttons']['delete'] = array( | |
| 151 | '#type' => 'submit', | |
| 152 | '#value' => t('Delete'), | |
| 153 | '#weight' => 15, | |
| 154 | '#submit' => array('fb_app_admin_form_delete_submit'), | |
| 155 | ); | |
| 156 | } | |
| 157 | ||
| 67523320 DC |
158 | return $form; |
| 159 | } | |
| 160 | ||
| 09898fe2 DC |
161 | /** |
| 162 | * Form validation. | |
| 163 | */ | |
| 67523320 | 164 | function fb_app_edit_form_validate($form, &$form_state) { |
| 09898fe2 | 165 | $fb_app = (object) $form_state['values']; |
| 67523320 | 166 | $fb_app->data = serialize($fb_app->fb_app_data); |
| 19092d2f | 167 | |
| 6178c18c | 168 | if ($form_state['values']['op'] != t('Delete')) { |
| f17f7dff | 169 | // Labels must be alphanumeric. |
| b389f367 DC |
170 | if (preg_match('/[^a-z0-9_]/', $fb_app->label)) { |
| 171 | form_error($form['label'], t('Label must be lower-case alphanumeric or underscores only.')); | |
| f17f7dff DC |
172 | } |
| 173 | ||
| 6178c18c DC |
174 | // Labels must be unique. |
| 175 | $apps = fb_get_all_apps(); | |
| 176 | foreach ($apps as $app) { | |
| 177 | if ($app->label == $fb_app->label && | |
| 178 | (!isset($form['#fb_app']) || $form['#fb_app']->label != $fb_app->label)) { | |
| 179 | form_set_error('fb_app][label', t('The label %label is in use by another application.', array( | |
| 180 | '%label' => $fb_app->label, | |
| 181 | ))); | |
| 182 | } | |
| 183 | } | |
| 184 | // Getting properties confirms apikey and secret. | |
| 185 | fb_admin_get_app_properties($fb_app); | |
| 186 | if (!$fb_app->application_name) { | |
| f404514e | 187 | // Don't use form_set_error(), as that will prevent the user from saving any data. |
| b3adf089 | 188 | drupal_set_message(t("Unable to get application properties. Possibly, you've given the wrong id or secret. Possibly, this server is unable to reach facebook's servers. Your application will not work properly!"), 'error'); |
| 51ecb79f | 189 | $fb_app->application_name = 'UNKOWN'; |
| 09898fe2 | 190 | } |
| 67523320 DC |
191 | } |
| 192 | } | |
| 193 | ||
| 09898fe2 | 194 | function fb_app_admin_form_submit($form, &$form_state) { |
| 67523320 DC |
195 | $fb_app = (object)$form_state['values']; |
| 196 | $fb_app->data = serialize($fb_app->fb_app_data); | |
| 19092d2f | 197 | |
| 29be740a DC |
198 | // Get canvas_name, application_name from facebook. |
| 199 | fb_admin_get_app_properties($fb_app); | |
| 19092d2f | 200 | |
| 0c4a9f92 | 201 | $orig_app = $form['#fb_app']; |
| 3cf45120 | 202 | |
| 0c4a9f92 | 203 | if ($orig_app->fba_id) { |
| 67523320 | 204 | // Updating. |
| 3cf45120 DC |
205 | try { |
| 206 | db_update('fb_app') | |
| 207 | ->fields(array( | |
| 208 | 'label' => $fb_app->label, | |
| 209 | 'status' => $fb_app->status, | |
| b3adf089 | 210 | 'apikey' => $fb_app->id, // Note, apikey deprecated. Using ID. |
| 3cf45120 DC |
211 | 'secret' => $fb_app->secret, |
| 212 | 'id' => $fb_app->id, | |
| 61ee6ce4 DC |
213 | // Canvas and title are learned from facebook, not the form. |
| 214 | 'canvas' => $fb_app->canvas_name ? $fb_app->canvas_name : '', | |
| 215 | 'title' => $fb_app->application_name ? $fb_app->application_name : $fb_app->label, | |
| 3cf45120 DC |
216 | 'data' => $fb_app->data, |
| 217 | )) | |
| 218 | ->condition('fba_id', $orig_app->fba_id) | |
| 219 | ->execute(); | |
| 220 | ||
| 221 | watchdog('fb_app', 'Updated Facebook Application %label.', | |
| 222 | array('%label' => $fb_app->label, | |
| 223 | ), | |
| 224 | WATCHDOG_NOTICE, | |
| 225 | l(t('view apps'), FB_PATH_ADMIN_APPS)); | |
| 226 | ||
| 227 | drupal_set_message(t('Saved changes to facebook application %title (%label).', | |
| 228 | array('%title' => $fb_app->application_name, | |
| 229 | '%label' => $fb_app->label))); | |
| 230 | } | |
| 231 | catch (Exception $e) { | |
| 232 | // Log the exception to watchdog. | |
| 233 | watchdog_exception('fb_app', $e); | |
| 19092d2f | 234 | |
| 3cf45120 DC |
235 | drupal_set_message(t('Failed to save changes to facebook application %title (%label). Check the log.', |
| 236 | array('%label' => $fb_app->label, | |
| 237 | '%title' => $fb_app->application_name))); | |
| 238 | } | |
| 67523320 DC |
239 | } |
| 240 | else { | |
| 241 | // Inserting. | |
| 3cf45120 DC |
242 | try { |
| 243 | db_insert('fb_app') | |
| 244 | ->fields(array( | |
| 61ee6ce4 DC |
245 | 'label' => $fb_app->label, |
| 246 | 'status' => $fb_app->status, | |
| b3adf089 | 247 | 'apikey' => $fb_app->id, // Note, apikey deprecated. Using ID. |
| 61ee6ce4 DC |
248 | 'secret' => $fb_app->secret, |
| 249 | 'id' => $fb_app->id, | |
| 250 | // Canvas and title are learned from facebook, not the form. | |
| 251 | 'canvas' => $fb_app->canvas_name ? $fb_app->canvas_name : '', | |
| 252 | 'title' => $fb_app->application_name ? $fb_app->application_name : $fb_app->label, | |
| 253 | 'data' => $fb_app->data, | |
| 254 | )) | |
| 3cf45120 DC |
255 | ->execute(); |
| 256 | ||
| b3adf089 DC |
257 | watchdog('fb_app', 'Created Facebook Application %label.', array( |
| 258 | '%label' => $fb_app->label, | |
| 3cf45120 DC |
259 | ), |
| 260 | WATCHDOG_NOTICE, | |
| 261 | l(t('view apps'), FB_PATH_ADMIN_APPS)); | |
| 262 | ||
| b3adf089 DC |
263 | drupal_set_message(t('Created facebook application %title (%label).', array( |
| 264 | '%label' => $fb_app->label, | |
| 265 | '%title' => $fb_app->application_name, | |
| 266 | ))); | |
| 3cf45120 DC |
267 | } |
| 268 | catch (Exception $e) { | |
| 269 | // Log the exception to watchdog. | |
| 270 | watchdog_exception('fb_app', $e); | |
| 271 | ||
| 272 | drupal_set_message(t('Failed to create facebook application %title (%label). Check the log.', | |
| 273 | array('%label' => $fb_app->label, | |
| 274 | '%title' => $fb_app->application_name))); | |
| 275 | } | |
| 67523320 | 276 | } |
| 19092d2f | 277 | |
| 831444a5 DC |
278 | if ($fb_app->status) { |
| 279 | fb_app_set_app_properties($fb_app); // Set callback URL, etc. | |
| 280 | } | |
| 19092d2f | 281 | |
| 67523320 DC |
282 | $form_state['redirect'] = FB_PATH_ADMIN; |
| 283 | } | |
| 284 | ||
| 285 | /** | |
| 09898fe2 DC |
286 | * Button submit function. Use has clicked delete, send them to confirm page. |
| 287 | */ | |
| 288 | function fb_app_admin_form_delete_submit($form, &$form_state) { | |
| 289 | $destination = ''; | |
| 290 | if (isset($_REQUEST['destination'])) { | |
| 291 | $destination = drupal_get_destination(); | |
| 292 | unset($_REQUEST['destination']); | |
| 293 | } | |
| 294 | $fb_app = $form['#fb_app']; | |
| 180c6450 | 295 | $form_state['redirect'] = array(FB_PATH_ADMIN_APPS . '/' . $fb_app->label . '/fb_app/delete', array('query' => $destination)); |
| 09898fe2 DC |
296 | } |
| 297 | ||
| 298 | ||
| 299 | /** | |
| 300 | * Form creator -- ask for confirmation of deletion | |
| 301 | */ | |
| 180c6450 | 302 | function fb_app_admin_delete_confirm_form($form, &$form_state, $fb_app) { |
| 09898fe2 DC |
303 | $form['fba_id'] = array( |
| 304 | '#type' => 'value', | |
| 305 | '#value' => $fb_app->fba_id, | |
| 306 | ); | |
| 19092d2f | 307 | |
| 09898fe2 DC |
308 | return confirm_form($form, |
| 309 | t('Are you sure you want to delete %title?', array('%title' => $fb_app->title)), | |
| 310 | isset($_GET['destination']) ? $_GET['destination'] : FB_PATH_ADMIN_APPS . '/' . $fb_app->label, | |
| 311 | t('This action cannot be undone.'), | |
| 312 | t('Delete'), | |
| 313 | t('Cancel') | |
| 314 | ); | |
| 315 | } | |
| 316 | ||
| 317 | /** | |
| 318 | * Execute node deletion | |
| 319 | */ | |
| 320 | function fb_app_admin_delete_confirm_form_submit($form, &$form_state) { | |
| 321 | if ($form_state['values']['confirm']) { | |
| 322 | $fba_id = $form_state['values']['fba_id']; | |
| 323 | ||
| f7951091 | 324 | // @TODO: invoke hooks so that third-party modules may act. |
| 19092d2f | 325 | |
| 3cf45120 DC |
326 | db_delete('fb_app') |
| 327 | ->condition('fba_id', $fba_id) | |
| 328 | ->execute(); | |
| 09898fe2 DC |
329 | } |
| 330 | ||
| 331 | $form_state['redirect'] = FB_PATH_ADMIN_APPS; | |
| 332 | } | |
| 333 | ||
| 334 | ||
| 335 | ||
| 336 | /** | |
| 19092d2f | 337 | * Sets callback URLs and other properties of a facebook app. Calls the facebook |
| 67523320 DC |
338 | */ |
| 339 | function fb_app_set_app_properties($fb_app) { | |
| 340 | $data = fb_get_app_data($fb_app); | |
| 341 | $fb_app_data = $data['fb_app']; | |
| 7ef49cce | 342 | // Collect properties from all modules. |
| 67523320 DC |
343 | $props = fb_invoke(FB_ADMIN_OP_SET_PROPERTIES, array('fb_app' => $fb_app), array(), FB_ADMIN_HOOK); |
| 344 | if (count($props)) { | |
| 345 | if ($fb_app_data['set_app_props']) { | |
| 3946309e | 346 | if ($fb = fb_api_init($fb_app)) { |
| 67523320 | 347 | try { |
| d3ef187d | 348 | $result = fb_call_method($fb, 'admin.setAppProperties', array( |
| 3946309e | 349 | 'properties' => json_encode($props), |
| 3946309e | 350 | )); |
| 52cc0254 | 351 | drupal_set_message(t('Note that it may take several minutes for property changes to propagate to all facebook servers.')); |
| 67523320 DC |
352 | if (fb_verbose()) { |
| 353 | drupal_set_message(t('Set the following properties for %label application:<br/><pre>!props</pre>', array('%label' => $fb_app->label, '!props' => print_r($props, 1)))); | |
| 354 | watchdog('fb_app', 'Set facebook app properties for %label.', | |
| 355 | array('%label' => $fb_app->label, | |
| 356 | ), | |
| 357 | WATCHDOG_NOTICE, | |
| 358 | l(t('view apps'), FB_PATH_ADMIN)); | |
| 359 | } | |
| 7ef49cce DC |
360 | |
| 361 | // Allow third-parties to set additional "properties" such as restrictions. | |
| 362 | fb_invoke(FB_ADMIN_OP_POST_SET_PROPERTIES, array( | |
| 363 | 'fb_app' => $fb_app, | |
| 364 | 'fb' => $fb, | |
| 365 | 'properties' => $props, | |
| 366 | ), array(), FB_ADMIN_HOOK); | |
| 67523320 | 367 | } catch (Exception $e) { |
| d3ef187d | 368 | drupal_set_message(t('Failed to set the following properties for %label application. You may need to manually editing remote settings!<br/><pre>!props</pre>', array('%label' => $fb_app->label, '!props' => print_r($props, 1))), 'error'); |
| 67523320 DC |
369 | fb_log_exception($e, t('Failed to set application properties on Facebook')); |
| 370 | } | |
| 371 | } | |
| 372 | } | |
| 456be90c | 373 | elseif (fb_verbose()) { |
| 09898fe2 | 374 | drupal_set_message(t('The following recommended properties for %label application have <strong>not been set automatically</strong>, consider editing remote settings manually:<br/><pre>!props</pre>', array('%label' => $fb_app->label, '!props' => print_r($props, 1))), 'warning'); |
| 67523320 DC |
375 | } |
| 376 | } | |
| 377 | } |