When Private is enabled there is no way to populate the private table. As a result, existing nodes remain absent from the table. This is a problem as other modules begin to use this access information (see http://drupal.org/node/113674).

The following update solves the problem for MySQL (I'd rather have someone else write the Postgres version).

In private.module

/**
 * Implementation of hook_nodeapi().
 *
 * - "delete", "insert", and "update":
 * The module must track the access status of the node.
 */
function private_nodeapi(&$node, $op, $arg = 0) {
  switch ($op) {
    case 'load':
      $result = db_fetch_object(db_query('SELECT * FROM {private} WHERE nid = %d', $node->nid));
      if (!isset($result->private)) {
	    $node->private = false;
	    $node->private_missing = true;
	  } else {
	    $node->private = $result->private;
	  }
      break;
    case 'delete':
      db_query('DELETE FROM {private} WHERE nid = %d', $node->nid);
      break;
    case 'insert':
      db_query('INSERT INTO {private} (nid, private) VALUES (%d, %d)', $node->nid, $node->private);
      break;
    case 'update':
	  if ($node->private_missing) {
	    db_query('INSERT INTO {private} (nid, private) VALUES (%d, %d)', $node->nid, $node->private); }
	  else {
        db_query('UPDATE {private} SET private = %d WHERE nid = %d', $node->private, $node->nid); }
      break;
  }
}

in private.install

function private_install() {
  switch ($GLOBALS['db_type']) {
    case 'mysql':
    case 'mysqli':
      db_query("
          CREATE TABLE {private} (
            nid int(10) unsigned NOT NULL default '0' PRIMARY KEY,
            private int,
            KEY private_nid (nid)
          ) /*!40100 DEFAULT CHARACTER SET utf8 */;
      ");
      db_query("
          INSERT INTO {private}
            SELECT
              n.nid, 
              0 
            FROM
              {node} n
              LEFT JOIN {private} p ON
                p.nid=n.nid 
            WHERE
              p.private is null	
            ORDER BY n.nid
      ");	  
      break;
    case 'pgsql':
      db_query("
          CREATE TABLE {private} (
            nid int NOT NULL default '0',
            private int,
            PRIMARY KEY (nid));
      ");
      break;
  }
}

It should not alter in any way standard private module behavior, so I'd really ask you to adopt it as a standad.

Comments

Bèrto ëd Sèra’s picture

BTW, I'm new to Drupal, so possibly there's a better hook to place the INSERT...SELECT. It should actually happen every time the module is enabled. Version 5 is still pretty experimental, all of us do disable and enable modules pretty often without uninstalling anything.

batsonjay’s picture

Category: feature » bug
Status: Needs review » Needs work

Note:

I didn't check the "before," but after applying this patch, and after installing it, the install/uninstall don't work correctly.

When I enable the module, and click "Save configuration," the next page I see is totally blank. No HTML in the source at all. The same thing happens when I disable the module. The URL that is showing in the title bar (in both cases) is .../modules/list/confirm

The module *appears* to be enabled when I revisit the Modules page. There are no errors in the apache logs, or in the watchdog.

(I don't know if the module is working; I'm just the admin, and another user is "using" this module.)

greggles’s picture

Status: Needs work » Closed (duplicate)

I implemented this in a slightly different way in #156751: Hook into node operations & set default during install.\

That has a patch and this doesn't, so...marking this as a duplicate.