One of the keys to a digg.com type of site is that nodes first start out in a queue and then are promoted to the frontpage after they receive enough votes. Nodes on the frontpage have to be sorted by the time they were promoted, and not by the node creation time.

This poses a problem because currently, nodes are only timestamped with their creation time and changed time. I have thought alot how to solve this problem, and I think I would need to create a new module and database table to store promotion timestamp information.

Here's how Merlinofchaos described this module to me:
"write a small nodeapi module that has a small table (nid, promote_date) that watches in hook_nodeapi for ops 'insert' and 'update', checks to see if $node->promote has changed, and if so, write that date to the db."

Yes, that sounds like the perfect solution, but alas, my programming skills stink.

Is this a difficult module to create? Would someone be willing to help me with the code?

Thanks in advance for your advice.

Comments

potential’s picture

Here are some other ideas I had:

I could turn on revisions, and then have the voting actions module change the creation time to the current time upon promotion and also do a node save to create a new revision. I could then limit the frontpage to nodes that have been promoted, sorted by creation time. Then, I could use the timestamp on origonal version of the node (as stored in node_revisions.module) to represent the origonal publishing time.

OR

Just create a new table called "node_promotion", and then have voting actions module save the nid and timestamp when it promotes the node.

The problem with both of these solutions arrises when I manually promote a node to the frontpage, because the new timestamp relies on voting actions doing the promotion.

The solution in the origonal post appears more complete, but more difficult to do. Will either of two methods I just described work for my situation? Can you help me understand how to accomplish this?

Thanks again.

potential’s picture

Hi guys,

I made some progress trying to make my first module, appropriately called promote.module.

My table has two rows, nid and promote_date.

Like merlin suggested I am using hook_nodeapi. Here is my code so far:

<?php
// $Id: promote.module, v 1.0 2006/04/11 23:04:56 potential Exp $

/**
 * @file
 * This module tracks node promotion times
 */

/**
 * Implementation of hook_help().
 */
function promote_help($section) {
  switch ($section) {
    case 'admin/help#promote':
      return t('TODO: Create admin help text.');
    case 'admin/modules#description':
      return t('creates database to track node promotion times');
    // OPTIONAL: Add additional cases for other paths that should display help text.
  }
}

/**
 * Implementation of hook_nodeapi().
 */
function promote_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'insert':
      if (node->promote) {
      // MISSING CODE
      }
      break;
    case 'update':
      // OPTIONAL: Insert code to execute when node is updated.
      break;
    case 'delete':
      // OPTIONAL: Insert code to execute when node is deleted.
      break;   
  }
}

I had trouble finding documentation that shows what code I need to analyze if the node is changing from unpromoted to promoted, and then if so, how do I write this to my table?

v1nce’s picture

Any progress on adding a timestamp to nodes when promotion is changed?

-------------------------------------
Petafoo

tomamic’s picture

In hook_nodeapi/presave:

// promoted nodes go to the top (in the front page)
// because sticky is set to the time when they're first promoted
// if edited while promoted, sticky won't change

if ($node->promote) {
	$old_sticky = 0;
	if ($node->nid) {
		$old_sticky = db_result(db_query('select sticky from {node} where nid = %d', $node->nid));
	}
	$node->sticky = $old_sticky ? $old_sticky : time();
} else {
	$node->sticky = 0;
}
jayburgh’s picture

tomamic's response look like the ticket. I've adapted his code to allow editors with sticky privs to order front page items by toggling the node's sticky attribute:

// $Id$
/**
* Implementation of hook_nodeapi().
*/
function mod_node_sticky_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'presave':
      // use time for new stickies to allow sorting by sticky time
      if ($node->sticky) {
        $old_sticky = 0;
        if ($node->nid) {
          $old_sticky = db_result(db_query('select sticky from {node} where nid = %d', $node->nid));
        }
        $node->sticky = $old_sticky ? $old_sticky : time();
      }
      break;
  }
}