/** read all nodes from table for this area and construct a tree * * this constructs the tree for this area, and makes sure that only * non-hidden pages and non-empty sections are visible * * @param int $area_id the tree is built from nodes within this area * @return array an array with the node-records linked as a tree */ function construct_tree($area_id) { $tree = tree_build($area_id); foreach ($tree as $node_id => $item) { $tree[$node_id]['is_visible'] = FALSE; $tree[$node_id]['is_breadcrumb'] = FALSE; } tree_visibility($tree[0]['first_child_id'], $tree); return $tree; }
/** display the content of the sitemap linked to node $node_id * * there are three different variations (depends on configuration parameter 'scope'): * * - 0 (small): only show a map of the tree in the current area $area_id * - 1 (medium): show a list of available areas followed by the map of the current area $area_id * - 2 (large): show the maps of all available areas * * The default is 0 (small). * * @param object &$theme collects the (html) output * @param int $area_id identifies the area where $node_id lives * @param int $node_id the node to which this module is connected * @param array $module the module record straight from the database * @return bool TRUE on success + output via $theme, FALSE otherwise */ function sitemap_view(&$theme, $area_id, $node_id, $module) { global $USER; // // 1 -- determine scope of sitemap: 0=small, 1=medium, 2=large // $table = 'sitemaps'; $fields = array('header', 'introduction', 'scope'); $where = array('node_id' => intval($node_id)); $record = db_select_single_record($table, $fields, $where); if ($record === FALSE) { logger(sprintf('%s(): error retrieving configuration: %s', __FUNCTION__, db_errormessage())); $scope = 0; $header = ''; $introduction = ''; } else { $scope = intval($record['scope']); $header = trim($record['header']); $introduction = trim($record['introduction']); } // // 2 -- compute a list of areas to process (could be just 1) // // 2A -- retrieve all areas, including those out of bounds for this user if (($all_areas = get_area_records()) === FALSE) { logger(sprintf('%s(): huh? cannot get area records: %s', __FUNCTION__, db_errormessage())); return FALSE; // shouldn't happen } // 2B -- narrow down the selection (active, (private) access allowed, within scope) $areas = array(); foreach ($all_areas as $id => $area) { if (db_bool_is(TRUE, $area['is_active']) && (db_bool_is(FALSE, $area['is_private']) || $USER->has_intranet_permissions(ACL_ROLE_INTRANET_ACCESS, $id))) { if ($scope == 2 || $scope == 1 || $scope == 0 && $id == $area_id) { $title = $area['title']; $params = array('area' => $id); $href = was_node_url(NULL, $params, $title, $theme->preview_mode); $areas[$id] = html_a($href, NULL, NULL, $title); } } } unset($all_areas); // $areas now holds all areas that we should to process if (sizeof($areas) <= 0) { logger(sprintf('%s(): weird, no areas to process; bailing out', __FUNCTION__)); return FALSE; // shouldn't happen } // // 3 -- maybe output a header and an introduction // if (!empty($header)) { $theme->add_content('<h2>' . $header . '</h2>'); } if (!empty($introduction)) { $theme->add_content($introduction); } // // 4 - Actually output a sitemap by walking the tree once for every elegible area // foreach ($areas as $id => $area_anchor) { if ($scope == 1 && $area_id != $id) { // 1=medium only shows area map of $area_id (and an area list lateron) continue; } // 4A -- output a clickable area title $theme->add_content('<h2>' . $area_anchor . '</h2>'); // 4B -- fetch the tree for this area... $tree = tree_build($id); tree_visibility($tree[0]['first_child_id'], $tree); // 4C -- ...and walk the tree sitemap_tree_walk($theme, $tree[0]['first_child_id'], $tree); unset($tree); } if ($scope == 1) { $theme->add_content('<h2>' . t('sitemap_available_areas', 'm_sitemap') . '</h2>'); $theme->add_content('<ul>'); foreach ($areas as $id => $area_anchor) { $theme->add_content('<li>' . $area_anchor); } $theme->add_content('</ul>'); } return TRUE; // indicate success }
/** calculate the visibility of the nodes in the tree * * this flags visible nodes as visible. Here 'visible' means that * * - the node is not hidden, not expired and not under embargo * - the section has at least 1 visible node (page or section) * * As a side effect, any subtree starting at a hidden/expired/embargo'ed * section is completely set to invisible so we don't risk the chance to * accidently show a page from an invisible section. * This routine walks through the tree recursively. * * @param int $subtree_id the starting point for the tree walking * @param array &$tree pointer to the current tree * @param bool $force_invisibility * @return bool TRUE when there is at least 1 visible node, FALSE otherwise * @todo how about making all nodes under embargo visible when previewing a page * or at least the path from the node to display? */ function tree_visibility($subtree_id, &$tree, $force_invisibility = FALSE) { $now = strftime("%Y-%m-%d %T"); $visible_nodes = 0; for ($node_id = $subtree_id; $node_id != 0; $node_id = $tree[$node_id]['next_sibling_id']) { if ($tree[$node_id]['is_page']) { if ($tree[$node_id]['record']['expiry'] < $now || $now < $tree[$node_id]['record']['embargo'] || $force_invisibility || $tree[$node_id]['is_hidden']) { $tree[$node_id]['is_visible'] = FALSE; } else { $tree[$node_id]['is_visible'] = TRUE; ++$visible_nodes; } } else { //section if ($tree[$node_id]['record']['expiry'] < $now || $now < $tree[$node_id]['record']['embargo'] || $force_invisibility) { $tree[$node_id]['is_visible'] = FALSE; tree_visibility($tree[$node_id]['first_child_id'], $tree, TRUE); } elseif ($tree[$node_id]['is_hidden']) { $tree[$node_id]['is_visible'] = FALSE; tree_visibility($tree[$node_id]['first_child_id'], $tree); } else { if (tree_visibility($tree[$node_id]['first_child_id'], $tree)) { $tree[$node_id]['is_visible'] = TRUE; ++$visible_nodes; } else { $tree[$node_id]['is_visible'] = FALSE; } } } } return $visible_nodes > 0 ? TRUE : FALSE; }