"This module adds a block to your site which displays your most recent update to Ping.FM. I didn't like that the existing ping.fm module created a node for each new update. I just wanted to store the one most recent so it could be displayed."

If I added a hook in the Ping.fm module that was triggered when the Custom URL was hit, it might make your life easier. Then Ping.fm Block could depend on the Ping.fm module, and just implement hook_pingfm_custom_url() hook, or something, and display the block. The functionality for the pingfm menu callback wouldn't have to be there.

Thoughts?

Comments

robloach’s picture

I've also been thinking about abstracting out the Ping.fm node creation stuff into a different module, keeping the API seperate from the functionality. Does that make sense?

chrisfromredfin’s picture

Hi Rob -

Actually, I think that makes perfect sense, IF you abstracted out some of your other functionality like you mention in comment (1). Then the API would afford the ability for multiple things to act on the one custom "ping" url.. so we could create nodes, or store it, or relay it, or all three!

I think I went to "recommended" too fast, but I think I can do a 2x-dev branch which would be the future of it, and would depend on "Ping FM API."

robloach’s picture

Just made a rather large commit: http://drupal.org/cvs?commit=189508

It creates a new hook_pingfm_custom_url() which looks a little something like this:

/**
 * Called when a custom URL is invoked from Ping.fm.
 *
 * Note that this is already passed through the security check on the user's application key.
 *
 * @param $user
 *   The Drupal user account that called the custom URL.
 * @param $data
 *   The data that's passed from Ping.fm. An associative array detailing:
 *   $data['method']
 *     The method of the message being sent (blog, microblog, status).
 *   $data['title']
 *     If method is "blog" then this contain the blog's title.
 *   $data['message']
 *     The posted message content.
 *   $data['location']
 *     Any location updates posted with the message.  This is plaintext, verbatim from the posting interface.
 *   $data['media']
 *     If media is posted, this will contain a URL to the media file.
 *   $data['raw_message']
 *     If media is posted, this will contain the posted message WITHOUT the hosted media link (i.e. http://ping.fm/p/12345)
 *   $data['trigger']
 *     If you post a message with a custom trigger (http://ping.fm/triggers/), it will show here.
 */
function hook_pingfm_custom_url($user, $data = array()) {
  // In this example, we create a node for the user.
  $node = array(
    'title' => $data['title'],
    'uid' => $user->uid,
    'name' => $user->name,
    'body' => $data['message'],
    'type' => $user->pingfm_customurl_nodetype,
    'promote' => 1,
  );
  if ($node = node_submit($node)) {
    node_save($node);
  }
}

The benefit to using this is that it goes through an md5 security check, and you don't have to worry about any of the user settings or anything. See an example in pingfm_node.module.

chrisfromredfin’s picture

Assigned: Unassigned » chrisfromredfin

Very cool - I will get on implementing my module this way, since this is much better/more extensible.

robloach’s picture

Now we just need to backport it to 5 :-P . Heh, yeah right.

robloach’s picture

What the Ping.fm block module is missing is the ability to display Ping.fm updates from different users. This would have to be an additional setting in pingfmblock_block(). Something like this might work, I haven't tested it....


/**
 * Implementation of hook_pingfm_custom_url().
 */
function pingfmblock_pingfm_custom_url($user, $data = array()) {
  $data['date'] = date("m.d.y g:ia");
  variable_set('pingfmblock_content_'. $user->uid, $data);
}

// implementation of hook_theme
function pingfmblock_theme() {
  return array(
    'pingfmblock_status' => array(
      'arguments' => array('data' => NULL),
    ),
  );
}

// theme function
function theme_pingfmblock_status($data = array()) {
  if(empty($data)) {
    return t('There are not any Ping.fm updates.... Yet!');
  }
  $status = '';
  $status .= '<div id="pingfmblock_wrapper">';
  $status .= '<div class="pingfmblock_title">'.$data['title'].'</div>';
  $status .= '<div class="pingfmblock_content">'.$data['message'].'</div>';
  $status .= '<div class="pingfmblock_source">(via \''.$data['method'].'\' at '.$data['date'].')</div>';
  $status .= '</div>';

  return $status;
}

// implementation of hook_block
function pingfmblock_block($op = 'list', $delta = 0, $edit = array()) {
    switch($op) {
      case 'list':
      $blocks[0] = array(
        'info' => t('Ping.FM Update'),
        'weight' => 0,
        'enabled' => 1,
        'region' => 'left',
        'cache' => BLOCK_NO_CACHE,
        );
        
        return $blocks;  
        break;
      case 'configure':
      $form['user'] = array(
        '#type' => 'textfield',
        '#title' => t('User account'),
        '#description' => t('The user ID number of which user you would like to show in the ping.fm block.'),
        '#default_value' => variable_get('pingfmblock_user', 1),
      );
      return $form;

        break;
      case 'save':
        switch($delta) {
          case 0:
            variable_set('pingfmblock_user', $edit['user']);
          break;
        }
        break;
      case 'view':
        switch($delta) {
          case 0:
            $user = variable_get('pingfmblock_user', 1);
            $data = variable_get('pingfmblock_content_'. $user, array());
            $block = array(
              'subject' => t('Latest from Ping.FM'),
              'content' => theme('pingfmblock_status', $data),
            );
            return $block;
            break;
        }
        break;
    }
}
chrisfromredfin’s picture

So, you have the ability to store multiple users, and then just change which user gets displayed by the block? Seems kinda "meh," to me -- like it is really just for the sites that are the one-user sites, like personal blogs and stuff. If I wanted multiple users, I would just (personally) use what you already have and create nodes so I can create views and do more powerful things, so I'm more inclined to just leave it.

Something that dawned on me though -- is there any kind of authentication process? I suppose any jamoke on ping.fm could start posting their updates to my site (including nefarious Nigerians or hawkers of enhancement products)... no?

robloach’s picture

Yup, when using the Custom URL with the Ping.fm module, it requires the user ID, as well as an encrypted hash of the user's Ping.fm remote API key. This way, if someone attempts to post to your site, they won't be able to, since they don't have that encrypted Ping.fm remote key. If you have a look at the pingfm_custom_url() function, you'll see that it checks if ($key == md5($user->pingfm_app_key)).

If you install the Ping.fm module and edit your account, you'll see that the custom URL it gives you to provide to Ping.fm is pretty secure ;-) .

chrisfromredfin’s picture

OK, hmm, well I've got the new code in HEAD and it works (it's running on my site - its530somewhere.com using the newest -dev of pingfm.module). You can check out the HEAD version if you'd like to test.

Unfortunately, creating a 6.x-2.x-dev release off HEAD and getting it to show up on my "administer releases" page is tricky. Either I need to wait, or I did something wrong. In the meantime, like I said, check out HEAD.

robloach’s picture

Status: Active » Fixed

Very nicely done! Tested and works! Just need a release ;-) .

chrisfromredfin’s picture

Status: Fixed » Closed (fixed)

OK, managed to get my 2.0 release up. Closing.