function xthreads_tfvalue_settable(&$tf, $val) { if (empty($tf['editable_values'])) { return true; } $cv = (string) xthreads_convert_str_to_datatype($val, $tf['datatype']); $allow_groups = $tf['editable_values'][$cv]; return !isset($allow_groups) || !xthreads_empty($allow_groups) && xthreads_user_in_groups($allow_groups); }
function xthreads_forumdisplay() { global $db, $threadfield_cache, $fid, $mybb, $tf_filters, $xt_filters, $filters_set, $xthreads_forum_filter_form, $xthreads_forum_filter_args; // the position of the "forumdisplay_start" hook is kinda REALLY annoying... $fid = (int) $mybb->input['fid']; if ($fid < 1 || !($forum = get_forum($fid))) { return; } // replicate some MyBB behaviour if (!isset($mybb->input['sortby']) && !empty($forum['defaultsortby'])) { $mybb->input['sortby'] = $forum['defaultsortby']; } $threadfield_cache = xthreads_gettfcache($fid); // Quick Thread integration if (!empty($threadfield_cache) && function_exists('quickthread_run')) { xthreads_forumdisplay_quickthread(); } $fpermissions = forum_permissions($fid); $show_threads = $fpermissions['canview'] == 1 && $fpermissions['canviewthreads'] != 0; $tf_filters = array(); $filters_set = array('__search' => array('hiddencss' => '', 'visiblecss' => 'display: none;', 'selected' => array('' => ' selected="selected"'), 'checked' => array('' => ' checked="checked"'), 'active' => array('' => 'filtertf_active'), 'nullselected' => ' selected="selected"', 'nullchecked' => ' checked="checked"', 'nullactive' => 'filtertf_active'), '__all' => array('hiddencss' => '', 'visiblecss' => 'display: none;', 'nullselected' => ' selected="selected"', 'nullchecked' => ' checked="checked"', 'nullactive' => 'filtertf_active')); $xthreads_forum_filter_form = $xthreads_forum_filter_args = ''; $use_default_filter = true; if (!empty($threadfield_cache)) { if ($show_threads) { function xthreads_forumdisplay_dbhook(&$s, &$db) { global $threadfield_cache, $fid, $plugins, $threadfields, $xthreads_forum_sort; //if(empty($threadfield_cache)) return; $fields = ''; foreach ($threadfield_cache as &$v) { $fields .= ', tfd.`' . $v['field'] . '` AS `xthreads_' . $v['field'] . '`'; } $sortjoin = ''; if (!empty($xthreads_forum_sort) && isset($xthreads_forum_sort['sortjoin'])) { $sortjoin = ' LEFT JOIN ' . $db->table_prefix . $xthreads_forum_sort['sortjoin']; } $s = strtr($s, array('SELECT t.*, ' => 'SELECT t.*' . $fields . ', ', 'WHERE t.fid=' => 'LEFT JOIN `' . $db->table_prefix . 'threadfields_data` tfd ON t.tid=tfd.tid' . $sortjoin . ' WHERE t.fid=')); $plugins->add_hook('forumdisplay_thread', 'xthreads_forumdisplay_thread'); $threadfields = array(); } control_object($db, ' function query($string, $hide_errors=0, $write_query=0) { static $done=false; if(!$done && !$write_query && strpos($string, \'SELECT t.*, \') && strpos($string, \'t.username AS threadusername, u.username\') && strpos($string, \'FROM ' . TABLE_PREFIX . 'threads t\')) { $done = true; xthreads_forumdisplay_dbhook($string, $this); } return parent::query($string, $hide_errors, $write_query); } '); } // also check for forumdisplay filters/sort // and generate form HTML foreach ($threadfield_cache as $n => &$tf) { $filters_set[$n] = array('hiddencss' => '', 'visiblecss' => 'display: none;', 'nullselected' => ' selected="selected"', 'nullchecked' => ' checked="checked"', 'nullactive' => 'filtertf_active'); if ($tf['ignoreblankfilter']) { // will be overwritten if not blank $filters_set[$n]['selected'] = array('' => ' selected="selected"'); $filters_set[$n]['checked'] = array('' => ' checked="checked"'); $filters_set[$n]['active'] = array('' => 'filtertf_active'); } if ($tf['allowfilter'] && isset($mybb->input['filtertf_' . $n]) && xthreads_user_in_groups($tf['viewable_gids'])) { $tf_filters[$n] = $mybb->input['filtertf_' . $n]; $use_default_filter = false; // ignore blank inputs if ($tf['ignoreblankfilter'] && (is_array($tf_filters[$n]) && (empty($tf_filters[$n]) || array_unique($tf_filters[$n]) == array('')) || $tf_filters[$n] === '')) { unset($tf_filters[$n]); } } } // sorting by thread fields if ($mybb->input['sortby'] && substr($mybb->input['sortby'], 0, 2) == 'tf') { global $xthreads_forum_sort; if (substr($mybb->input['sortby'], 0, 3) == 'tf_') { $n = substr($mybb->input['sortby'], 3); if (isset($threadfield_cache[$n]) && xthreads_empty($threadfield_cache[$n]['multival']) && $threadfield_cache[$n]['inputtype'] != XTHREADS_INPUT_FILE && xthreads_user_in_groups($threadfield_cache[$n]['viewable_gids'])) { if ($threadfield_cache[$n]['inputtype'] != XTHREADS_INPUT_TEXTAREA) { // also disallow sorting by textarea inputs $xthreads_forum_sort = array('t' => 'tfd.', 'sortby' => $mybb->input['sortby'], 'sortfield' => '`' . $n . '`'); } } } elseif (substr($mybb->input['sortby'], 0, 4) == 'tfa_') { $p = strpos($mybb->input['sortby'], '_', 5); if ($p) { $field = strtolower(substr($mybb->input['sortby'], 4, $p - 4)); $n = substr($mybb->input['sortby'], $p + 1); if (isset($threadfield_cache[$n]) && xthreads_empty($threadfield_cache[$n]['multival']) && $threadfield_cache[$n]['inputtype'] == XTHREADS_INPUT_FILE && xthreads_user_in_groups($threadfield_cache[$n]['viewable_gids']) && in_array($field, array('filename', 'filesize', 'uploadtime', 'updatetime', 'downloads'))) { $xthreads_forum_sort = array('t' => 'xta.', 'sortby' => $mybb->input['sortby'], 'sortfield' => '`' . $field . '`', 'sortjoin' => 'xtattachments xta ON tfd.`' . $n . '`=xta.aid'); } } } } } if (!isset($xthreads_forum_sort) && $mybb->input['sortby'] && in_array($mybb->input['sortby'], array('prefix', 'icon', 'lastposter', 'numratings', 'attachmentcount'))) { global $xthreads_forum_sort; switch ($mybb->input['sortby']) { case 'prefix': if ($mybb->version_code >= 1500) { $xthreads_forum_sort = array('t' => $mybb->version_code >= 1604 ? 't.' : 'p.', 'sortby' => $mybb->input['sortby'], 'sortfield' => $mybb->input['sortby']); } break; case 'icon': $xthreads_forum_sort = array('t' => 't.', 'sortby' => $mybb->input['sortby'], 'sortfield' => $mybb->input['sortby']); break; case 'lastposter': case 'numratings': case 'attachmentcount': $xthreads_forum_sort = array('t' => 't.', 'sortby' => $mybb->input['sortby'], 'sortfield' => $mybb->input['sortby']); } } $xt_filters = array(); //$enabled_xtf = explode(',', $forum['xthreads_addfiltenable']); //if(!empty($enabled_xtf)) { //global $lang; //foreach($enabled_xtf as &$xtf) { $enabled_xtf = array('uid', 'icon', 'lastposteruid'); if ($mybb->version_code >= 1500) { $enabled_xtf[] = 'prefix'; } foreach ($enabled_xtf as &$xtf) { $filters_set['__xt_' . $xtf] = array('hiddencss' => '', 'visiblecss' => 'display: none;', 'nullselected' => ' selected="selected"', 'nullchecked' => ' checked="checked"', 'nullactive' => 'filtertf_active'); if (isset($mybb->input['filterxt_' . $xtf]) && $mybb->input['filterxt_' . $xtf] !== '') { $xt_filters[$xtf] = $mybb->input['filterxt_' . $xtf]; $use_default_filter = false; } } unset($enabled_xtf); //} if (function_exists('xthreads_evalcacheForumFilters')) { $xtforum = xthreads_evalcacheForumFilters($fid); if ($use_default_filter && (!empty($xtforum['defaultfilter_tf']) || !empty($xtforum['defaultfilter_xt'])) && !$mybb->input['filterdisable']) { $tf_filters = $xtforum['defaultfilter_tf']; foreach ($tf_filters as $n => &$filter) { if (!xthreads_user_in_groups($threadfield_cache[$n]['viewable_gids'])) { unset($tf_filters[$n]); continue; } } $xt_filters = $xtforum['defaultfilter_xt']; } //unset($enabled_xtf); } foreach ($tf_filters as $n => &$filter) { xthreads_forumdisplay_filter_input('filtertf_' . $n, $filter, $filters_set[$n]); } foreach ($xt_filters as $n => &$filter) { /* // sanitise input here as we may need to grab extra info if(is_array($filter)) $filter = array_map('intval', $filter); else $filter = (int)$filter; */ xthreads_forumdisplay_filter_input('filterxt_' . $n, $filter, $filters_set['__xt_' . $n]); /* if(is_array($filter)) $ids = implode(',', $filter); else $ids = $filter; // grab extra info for $filter_set array switch($n) { case 'uid': case 'lastposteruid': // perhaps might be nice if we could merge these two together... $info = xthreads_forumdisplay_xtfilter_extrainfo('users', array('username'), 'uid', $ids, 'guest'); $filters_set['__xt_'.$n]['name'] = $info['username']; break; case 'prefix': // displaystyles? if(!$lang->xthreads_no_prefix) $lang->load('xthreads'); $info = xthreads_forumdisplay_xtfilter_extrainfo('threadprefixes', array('prefix', 'displaystyle'), 'pid', $ids, 'xthreads_no_prefix'); $filters_set['__xt_'.$n]['name'] = $info['prefix']; $filters_set['__xt_'.$n]['displayname'] = $info['displaystyle']; break; case 'icon': // we'll retrieve icons from the cache rather than query the DB $icons = $GLOBALS['cache']->read('posticons'); if(is_array($filter)) $ids =& $filter; else $ids = array($ids); $filters_set['__xt_'.$n]['name'] = ''; $iconstr =& $filters_set['__xt_'.$n]['name']; foreach($ids as $id) { if($id && $icons[$id]) $iconstr .= ($iconstr?', ':'') . htmlspecialchars_uni($icons[$id]['name']); elseif(!$id) { if(!$lang->xthreads_no_icon) $lang->load('xthreads'); $iconstr .= ($iconstr?', ':'') . '<em>'.$lang->xthreads_no_icon.'</em>'; } } unset($icons); break; } */ } unset($filter); if ($xthreads_forum_filter_args) { $filters_set['__all']['urlarg'] = htmlspecialchars_uni(substr($xthreads_forum_filter_args, 1)); $filters_set['__all']['urlarga'] = '&' . $filters_set['__all']['urlarg']; $filters_set['__all']['urlargq'] = '?' . $filters_set['__all']['urlarg']; $filters_set['__all']['forminput'] = $xthreads_forum_filter_form; $filters_set['__all']['hiddencss'] = 'display: none;'; $filters_set['__all']['visiblecss'] = ''; unset($filters_set['__all']['nullselected'], $filters_set['__all']['nullchecked'], $filters_set['__all']['nullactive']); } if ($forum['xthreads_inlinesearch'] && isset($mybb->input['search']) && $mybb->input['search'] !== '') { $urlarg = 'search=' . rawurlencode($mybb->input['search']); $xthreads_forum_filter_args .= '&' . $urlarg; $GLOBALS['xthreads_forum_search_form'] = '<input type="hidden" name="search" value="' . htmlspecialchars_uni($mybb->input['search']) . '" />'; $filters_set['__search']['forminput'] =& $GLOBALS['xthreads_forum_search_form']; $filters_set['__search']['value'] = htmlspecialchars_uni($mybb->input['search']); $filters_set['__search']['urlarg'] = htmlspecialchars_uni($urlarg); $filters_set['__search']['urlarga'] = '&' . $filters_set['__search']['urlarg']; $filters_set['__search']['urlargq'] = '?' . $filters_set['__search']['urlarg']; $filters_set['__search']['selected'] = array($mybb->input['search'] => ' selected="selected"'); $filters_set['__search']['checked'] = array($mybb->input['search'] => ' checked="checked"'); $filters_set['__search']['active'] = array($mybb->input['search'] => 'filtertf_active'); $filters_set['__search']['hiddencss'] = 'display: none;'; $filters_set['__search']['visiblecss'] = ''; unset($filters_set['__search']['nullselected'], $filters_set['__search']['nullchecked'], $filters_set['__search']['nullactive']); } if ($show_threads) { $using_filter = $forum['xthreads_inlinesearch'] || !empty($tf_filters) || !empty($xt_filters); if ($using_filter || isset($xthreads_forum_sort)) { // only nice way to do all of this is to gain control of $templates, so let's do it control_object($GLOBALS['templates'], ' function get($title, $eslashes=1, $htmlcomments=1) { static $done=false; if(!$done && $title == \'forumdisplay_orderarrow\') { $done = true; ' . ($using_filter ? 'xthreads_forumdisplay_filter();' : '') . ' ' . (isset($xthreads_forum_sort) ? ' $orderbyhack = xthreads_forumdisplay_sorter(); return $orderbyhack.parent::get($title, $eslashes, $htmlcomments); ' : '') . ' } return parent::get($title, $eslashes, $htmlcomments); } '); /* if($forum['xthreads_inlinesearch']) { // give us a bit of a free speed up since this isn't really being used anyway... $templates->cache['forumdisplay_searchforum'] = ''; } */ // generate stuff for pagination/sort-links and fields for forms (sort listboxes, inline search) } } if ($forum['xthreads_fdcolspan_offset']) { control_object($GLOBALS['cache'], ' function read($name, $hard=false) { static $done=false; if(!$done && $name == "posticons" && isset($GLOBALS["colspan"])) { $done = true; $GLOBALS["colspan"] += $GLOBALS["foruminfo"]["xthreads_fdcolspan_offset"]; } return parent::read($name, $hard); } '); } }
function xthreads_sanitize_disp(&$s, &$tfinfo, $mename = null, $noextra = false) { $evalfunc = 'xthreads_evalcache_' . $tfinfo['field']; if (!$noextra) { // this "hack" stops this function being totally independent of the outside world :( global $threadfields_x; if (!isset($threadfields_x)) { $threadfields_x = array(); } $sx =& $threadfields_x[$tfinfo['field']]; } // otherwise, let the following line dummy the variable $sx = array('title' => htmlspecialchars_uni($tfinfo['title']), 'desc' => htmlspecialchars_uni($tfinfo['desc']), 'num_values' => 1, 'num_values_friendly' => my_number_format(1), 'raw_value' => $s); $dispfmt = 'dispformat'; if (!xthreads_user_in_groups($tfinfo['viewable_gids'])) { $dispfmt = 'unviewableval'; } if ($tfinfo['inputtype'] == XTHREADS_INPUT_FILE || $tfinfo['inputtype'] == XTHREADS_INPUT_FILE_URL && !preg_match('~^[a-z]+\\://~i', $s)) { global $xta_cache, $mybb; // attached file if (!$s) { $s = array('value' => $evalfunc('blankval')); xthreads_sanitize_disp_set_blankthumbs($s, $tfinfo); return; } if (xthreads_empty($tfinfo['multival'])) { xthreads_sanitize_disp_set_xta_fields($s, $s, $tfinfo, $dispfmt, $evalfunc); $sx['value'] =& $s['value']; } else { $aids = explode(',', $s); $s = array('total_downloads' => 0, 'total_filesize' => 0, 'updatetime' => 0, 'uploadtime' => 0, 'value' => '', 'num_files' => 0); $sx['items'] = $sx['value'] = array(); $comma = ''; foreach ($aids as $aid) { $xta =& $sx['items'][]; xthreads_sanitize_disp_set_xta_fields($xta, $aid, $tfinfo, 'dispitemformat', $evalfunc); if (!$xta['aid']) { continue; } $sx['value'][] = $xta['value']; $s['total_downloads'] += $xta['downloads']; $s['total_filesize'] += $xta['filesize']; $s['uploadtime'] = max($xta['uploadtime'], $s['uploadtime']); ++$s['num_files']; $s['value'] .= $comma . $xta['value']; $comma = $tfinfo['multival']; } $s['total_downloads_friendly'] = my_number_format($s['total_downloads']); $s['total_filesize_friendly'] = get_friendly_size($s['total_filesize']); $s['upload_time'] = my_date($mybb->settings['timeformat'], $s['uploadtime']); $s['upload_date'] = my_date($mybb->settings['dateformat'], $s['uploadtime']); $s['value'] = $evalfunc($dispfmt, array('VALUE' => $s['value'])); $sx['num_values'] = $s['num_files']; $sx['num_values_friendly'] = $s['num_files_friendly'] = my_number_format($s['num_files']); } } else { if ($s === '' || $s === null) { $sx['num_values'] = 0; $sx['num_values_friendly'] = my_number_format(0); $s = $evalfunc('blankval'); return; } if (!xthreads_empty($tfinfo['multival'])) { // we _could_ optimise this out if the final $dispformat never actually refers to {VALUE}, but this is perhaps an unlikely situation, and we don't know whether the dispitemformat has some special eval'd code we should run $vals = explode("\n", str_replace("\r", '', $s)); $i = 0; $sx['value'] = array(); foreach ($vals as &$v) { xthreads_sanitize_disp_field($v, $tfinfo, 'dispitemformat', $mename); $sx['value'][$i++] = $v; } $sx['num_values'] = $i; $sx['num_values_friendly'] = my_number_format($i); $s = implode($tfinfo['multival'], $vals); $s = $evalfunc($dispfmt, array('VALUE' => $s)); } else { xthreads_sanitize_disp_field($s, $tfinfo, $dispfmt, $mename); $sx['value'] =& $s; } } }