/** * 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('catalogues'); $only_owned = array_key_exists('only_owned', $options) ? is_null($options['only_owned']) ? NULL : intval($options['only_owned']) : NULL; $catalogue_name = array_key_exists('catalogue_name', $options) ? $options['catalogue_name'] : NULL; $editable_filter = array_key_exists('editable_filter', $options) ? $options['editable_filter'] : false; $tree = get_catalogue_entries_tree($catalogue_name, $only_owned, is_null($id) ? NULL : intval($id), NULL, NULL, is_null($id) ? 0 : 1, $editable_filter); if (!has_actual_page_access(NULL, 'catalogues')) { $tree = array(); } $out = ''; foreach ($tree as $t) { $_id = $t['id']; if ($id === strval($_id)) { foreach ($t['entries'] as $eid => $etitle) { if (is_object($etitle)) { $etitle = @strip_tags(html_entity_decode($etitle->evaluate(), ENT_QUOTES, get_charset())); } $out .= '<entry id="' . xmlentities(strval($eid)) . '" title="' . xmlentities($etitle) . '" selectable="true"></entry>'; } continue; } $title = $t['title']; $has_children = $t['child_count'] != 0 || $t['child_entry_count'] != 0; $out .= '<category id="' . xmlentities(strval($_id)) . '" title="' . xmlentities($title) . '" has_children="' . ($has_children ? 'true' : 'false') . '" selectable="false"></category>'; } // Mark parent cats for pre-expansion if (!is_null($default) && $default != '') { $cat = $GLOBALS['SITE_DB']->query_value_null_ok('catalogue_entries', 'cc_id', array('id' => intval($default))); while (!is_null($cat)) { $out .= '<expand>' . strval($cat) . '</expand>'; $cat = $GLOBALS['SITE_DB']->query_value_null_ok('catalogue_categories', 'cc_parent_id', array('id' => $cat)); } } return '<result>' . $out . '</result>'; }
/** * Get a list of maps containing all the catalogue entries, and path information, under the specified category - and those beneath it, recursively. * * @param ID_TEXT The catalogue name * @param ?AUTO_LINK Only show entries submitted by this member (NULL: no filter) * @param ?AUTO_LINK The category being at the root of our recursion (NULL: true root) * @param ?string The tree up to this point in the recursion (NULL: blank, as we are starting the recursion) * @param ?ID_TEXT The 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 ?integer The number of recursive levels to search (NULL: all) * @param boolean Whether to only show for what may be edited by the current member * @return array A list of maps for all categories. Each map entry containins the fields 'id' (category ID) and 'tree' (tree path to the category, including the categories own title), and more. */ function get_catalogue_entries_tree($catalogue_name, $submitter = NULL, $category_id = NULL, $tree = NULL, $title = NULL, $levels = NULL, $editable_filter = false) { if (is_null($category_id)) { $is_tree = $GLOBALS['SITE_DB']->query_value_null_ok('catalogues', 'c_is_tree', array('c_name' => $catalogue_name)); } if (is_null($category_id) && is_null($levels)) { if ($GLOBALS['SITE_DB']->query_value('catalogue_categories', 'COUNT(*)', array('c_name' => $catalogue_name)) > 1000) { return array(); } // Too many! } if (is_null($category_id)) { if (is_null($is_tree)) { return array(); } if ($is_tree == 0) { $temp_rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('c_name' => $catalogue_name, 'cc_parent_id' => NULL), 'ORDER BY id DESC', 300); if (get_page_name() == 'cms_catalogues') { if (count($temp_rows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $children = array(); foreach ($temp_rows as $row) { $children = array_merge(get_catalogue_entries_tree($catalogue_name, $submitter, $row['id'], NULL, get_translated_text($row['cc_title']), 1, $editable_filter), $children); } return $children; } $temp_rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('c_name' => $catalogue_name, 'cc_parent_id' => NULL), 'ORDER BY id', 1); if (!array_key_exists(0, $temp_rows)) { return array(); } $category_id = $temp_rows[0]['id']; $title = get_translated_text($temp_rows[0]['cc_title']); } if (is_null($tree)) { $tree = ''; } if (!has_category_access(get_member(), 'catalogues_catalogue', $catalogue_name)) { return array(); } if (get_value('disable_cat_cat_perms') !== '1' && !has_category_access(get_member(), 'catalogues_category', strval($category_id))) { return array(); } // Put our title onto our tree if (is_null($title)) { $title = get_translated_text($GLOBALS['SITE_DB']->query_value('catalogue_categories', 'cc_title', 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 of this category $rows = $GLOBALS['SITE_DB']->query_select('catalogue_categories', array('id', 'cc_title'), array('cc_parent_id' => $category_id), '', 300); if (get_page_name() == 'cms_catalogues') { if (count($rows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $where = array('cc_id' => $category_id); if (!is_null($submitter)) { $where['ce_submitter'] = $submitter; } $erows = $GLOBALS['SITE_DB']->query_select('catalogue_entries', array('id', 'ce_submitter'), $where, 'ORDER BY ce_add_date DESC', 300); if (get_page_name() == 'cms_catalogues') { if (count($erows) == 300) { attach_message(do_lang_tempcode('TOO_MUCH_CHOOSE__RECENT_ONLY', escape_html(integer_format(300))), 'warn'); } } $children[0]['entries'] = array(); foreach ($erows as $row) { if ($editable_filter && !has_edit_permission('mid', get_member(), $row['ce_submitter'], 'cms_catalogues', array('catalogues_catalogue', $catalogue_name, 'catalogues_category', $category_id))) { continue; } $entry_fields = get_catalogue_entry_field_values($catalogue_name, $row['id'], array(0)); $name = $entry_fields[0]['effective_value']; // 'Name' is value of first field $children[0]['entries'][$row['id']] = $name; } $children[0]['child_entry_count'] = count($children[0]['entries']); if ($levels === 0) { $children[0]['entries'] = array(); } $children[0]['child_count'] = count($rows); $tree .= ' > '; if ($levels !== 0) { foreach ($rows as $i => $child) { $rows[$i]['_cc_title'] = get_translated_text($child['cc_title']); } global $M_SORT_KEY; $M_SORT_KEY = '_cc_title'; usort($rows, 'multi_sort'); foreach ($rows as $child) { $child_id = $child['id']; $child_title = $child['_cc_title']; $child_tree = $tree; $child_children = get_catalogue_entries_tree($catalogue_name, $submitter, $child_id, $child_tree, $child_title, is_null($levels) ? NULL : $levels - 1, $editable_filter); $children = array_merge($children, $child_children); } } return $children; }