/** * Standard modular run function for ajax-tree hooks. Generates XML for a tree list, which is interpreted by Javascript and expanded on-demand (via new calls). * * @param ?ID_TEXT The ID to do under (NULL: root) * @param array Options being passed through * @param ?ID_TEXT The ID to select by default (NULL: none) * @return string XML in the special category,entry format */ function run($id, $options, $default = NULL) { require_code('downloads'); require_lang('downloads'); $compound_list = array_key_exists('compound_list', $options) ? $options['compound_list'] : false; $addable_filter = array_key_exists('addable_filter', $options) ? $options['addable_filter'] : false; $stripped_id = $compound_list ? preg_replace('#,.*$#', '', $id) : $id; $tree = get_download_category_tree(is_null($id) ? NULL : intval($id), NULL, NULL, true, $compound_list, is_null($id) ? 0 : 1, $addable_filter); $out = ''; if (!has_actual_page_access(NULL, 'downloads')) { $tree = array(); } if ($compound_list) { list($tree, ) = $tree; } foreach ($tree as $t) { if ($compound_list) { $_id = $t['compound_list']; } else { $_id = strval($t['id']); } if ($stripped_id === strval($t['id'])) { continue; } // Possible when we look under as a root $title = $t['title']; $has_children = $t['child_count'] != 0; $selectable = !$addable_filter || $t['addable']; $tag = 'category'; // category $out .= '<' . $tag . ' id="' . $_id . '" title="' . xmlentities($title) . '" has_children="' . ($has_children ? 'true' : 'false') . '" selectable="' . ($selectable ? 'true' : 'false') . '"></' . $tag . '>'; } // Mark parent cats for pre-expansion if (!is_null($default) && $default != '') { $cat = intval($default); while (!is_null($cat)) { $out .= '<expand>' . strval($cat) . '</expand>'; $cat = $GLOBALS['SITE_DB']->query_value_null_ok('download_categories', 'parent_id', array('id' => $cat)); } } $tag = 'result'; // result return '<' . $tag . '>' . $out . '</' . $tag . '>'; }
/** * Get a list of maps containing all the subcategories, and path information, of the specified category - and those beneath it, recursively. * * @param ?AUTO_LINK The category being at the root of our recursion (NULL: true root category) * @param ?string The tree up to this point in the recursion (NULL: blank, as we are starting the recursion) * @param ?ID_TEXT The category name of the $category_id we are currently going through (NULL: look it up). This is here for efficiency reasons, as finding children IDs to recurse to also reveals the childs title * @param boolean Whether to collect download counts with our tree information * @param boolean Whether to make a compound list (a pair of a comma-separated list of children, and the child array) * @param ?integer The number of recursive levels to search (NULL: all) * @param boolean Whether to only show for what may be added to by the current member * @return array A list of maps for all subcategories. Each map entry containins the fields 'id' (category ID) and 'tree' (tree path to the category, including the categories own title). There is also an additional 'downloadcount' entry if stats were requested */ function get_download_category_tree($category_id = NULL, $tree = NULL, $title = NULL, $do_stats = true, $use_compound_list = false, $levels = NULL, $addable_filter = false) { if (!$use_compound_list) { if ($levels == -1) { return array(); } } // if (!has_category_access(get_member(),'downloads',strval($category_id))) return array(); if (is_null($category_id)) { $category_id = db_get_first_id(); } if (is_null($tree)) { $tree = ''; } // Put our title onto our tree if (is_null($title)) { $title = get_translated_text($GLOBALS['SITE_DB']->query_value('download_categories', 'category', array('id' => $category_id))); } $tree .= $title; // We'll be putting all children in this entire tree into a single list $children = array(); $children[0] = array(); $children[0]['id'] = $category_id; $children[0]['title'] = $title; $children[0]['tree'] = $tree; $children[0]['compound_list'] = strval($category_id) . ','; if ($addable_filter) { $children[0]['addable'] = has_submit_permission('mid', get_member(), get_ip_address(), 'cms_downloads', array('downloads', $category_id)); } if ($do_stats) { $children[0]['filecount'] = $GLOBALS['SITE_DB']->query_value('download_downloads', 'COUNT(*)', array('category_id' => $category_id)); } // Children of this category $rows = $GLOBALS['SITE_DB']->query_select('download_categories', array('id', 'category'), array('parent_id' => $category_id), '', 300); if (count($rows) == 300) { $rows = array(); } $children[0]['child_count'] = count($rows); $tree .= ' > '; if ($levels !== 0 || $use_compound_list) { foreach ($rows as $child) { $child_id = $child['id']; $child_title = get_translated_text($child['category']); $child_tree = $tree; $child_children = get_download_category_tree($child_id, $child_tree, $child_title, $do_stats, $use_compound_list, is_null($levels) ? NULL : max(0, $levels - 1), $addable_filter); if ($use_compound_list) { list($child_children, $_compound_list) = $child_children; $children[0]['compound_list'] .= $_compound_list; } if ($levels !== 0) { $children = array_merge($children, $child_children); } } } return $use_compound_list ? array($children, $children[0]['compound_list']) : $children; }
/** * Standard modular page-link finder function (does not return the main entry-points that are not inside the tree). * * @param ?integer The number of tree levels to computer (NULL: no limit) * @param boolean Whether to not return stuff that does not support permissions (unless it is underneath something that does). * @param ?string Position to start at in the tree. Does not need to be respected. (NULL: from root) * @param boolean Whether to avoid returning categories. * @return ?array A tuple: 1) full tree structure [made up of (pagelink, permission-module, permissions-id, title, children, ?entry point for the children, ?children permission module, ?whether there are children) OR a list of maps from a get_* function] 2) permissions-page 3) optional base entry-point for the tree 4) optional permission-module 5) optional permissions-id (NULL: disabled). */ function get_page_links($max_depth = NULL, $require_permission_support = false, $start_at = NULL, $dont_care_about_categories = false) { unset($require_permission_support); $permission_page = 'cms_downloads'; require_code('downloads'); $category_id = NULL; if (!is_null($start_at)) { $matches = array(); if (preg_match('#[^:]*:downloads:type=misc:id=(.*)#', $start_at, $matches) != 0) { $category_id = intval($matches[1]); } } $adjusted_max_depth = is_null($max_depth) ? NULL : (is_null($category_id) ? $max_depth - 1 : $max_depth); return array($dont_care_about_categories ? array() : get_download_category_tree($category_id, NULL, NULL, false, false, $adjusted_max_depth, false), $permission_page, '_SELF:_SELF:type=misc:id=!', 'downloads'); }