Index: book.module =================================================================== retrieving revision 1.216 diff -u -r1.216 book.module --- book.module 15 Feb 2004 20:09:46 -0000 1.216 +++ book.module 9 Mar 2004 09:27:38 -0000 @@ -5,45 +5,73 @@ return t("book page"); } +/** + * Return "maintain" and "access" permissions for each book + */ function book_perm() { - return array("maintain books"); + $result = db_query("SELECT n.title FROM {node} AS n INNER JOIN {book} AS b ON b.nid = n.nid WHERE b.parent = 0;"); + while ($node = db_fetch_object($result)) { + $books[] = "maintain $node->title"; + $books[] = "access $node->title"; + } + return $books; } +/* + * Given a book node id, return the nid of the top-most parent + */ +function book_find_root_node($nid) { + + $root_parent_nid = 0; + + // If no $nid has been passed, we are previewing a page, and the root will default to 0 + if ($nid) { + $result = db_query("SELECT parent, nid FROM {book} WHERE nid = $nid", $nid); + while ($parent = db_fetch_object($result)) { + if ($parent->parent > 0) { + book_find_root_node($parent->parent); + } + else { + $root_parent_nid = $parent->nid; + } + } + } + return $root_parent_nid; + } // endfunction _book_find_root_node + +/** + * This hook finds the topmost parent node (the book this page is in) and returns whether the user + * has access to this book. As stated earlier, if the page has no parents, we assume it is being + * previewed and allow access. + */ function book_access($op, $node) { global $user; - if ($op == "view") { - /* - ** Everyone can access all published book pages whether these pages - ** are still waiting for approval or not. We might not always want - ** to display pages that are waiting for approval, but we take care - ** of that problem in the book_view() function. - */ + $parentnid = book_find_root_node($node->nid); + $result = db_query("SELECT n.title FROM node AS n WHERE n.nid = $parentnid", $parentnid); + $node = db_fetch_object($result); - return $node->status; + if ($op == "view") { + return user_access("access $node->title"); } + /** + * Only registered users can create book pages, and only in the books for which they have been + * given access. + */ if ($op == "create") { - /* - ** Only registered users can create book pages. Given the nature - ** of the book module this is considered to be a good/safe idea. - */ - - return user_access("maintain books"); + return user_access("maintain $node->title"); } + /** + * One can only update a book page if there are no suggested updates + * of that page waiting for approval, when it is not a PHP-page and + * as long as the "create new revision"-bit is set. That is, only + * updates that don't overwrite the current or pending information + * are allowed. + */ if ($op == "update") { - /* - ** Only registered users can update book pages. Given the nature - ** of the book module this is considered to be a good/safe idea. - ** One can only update a book page if there are no suggested updates - ** of that page waiting for approval, when it is not a PHP-page and - ** as long as the "create new revision"-bit is set. That is, only - ** updates that don't overwrite the current or pending information - ** are allowed. - */ - - return user_access("maintain books") && !$node->moderate && !$node->format && $node->revision; + return user_access("maintain $node->title") && !$node->moderate && !$node->format && $node->revision; } } @@ -568,7 +596,10 @@ if (!$children[$node->parent]) { $children[$node->parent] = array(); } - array_push($children[$node->parent], $node); + // Only allow users to see books for which they have access. + if (book_access("view", $node)) { + array_push($children[$node->parent], $node); + } } /*