/** * 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('galleries'); require_lang('galleries'); $must_accept_images = array_key_exists('must_accept_images', $options) ? $options['must_accept_images'] : false; $must_accept_videos = array_key_exists('must_accept_videos', $options) ? $options['must_accept_videos'] : false; $filter = array_key_exists('filter', $options) ? $options['filter'] : NULL; $purity = array_key_exists('purity', $options) ? $options['purity'] : false; $member_id = array_key_exists('member_id', $options) ? $options['member_id'] : NULL; $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_gallery_tree(is_null($id) ? 'root' : $stripped_id, '', NULL, true, $filter, false, false, $purity, $compound_list, is_null($id) ? 0 : 1, $member_id, $addable_filter); if (!has_actual_page_access(NULL, 'galleries')) { $tree = array(); } if ($compound_list) { list($tree, ) = $tree; } $out = ''; for ($i = 0; $i < count($tree); $i++) { $t = $tree[$i]; $_id = $compound_list ? $t['compound_list'] : $t['id']; if ($stripped_id === $t['id']) { // Possible when we look under as a root if (array_key_exists('children', $t)) { $tree = $t['children']; $i = 0; } continue; } $title = $t['title']; if (is_object($title)) { $title = @html_entity_decode(strip_tags($title->evaluate()), ENT_QUOTES, get_charset()); } $has_children = $t['child_count'] != 0; $selectable = ($addable_filter !== true || $t['addable']) && ($t['accept_videos'] == 1 && $t['is_member_synched'] == 0 || !$must_accept_videos) && ($t['accept_images'] == 1 && $t['is_member_synched'] == 0 || !$must_accept_images); $tag = 'category'; // category $out .= '<' . $tag . ' id="' . xmlentities($_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 = $default; while (!is_null($cat) && $cat != '') { $out .= '<expand>' . $cat . '</expand>'; $cat = $GLOBALS['SITE_DB']->query_value_null_ok('galleries', 'parent_id', array('name' => $cat)); } } } $tag = 'result'; // result return '<' . $tag . '>' . $out . '</' . $tag . '>'; }
/** * Standard function to create the standardised category tree * * @param ID_TEXT Notification code * @param ?ID_TEXT The ID of where we're looking under (NULL: N/A) * @return array Tree structure */ function create_category_tree($notification_code, $id) { require_code('galleries'); if (is_null($id)) { $total = $GLOBALS['SITE_DB']->query_value_null_ok('galleries', 'COUNT(*)'); if ($total > 300) { return parent::create_category_tree($notification_code, $id); } // Too many, so just allow removing UI } $pagelinks = get_gallery_tree($id, '', NULL, true, NULL, false, false, true, false, is_null($id) ? 0 : 1); $filtered = array(); foreach ($pagelinks as $p) { if ($p['id'] !== $id) { $filtered[] = $p; } } return $filtered; }
/** * 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_galleries'; $category_data_count = $GLOBALS['SITE_DB']->query_value('galleries', 'COUNT(*)'); if ($category_data_count > 2000) { $dont_care_about_categories = true; } require_code('galleries'); $category_id = NULL; if (!is_null($start_at)) { $matches = array(); if (preg_match('#[^:]*:galleries:type=misc:id=(.*)#', $start_at, $matches) != 0) { $category_id = $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_gallery_tree($category_id, '', NULL, true, NULL, false, false, true, false, $adjusted_max_depth, NULL, false), $permission_page, '_SELF:_SELF:type=misc:id=!', 'galleries'); }
/** * Gets a gallery selection tree list, extending deeper from the given category_id, showing all sub(sub...)galleries. * * @param ?ID_TEXT The gallery we are getting the tree starting from (NULL: root) * @param string The parent tree at this point of the recursion * @param ?array The database row for the $category_id gallery (NULL: get it from the DB) * @param boolean Whether to include video/image statistics in the returned tree * @param ?string A function name to filter galleries with (NULL: no filter) * @param boolean Whether displayed galleries must support images * @param boolean Whether displayed galleries must support videos * @param boolean Whether to NOT show member galleries that do not exist yet * @param boolean Whether to get a list of child galleries (not just direct ones, recursively), instead of just IDs * @param ?integer The number of recursive levels to search (NULL: all) * @param ?MEMBER Member we are filtering for (NULL: not needed) * @param boolean Whether to only show for what may be added to by the current member * @return array The tree structure, or if $use_compound_list, the tree structure built with pairs containing the compound list in addition to the child branches */ function get_gallery_tree($category_id = 'root', $tree = '', $gallery_info = NULL, $do_stats = true, $filter = NULL, $must_accept_images = false, $must_accept_videos = false, $purity = false, $use_compound_list = false, $levels = NULL, $member_id = NULL, $addable_filter = false) { if ($levels == -1) { return $use_compound_list ? array(array(), '') : array(); } if (is_null($category_id)) { $category_id = 'root'; } if (!has_category_access(get_member(), 'galleries', $category_id)) { return $use_compound_list ? array(array(), '') : array(); } // Put our title onto our tree if (is_null($gallery_info)) { $_gallery_info = $GLOBALS['SITE_DB']->query_select('galleries', array('fullname', 'is_member_synched', 'accept_images', 'accept_videos'), array('name' => $category_id), '', 1); if (!array_key_exists(0, $_gallery_info)) { warn_exit(do_lang_tempcode('_MISSING_RESOURCE', escape_html('gallery:' . $category_id))); } $gallery_info = $_gallery_info[0]; } $title = array_key_exists('text_original', $gallery_info) ? $gallery_info['text_original'] : get_translated_text($gallery_info['fullname']); $is_member_synched = $gallery_info['is_member_synched'] == 1; $accept_images = $gallery_info['accept_images'] == 1; $accept_videos = $gallery_info['accept_videos'] == 1; $tree .= $title; $children = array(); $sub = false; $query = 'FROM ' . get_table_prefix() . 'galleries g LEFT JOIN ' . get_table_prefix() . 'translate t ON ' . db_string_equal_to('language', user_lang()) . ' AND g.fullname=t.id WHERE ' . db_string_equal_to('parent_id', $category_id); if (current(current($GLOBALS['SITE_DB']->query('SELECT COUNT(*) ' . $query))) >= 300) { $rows = $GLOBALS['SITE_DB']->query('SELECT text_original,name,fullname,accept_images,accept_videos,is_member_synched,g.fullname ' . $query . ' ORDER BY add_date', 300); } else { $rows = $GLOBALS['SITE_DB']->query('SELECT text_original,name,fullname,accept_images,accept_videos,is_member_synched,g.fullname ' . $query . ' ORDER BY text_original ASC'); } if ((is_null($filter) || call_user_func_array($filter, array($category_id, $member_id, count($rows)))) && (!$must_accept_images || $accept_images && !$is_member_synched) && (!$must_accept_videos || $accept_videos && !$is_member_synched)) { // We'll be putting all children in this entire tree into a single list $children[0]['id'] = $category_id; $children[0]['tree'] = $tree; $children[0]['title'] = $title; $children[0]['accept_images'] = $gallery_info['accept_images']; $children[0]['accept_videos'] = $gallery_info['accept_videos']; $children[0]['is_member_synched'] = $gallery_info['is_member_synched']; if ($addable_filter) { $children[0]['addable'] = has_submit_permission('mid', get_member(), get_ip_address(), 'cms_galleries', array('galleries', $category_id)); } if ($do_stats) { $good_row_count = 0; foreach ($rows as $row) { if ((is_null($filter) || call_user_func_array($filter, array($row['name'], $member_id, 1))) && (!$must_accept_images || $row['accept_images'] && $row['is_member_synched'] == 0) && (!$must_accept_videos || $row['accept_videos'] && $row['is_member_synched'] == 0)) { $good_row_count++; } } $children[0]['child_count'] = $good_row_count; if ($good_row_count == 0 && !$purity && $gallery_info['is_member_synched']) { $children[0]['child_count'] = 1; } // XHTMLXHTML $children[0]['video_count'] = $GLOBALS['SITE_DB']->query_value('videos', 'COUNT(*)', array('cat' => $category_id)); $children[0]['image_count'] = $GLOBALS['SITE_DB']->query_value('images', 'COUNT(*)', array('cat' => $category_id)); } $sub = true; } $can_submit = mixed(); // Children of this category $tree .= ' > '; $found_own_gallery = false; $found_member_galleries = array($GLOBALS['FORUM_DRIVER']->get_guest_id() => 1); $compound_list = $category_id . ','; foreach ($rows as $child) { if ($child['name'] == 'root') { continue; } $can_submit = can_submit_to_gallery($child['name']); if ($can_submit === false) { $can_submit = !$addable_filter; } if ($can_submit !== false && $can_submit !== true) { $found_own_gallery = true; $found_member_galleries[$can_submit] = 1; } if ($can_submit !== false && ($levels !== 0 || $use_compound_list)) { $child_id = $child['name']; // $child_title=$child['text_original']; $child_tree = $tree; $child_children = get_gallery_tree($child_id, $child_tree, $child, $do_stats, $filter, $must_accept_images, $must_accept_videos, $purity, $use_compound_list, is_null($levels) ? NULL : $levels - 1, $member_id, $addable_filter); if ($use_compound_list) { list($child_children, $_compound_list) = $child_children; $compound_list .= $_compound_list; } if ($levels !== 0) { $children = array_merge($children, $child_children); } } } if ($sub && array_key_exists(0, $children)) { $children[0]['compound_list'] = $compound_list; } $done_for_all = false; if ($is_member_synched && !$purity && $levels !== 0) { if (has_specific_permission(get_member(), 'can_submit_to_others_categories') && get_forum_type() == 'ocf') { ocf_require_all_forum_stuff(); $members = $GLOBALS['FORUM_DB']->query_select('f_members', array('id', 'm_username', 'm_primary_group'), NULL, 'ORDER BY m_username', 100); if (count($members) != 100) { $done_for_all = true; $group_membership = $GLOBALS['FORUM_DB']->query_select('f_group_members', array('gm_group_id', 'gm_member_id'), array('gm_validated' => 1)); $group_permissions = $GLOBALS['SITE_DB']->query('SELECT group_id,the_page,the_value FROM ' . $GLOBALS['SITE_DB']->get_table_prefix() . 'gsp WHERE ' . db_string_equal_to('specific_permission', 'have_personal_category') . ' AND (' . db_string_equal_to('the_page', '') . ' OR ' . db_string_equal_to('the_page', 'cms_galleries') . ')'); $is_super_admin = $GLOBALS['FORUM_DRIVER']->is_super_admin(get_member()); foreach ($members as $_member) { $member = $_member['id']; $username = $_member['m_username']; $this_category_id = 'member_' . strval($member) . '_' . $category_id; if ($member == get_member()) { $has_permission = true; } else { $a = in_array(array('group_id' => $member['m_primary_group'], 'the_page' => '', 'the_value' => 1), $group_permissions); $b = in_array(array('group_id' => $member['m_primary_group'], 'the_page' => 'cms_galleries', 'the_value' => 0), $group_permissions); $c = in_array(array('group_id' => $member['m_primary_group'], 'the_page' => 'cms_galleries', 'the_value' => 1), $group_permissions); $has_permission = $is_super_admin; if ($a && !$b || $c) { $has_permission = true; } if (!$has_permission) { foreach ($group_membership as $_g) { if ($_g['gm_member_id'] == $member) { $a = in_array(array('group_id' => $_g['gm_group_id'], 'the_page' => '', 'the_value' => 1), $group_permissions); $b = in_array(array('group_id' => $_g['gm_group_id'], 'the_page' => 'cms_galleries', 'the_value' => 0), $group_permissions); $c = in_array(array('group_id' => $_g['gm_group_id'], 'the_page' => 'cms_galleries', 'the_value' => 1), $group_permissions); if ($a && !$b || $c) { $has_permission = true; } break; } } } } if ($has_permission && !array_key_exists($member, $found_member_galleries) && (is_null($filter) || call_user_func_array($filter, array($this_category_id, $member_id, 0)))) { $own_gallery = array(); $own_gallery['id'] = $this_category_id; $this_title = do_lang('NEW_PERSONAL_GALLERY_OF', $username, $title); $own_gallery['tree'] = $tree . $this_title; $own_gallery['video_count'] = 0; $own_gallery['image_count'] = 0; $own_gallery['child_count'] = 0; $own_gallery['title'] = $this_title; $own_gallery['accept_images'] = $gallery_info['accept_images']; $own_gallery['accept_videos'] = $gallery_info['accept_videos']; $own_gallery['is_member_synched'] = 0; $own_gallery['compound_list'] = $compound_list; $own_gallery['addable'] = true; $children[] = $own_gallery; if ($member == get_member()) { $found_own_gallery = true; } } } } } if ((!$done_for_all || !$found_own_gallery) && !array_key_exists(get_member(), $found_member_galleries) && !is_guest() && !$purity && has_specific_permission(get_member(), 'have_personal_category')) { $this_category_id = 'member_' . strval(get_member()) . '_' . $category_id; if (is_null($filter) || call_user_func_array($filter, array($this_category_id, $member_id, 0))) { $own_gallery = array(); $own_gallery['id'] = $this_category_id; $this_title = do_lang('NEW_PERSONAL_GALLERY_OF', $GLOBALS['FORUM_DRIVER']->get_username(get_member()), $title); $own_gallery['tree'] = $tree . $this_title; $own_gallery['video_count'] = 0; $own_gallery['image_count'] = 0; $own_gallery['child_count'] = 0; $own_gallery['title'] = $this_title; $own_gallery['accept_images'] = $gallery_info['accept_images']; $own_gallery['accept_videos'] = $gallery_info['accept_videos']; $own_gallery['is_member_synched'] = 0; $own_gallery['addable'] = true; $own_gallery['compound_list'] = $compound_list; $children[] = $own_gallery; } } } return $use_compound_list ? array($children, $compound_list) : $children; }