You are here

function action_fb_cron_per_user in Drupal for Facebook 5

File

./fb_cron.module, line 86
This module helps administer facebook-specific actions to be performed during cron jobs.

Code

function action_fb_cron_per_user($op, $edit = array(), $obj) {

  // The code in this function requires a lot of knowledge about the
  // fb_user_app table, fb globals and such.  So it really violates the data
  // separation between modules.  Is there a better place for it?  Or a better
  // way to build the APIs?
  if ($op == 'metadata') {
    return array(
      'description' => t('Facebook: user-specific actions'),
      'type' => t('Facebook App'),
      // Expects Facebook App as 3rd param
      'batchable' => FALSE,
      'configurable' => TRUE,
    );
  }
  else {
    if ($op == 'form') {
      $form['description'] = array(
        '#value' => t('This action will iterate through user\'s of a Facebook Application, attempt to log into the Facebook API as that user (or failing that, the infinite session user), and execute additional actions.  Use this to perform per-user actions during a Facebook cron job.'),
      );
      foreach (actions_get_all_actions() as $aid => $action) {
        $options[$action['type']][$aid] = $action['description'];
      }
      $form['actions'] = array(
        '#type' => 'select',
        '#title' => t('Actions'),
        '#default_value' => $edit['actions'],
        '#multiple' => TRUE,
        '#required' => TRUE,
        '#options' => $options,
        '#description' => t('Select one or more actions to perform while logged in as a Facebook Application user.'),
      );
      $form['throttle'] = array(
        '#type' => 'textfield',
        '#title' => t('Throttle'),
        '#default_value' => $edit['throttle'],
        '#required' => TRUE,
        '#description' => t('Number of users to iterate through each time this action is invoked.  Recommended: start with a small number and increase when you are sure things are working.'),
      );
      return $form;
    }
    else {
      if ($op == 'submit') {
        return array(
          'actions' => $edit['actions'],
          'throttle' => $edit['throttle'],
        );
      }
      else {
        if ($op == 'do') {

          // TODO: make sure the app is properly passed in.
          $fb_app = $obj;

          // Save current settings
          $before_fb = $GLOBALS['fb'];
          $before_fb_app = $GLOBALS['fb_app'];
          $before_user = $GLOBALS['user'];

          // Find some users of the app, for whom cron has not run recently.
          $result = db_query("SELECT * FROM {fb_user_app} WHERE apikey='%s' AND fbu > 0 AND added > 0 ORDER BY time_cron ASC LIMIT %d", $fb_app->apikey, $edit['throttle']);
          while ($data = db_fetch_object($result)) {

            // Log into facebook as the user from the database
            $account = fb_user_get_local_user($data->fbu, $fb_app);
            if (!$account || !$account->uid) {
              watchdog('fb cron', t('Facebook user %fbu does not correspond to a local account.  Purging bad data from Facebook User table.', array(
                '%fbu' => $data->fbu,
              )));

              //db_query("DELETE FROM {fb_user_app} WHERE apikey='%s' AND fbu = %d",

              //         $fb_app->apikey,
              //         $data->fbu);
            }
            else {

              // If here, local user has been found.
              $fb = fb_api_init($fb_app, $data->fbu);
              if (!$fb || !$fb->api_client
                ->users_getLoggedInUser()) {

                // Failed to log in as the current user, fallback to infinite session.
                $fb = fb_api_init($fb_app, FB_FBU_INFINITE_SESSION);
              }
              if (!$fb || !$fb->api_client
                ->users_getLoggedInUser()) {
                watchdog('fb cron', t('Failed to log into %app during cron.  Try testing infinite session key.', array(
                  '%app' => $fb_app->title,
                )));
              }
              else {

                // if here, we're logged into facebook.
                // Set things up as if this were a canvas page.
                $GLOBALS['user'] = $account;
                $GLOBALS['fb'] = $fb;
                $GLOBALS['fb_app'] = $fb_app;

                // Don't call fb_init_path here, it has already been called during cron jobs.
                // Invoke any actions that we've been configured to invoke.
                actions_do($edit['actions'], $fb_app);
              }

              // end if able to log into facebook
            }

            // end if local user found.
            // Record how recently cron was run for this user.  We do this even if
            // we failed to log in, because we don't want persistent problems to
            // clog the cron queue.  We'll get to this user again, eventually.
            db_query("UPDATE {fb_user_app} SET time_cron=%d WHERE apikey='%s' AND fbu=%d", time(), $fb_app->apikey, $data->fbu);
          }

          // Restore global variables
          $GLOBALS['user'] = $before_user;
          $GLOBALS['fb'] = $before_fb;
          $GLOBALS['fb_app'] = $before_fb_app;
        }
      }
    }
  }
}