book form alter module

dwees - January 14, 2007 - 12:29

Hey there folks,

I've seen some discussions about the book.module, and it seems there are two camps.

Camp 1 thinks it is perfect and has no flaws (this is a over-simplification of their position).

Camp 2 thinks it is frustrating that users can add their book pages to ANY book ANY where regardless of permissions, etc...

I've worked out a module to allow users to view and modify the structure of their book using a GUI, but I'd like to be able to handle the permission issues.

What I think would be nice is a module that lets an administrator add another filter to the drop-down select that users use to choose the position of their book page. I've seen a lot of talk about this, and I think some people have already come up with a solution. What I want is to find their solution for Drupal 4.7.x (which shouldn't be to hard to convert to Drupal 5.0 if it hasn't been done).

I envision a settings page for books where an administrator (or authorized role) choose a filter to apply to the appropriate book_toc function. Basically you should be able to filter that list by Organic Group, Author, Role, etc... This actually just looks like altering a single field in book_form to use an alternative of book_toc to create the options for the drop-down box.

Has anyone worked on this already?

Structure complete

dwees - January 15, 2007 - 20:41

Hey folks,

I've got the base structure of this module complete. I had to install the 'scratch' module (great idea whoever that was) to get the information for the form correct so I could use hook_form_alter, but it looks like it is working.

Now all I need to do is write the appropriate SQL queries to correspond to the extra filters I want to add. The current plan is to start with 3 filters that make the most sense to me. These filters would be administered by the admin of the site, rather than by the users themselves (the plan here is to try and create an idiot-proof system, not allow users even MORE ways to screw up!).

1. Filter the book pages by User Id, so that users can only either create a new book, or add to a book they've already started.
2. Filter the book pages by User Role Id, so that users can only either create a new book, or add to a existing book available to their role. If they create a new book, all users with the same role would be able to add to it.
3. Filter the book pages by the Organic Groups that the current user is a member of so they are only able to add pages to their group's books. This would also mean that a user who was not a member of any group would only be able to add top-level pages.
4. It's probably not a bad idea to allow merging of one or all of these options to allow for different variations of "permissions" to add book pages.

I'm not sure what the queries are supposed to be, but the original query, with no extra filter is:

'SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.status = 1 ORDER BY b.weight, n.title'

If anyone out there is especially good at building queries, it would be very helpful.

Thanks,

Dave

By User appears to be done

dwees - January 15, 2007 - 21:58

It looks like I've got the query correct for by user. At least on my site with 2 users it works the way I want it to. :) Just need to figure out by role and by Organic Group. Organic Group definitely looks like the most difficult of the 3 queries.

Dave

By Role done, need help with by Group

dwees - January 16, 2007 - 02:02

I worked out filter by role tonight but it looks like I'm going to have difficulty doing the filter by group.

What I want is for all of the book pages of the groups the current user is a member of to show up in the drop down list of possible book page parents. Unfortunately, looking at my version of the Organic Groups module, it doesn't look like there is any mechanism in OG to keep track of which pages belong to which groups.

It may be that I have to adjust the node creation mechanism so that there is some way to select the group to add the node to (probably by finding the groups the current user is a member of and creating a drop-down to select the group to associate the node with, then adding a table (or column to the already bloated node table) to keep track of this information), unless someone else has a different suggestion?

Dave

In case anyone is following my conversation with myself...

dwees - January 16, 2007 - 11:16

Does this function look right? I want to return the list of all of the nodes produced in an OG group. I'm using part of a function I found in the OG module. Then I use a modification of the book_toc function that allows me to substitute my own query in for the basic book page query.

<?php
/*
*    Changes the query to match the chosen filter - This one is by Group
**/
function bookexpanded_toc_group ($exclude = 0) {
    global
$user;
   
$uid = $user->uid;
   
$gid = $user->og_groups;
   
    if ((
$uid != 1)&&(module_exist('og'))) {
       
$sql = og_get_home_nodes_sql($type);
       
$query = db_rewrite_sql($sql, 'n', 'nid', array('og_nid' => $gid));
    } else {
       
$query = 'SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN ';
       
$query .= '{book} b ON n.vid = b.vid WHERE n.status = 1 ORDER BY b.weight, n.title';
    }
   
   
$output = bookexpanded_toc($query, $exclude);

    return
$output;
}

/**
* Returns an array of titles and nid entries of book pages in table of contents order by query.
*/
function bookexpanded_toc($q, $exclude = 0) {
 
$result = db_query(db_rewrite_sql($q));

  while (
$node = db_fetch_object($result)) {
    if (!
$children[$node->parent]) {
     
$children[$node->parent] = array();
    }
   
$children[$node->parent][] = $node;
  }

 
$toc = array();
 
// If the user has permission to create new books, add the top-level book page to the menu;
 
if (user_access('create new books')) {
   
$toc[0] = '<'. t('top-level') .'>';
  }

 
$toc = book_toc_recurse(0, '', $toc, $children, $exclude);

  return
$toc;
}
?>

 
 

Drupal is a registered trademark of Dries Buytaert.