Example #1
0
/**
 * Render a menu branch to tempcode.
 *
 * @param  array			The menu branch map
 * @param  SHORT_TEXT	An identifier for the menu (will be used as a unique id by menu javascript code)
 * @param  MEMBER			The member the menu is being built as
 * @param  integer		The depth into the menu that this branch resides at
 * @param  ID_TEXT		The menu type (determines what templates get used)
 * @param  boolean		Whether to generate Comcode with admin privilege
 * @param  array			Array of all other branches
 * @param  integer		The level
 * @return array			A pair: array of parameters of the menu branch (or NULL if unrenderable, or Tempcode of something to attach), and whether it is expanded
 */
function render_menu_branch($branch, $codename, $source_member, $level, $type, $as_admin, $all_branches, $the_level = 1)
{
    global $REDIRECTED_TO;
    $caption = mixed();
    // Initialise type to mixed
    if (is_string($branch['caption']) && strpos($branch['caption'], '[') !== false) {
        $caption = comcode_to_tempcode($branch['caption'], $source_member, $as_admin);
    } else {
        $caption = $branch['caption'];
    }
    if (!is_null($branch['only_on_page']) && $branch['only_on_page'] != '') {
        if (strpos($branch['only_on_page'], '{') !== false) {
            require_code('tempcode_compiler');
            $branch['only_on_page'] = static_evaluate_tempcode(template_to_tempcode($branch['only_on_page']));
        }
        if ($branch['only_on_page'] != '' && !match_key_match($branch['only_on_page'])) {
            return array(NULL, false);
        }
        // We are not allowed to render this on this page
    }
    $current_zone = false;
    $current_page = false;
    $expand_this = false;
    $tooltip = array_key_exists('caption_long', $branch) ? $branch['caption_long'] : '';
    if (is_null($tooltip)) {
        $tooltip = '';
    }
    // Caused by corrupt in DB. translate table join failed due to corrupt lang string reference
    $dp = $GLOBALS['ZONE']['zone_default_page'];
    $url = mixed();
    // Spacers
    if ($branch['type'] == 'blank') {
        return array(do_template('MENU_SPACER_' . filter_naughty_harsh($type), array('MENU' => $codename, 'TOP_LEVEL' => $the_level == 1, 'THE_LEVEL' => strval($the_level), 'CURRENT' => $current_page, 'CURRENT_ZONE' => $current_zone), NULL, false, 'MENU_SPACER_tree'), false);
    }
    // Normal branches...
    $users_current_zone = get_zone_name();
    // Work out the final URL to use
    $url = $branch['special'];
    if (is_object($url)) {
        if (isset($url->seq_parts) && isset($url->seq_parts[0]) && $url->seq_parts[0][3] == 'PAGE_LINK') {
            $url = $url->seq_parts[0][1][0];
            if (is_object($url)) {
                $url = $url->evaluate();
            }
        } elseif (isset($url->bits) && isset($url->bits[0]) && $url->bits[0][2] == 'PAGE_LINK') {
            $url = $url->bits[0][3][0];
            if (is_object($url)) {
                $url = $url->evaluate();
            }
        } elseif (substr($url->evaluate(), 0, strlen(get_base_url())) == get_base_url()) {
            $page_link = url_to_pagelink($url->evaluate(), true, true);
            if ($page_link != '') {
                $url = $page_link;
            }
        }
    }
    if (!is_object($url)) {
        $parts = array();
        if (preg_match('#([\\w-]*):([\\w-]+|[^/]|$)((:(.*))*)#', $url, $parts) != 0 && $parts[1] != 'mailto') {
            $page_link = $url;
            list($zone_name, $map, $hash) = page_link_decode($url);
            if ($zone_name == 'forum' && get_forum_type() != 'ocf') {
                return array(NULL, false);
            }
            if (!isset($map['page'])) {
                $map['page'] = get_zone_default_page($zone_name);
            }
            // If we need to check access
            if (array_key_exists('check_perms', $branch['modifiers'])) {
                if (!has_zone_access(get_member(), $zone_name)) {
                    return array(NULL, false);
                }
                if (!has_page_access(get_member(), $map['page'], $zone_name)) {
                    return array(NULL, false);
                }
            }
            // Scan for Tempcode symbols etc
            foreach ($map as $key => $val) {
                if (strpos($val, '{') !== false) {
                    require_code('tempcode_compiler');
                    $map[$key] = template_to_tempcode($val);
                }
            }
            $url = build_url($map, $zone_name, NULL, false, false, false, $hash);
            // See if this is current page
            $somewhere_definite = false;
            $_parts = array();
            foreach ($all_branches as $_branch) {
                if (!is_string($_branch['special'])) {
                    continue;
                }
                if (preg_match('#([\\w-]*):([\\w-]+|[^/]|$)((:(.*))*)#', $_branch['special'], $_parts) != 0) {
                    if ($_parts[1] == $users_current_zone) {
                        $somewhere_definite = true;
                    }
                }
            }
            $current_zone = $zone_name == $users_current_zone || !is_null($REDIRECTED_TO) && $zone_name == $REDIRECTED_TO['r_to_zone'] && !$somewhere_definite;
            // This code is a bit smart, as zone menus usually have a small number of zones on them - redirects will be counted into the zone redirected to, so long as there is no more suitable zone and so long as it is not a transparent redirect
            if ($zone_name == $users_current_zone || !is_null($REDIRECTED_TO) && $zone_name == $REDIRECTED_TO['r_to_zone'] && array_key_exists('page', $map) && $map['page'] == $REDIRECTED_TO['r_to_page']) {
                $current_page = true;
                foreach ($map as $k => $v) {
                    if (is_integer($v)) {
                        $v = strval($v);
                    }
                    if (is_object($v)) {
                        $v = $v->evaluate();
                    }
                    if ($v == '' && $k == 'page') {
                        $v = 'start';
                        if ($zone_name == $users_current_zone) {
                            global $ZONE;
                            $v = $ZONE['zone_default_page'];
                        }
                    }
                    $pv = get_param($k, $k == 'page' ? $dp : NULL, true);
                    if ($pv !== $v && ($k != 'page' || is_null($REDIRECTED_TO) || !is_null($REDIRECTED_TO) && ($v !== $REDIRECTED_TO['r_to_page'] || $zone_name != $REDIRECTED_TO['r_to_zone'])) && ($k != 'type' || $v != 'misc') && ($v != $dp || $k != 'page' || get_param('page', '') != '') && substr($k, 0, 5) != 'keep_') {
                        $current_page = false;
                        break;
                    }
                }
            }
        } else {
            $page_link = '';
            $sym_pos = mixed();
            $sym_pos = is_null($url) ? false : strpos($url, '{$');
            if ($sym_pos !== false) {
                $_url = new ocp_tempcode();
                $len = strlen($url);
                $prev = 0;
                do {
                    $p_len = $sym_pos + 1;
                    $balance = 1;
                    while ($p_len < $len && $balance != 0) {
                        if ($url[$p_len] == '{') {
                            $balance++;
                        } elseif ($url[$p_len] == '}') {
                            $balance--;
                        }
                        $p_len++;
                    }
                    $_url->attach(substr($url, $prev, $sym_pos - $prev));
                    $_ret = new ocp_tempcode();
                    $_ret->parse_from($url, $sym_pos, $p_len);
                    $_url->attach($_ret);
                    $prev = $p_len;
                    $sym_pos = strpos($url, '{$', $sym_pos + 1);
                } while ($sym_pos !== false);
                $_url->attach(substr($url, $prev));
                $url = $_url;
            }
        }
    } else {
        $page_link = NULL;
    }
    // Children
    $children = new ocp_tempcode();
    $display = 'block';
    if ($branch['type'] == 'drawer') {
        $new_children = array();
        foreach ($branch['children'] as $i => $child) {
            list($children2, $_expand_this) = render_menu_branch($child, $codename, $source_member, $level + 1, $type, $as_admin, $all_branches, $the_level + 1);
            if ($_expand_this) {
                $expand_this = true;
            }
            if ($children2 !== '' && !is_null($children2)) {
                $new_children[] = $children2;
            }
        }
        $num = count($new_children);
        foreach ($new_children as $i => $child) {
            if (is_object($child)) {
                $children->attach($child);
            } else {
                $children->attach(do_template('MENU_BRANCH_' . filter_naughty_harsh($type), $child + array('POSITION' => strval($i), 'LAST' => $i == $num - 1, 'BRETHREN_COUNT' => strval($num)), NULL, false, 'MENU_BRANCH_tree'));
            }
        }
        if ($children->is_empty()) {
            return array(NULL, false);
        }
        // Nothing here!
        if (!array_key_exists('expanded', $branch['modifiers']) && !$expand_this && !$current_page) {
            $display = has_js() ? 'none' : 'block';
            // We remap to 'none' using JS. If no JS, it remains visible. Once we have learn't we have JS, we don't need to do it again
        } else {
            $display = 'block';
        }
    }
    // Data cleanups
    $escape = is_string($caption) && !array_key_exists('comcode', $branch['modifiers']);
    if ($escape) {
        $caption = escape_html($caption);
    }
    // Access key
    if ($page_link === '_SEARCH:help') {
        $accesskey = '6';
    } elseif ($page_link === '_SEARCH:rules') {
        $accesskey = '7';
    } elseif ($page_link === '_SEARCH:staff:type=misc') {
        $accesskey = '5';
    } else {
        $accesskey = '';
    }
    // Other properties
    $popup = array_key_exists('popup', $branch['modifiers']);
    $popup_width = '';
    $popup_height = '';
    if ($popup) {
        $popup_width = strval($branch['width']);
        $popup_height = strval($branch['height']);
    }
    $new_window = array_key_exists('new_window', $branch['modifiers']);
    // Render!
    $rendered_branch = array('RANDOM' => substr(md5(uniqid('')), 0, 7), 'CAPTION' => $caption, 'IMG' => array_key_exists('img', $branch) ? $branch['img'] : '', 'URL' => $url, 'PAGE_LINK' => $page_link, 'ACCESSKEY' => $accesskey, 'POPUP' => $popup, 'POPUP_WIDTH' => $popup_width, 'POPUP_HEIGHT' => $popup_height, 'NEW_WINDOW' => $new_window, 'TOOLTIP' => $tooltip, 'CHILDREN' => $children, 'DISPLAY' => $display, 'MENU' => $codename, 'TOP_LEVEL' => $the_level == 1, 'THE_LEVEL' => strval($the_level), 'CURRENT' => $current_page, 'CURRENT_ZONE' => $current_zone);
    return array($rendered_branch, $current_page || $expand_this);
}
Example #2
0
/**
 * Take a page link and convert to attributes and zone.
 *
 * @param  SHORT_TEXT	The page link
 * @return array			Triple: zone, attribute-array, hash part of a URL including the hash (or blank)
 */
function page_link_decode($param)
{
    global $CHR_0;
    if (strpos($param, '#') === false) {
        $hash = '';
    } else {
        $hash_pos = strpos($param, '#');
        $hash = substr($param, $hash_pos);
        $param = substr($param, 0, $hash_pos);
    }
    if (strpos($param, $CHR_0) === false) {
        $bits = explode(':', $param);
    } else {
        $term_pos = strpos($param, $CHR_0);
        $bits = explode(':', substr($param, 0, $term_pos));
        $bits[count($bits) - 1] .= substr($param, $term_pos);
    }
    $zone = $bits[0];
    if ($zone == '_SEARCH') {
        if (isset($bits[1])) {
            $zone = get_page_zone($bits[1], false);
            if ($zone === NULL) {
                $zone = '';
            }
        } else {
            $zone = '';
        }
    } elseif ($zone == 'site' && get_option('collapse_user_zones') == '1') {
        $zone = '';
    } elseif ($zone == '_SELF') {
        $zone = get_zone_name();
    }
    if (isset($bits[1])) {
        if ($bits[1] != '') {
            if ($bits[1] == '_SELF') {
                $attributes = array('page' => get_page_name());
            } else {
                $attributes = array('page' => $bits[1]);
            }
        } else {
            $attributes = array();
        }
        unset($bits[1]);
    } else {
        $attributes = array('page' => get_zone_default_page($zone));
    }
    unset($bits[0]);
    $i = 0;
    foreach ($bits as $bit) {
        if ($bit != '' || $i == 1) {
            if ($i == 0 && strpos($bit, '=') === false) {
                $_bit = array('type', $bit);
            } elseif ($i == 1 && strpos($bit, '=') === false) {
                $_bit = array('id', $bit);
            } else {
                $_bit = explode('=', $bit, 2);
            }
        } else {
            $_bit = array($bit, '');
        }
        if (isset($_bit[1])) {
            $decoded = urldecode($_bit[1]);
            if ($decoded != '' && $decoded[0] == '{' && strlen($decoded) > 2 && intval($decoded[1]) > 51) {
                require_code('tempcode_compiler');
                $decoded = template_to_tempcode($decoded);
                $decoded = $decoded->evaluate();
            }
            if ($decoded == '<null>') {
                $attributes[$_bit[0]] = NULL;
            } else {
                $attributes[$_bit[0]] = $decoded;
            }
        }
        $i++;
    }
    return array($zone, $attributes, $hash);
}
Example #3
0
 /**
  * The UI to show page view statistics for the front page.
  *
  * @return tempcode		The UI
  */
 function overview()
 {
     $page_request = _request_page(get_zone_default_page(''), '');
     $page = $page_request[count($page_request) - 1];
     $title = get_page_title('OVERVIEW_STATISTICS');
     list($graph_views_monthly, $list_views_monthly) = array_values($this->views_per_x($page, 'views_hourly', 'VIEWS_PER_MONTH', 'DESCRIPTION_VIEWS_PER_MONTH', 730, 8766));
     //************************************************************************************************
     // Views
     //************************************************************************************************
     $start = get_param_integer('start_views', 0);
     $max = get_param_integer('max_views', 30);
     $sortables = array('date_and_time' => do_lang_tempcode('DATE_TIME'));
     list($sortable, $sort_order) = explode(' ', get_param('sort_views', 'date_and_time DESC'));
     if (strtoupper($sort_order) != 'ASC' && strtoupper($sort_order) != 'DESC' || !array_key_exists($sortable, $sortables)) {
         log_hack_attack_and_exit('ORDERBY_HACK');
     }
     global $NON_CANONICAL_PARAMS;
     $NON_CANONICAL_PARAMS[] = 'sort_views';
     // NB: not used in default templates
     $where = db_string_equal_to('the_page', $page);
     if (substr($page, 0, 6) == 'pages/') {
         $where .= ' OR ' . db_string_equal_to('the_page', '/' . $page);
     }
     // Legacy compatibility
     $rows = $GLOBALS['SITE_DB']->query('SELECT date_and_time FROM ' . get_table_prefix() . 'stats WHERE (' . $where . ') ORDER BY ' . $sortable . ' ' . $sort_order);
     if (count($rows) < 1) {
         $list_views = new ocp_tempcode();
     } else {
         require_code('templates_results_table');
         $fields_title = results_field_title(array(do_lang_tempcode('DATE_TIME'), do_lang_tempcode('COUNT_VIEWS')), $sortables, 'sort', $sortable . ' ' . $sort_order);
         $fields = new ocp_tempcode();
         $i = 0;
         while (array_key_exists($i, $rows)) {
             $row = $rows[$i];
             $date = get_timezoned_date($row['date_and_time'], false);
             $week = round($row['date_and_time'] / (60 * 60 * 24 * 7));
             $views = 0;
             while (array_key_exists($i + $views, $rows)) {
                 $_week = round($row['date_and_time'] / (60 * 60 * 24 * 7));
                 if ($_week != $week) {
                     break;
                 }
                 $views++;
             }
             $i += $views;
             if ($i < $start) {
                 continue;
             } elseif ($i >= $start + $max) {
                 break;
             }
             $fields->attach(results_entry(array($date, integer_format($views)), true));
         }
         $list_views = results_table(do_lang_tempcode('PAGES_STATISTICS', escape_html($page)), $start, 'start_views', $max, 'max_views', $i, $fields_title, $fields, $sortables, $sortable, $sort_order, 'sort_views');
     }
     breadcrumb_set_parents(array(array('_SELF:_SELF:misc', do_lang_tempcode('SITE_STATISTICS'))));
     return do_template('STATS_OVERVIEW_SCREEN', array('_GUID' => '71be91ba0d83368e1e1ceaf39e506610', 'TITLE' => $title, 'STATS_VIEWS' => $list_views, 'GRAPH_VIEWS_MONTHLY' => $graph_views_monthly, 'STATS_VIEWS_MONTHLY' => $list_views_monthly));
 }
Example #4
0
/**
 * Get an array of all the pages of the specified type (module, etc) and extension (for small sites everything will be returned, for larger ones it depends on the show method).
 *
 * @param  ID_TEXT		The zone name
 * @param  ID_TEXT		The type (including language, if appropriate)
 * @set    modules modules_custom comcode/EN comcode_custom/EN html/EN html_custom/EN
 * @param  string			The file extension to limit us to (without a dot)
 * @param  boolean		Whether to leave file extensions on the page name
 * @param  ?TIME			Only show pages newer than (NULL: no restriction)
 * @param  integer		Selection algorithm constant
 * @set 0 1 2
 * @param  ?boolean		Whether to search under the custom-file-base (NULL: auto-decide)
 * @return array			A map of page name to type (modules_custom, etc)
 */
function _find_all_pages($zone, $type, $ext = 'php', $keep_ext_on = false, $cutoff_time = NULL, $show_method = 0, $custom = NULL)
{
    $out = array();
    $module_path = $zone == '' ? 'pages/' . filter_naughty($type) : filter_naughty($zone) . '/pages/' . filter_naughty($type);
    if (is_null($custom)) {
        $custom = strpos($type, 'comcode_custom') !== false || strpos($type, 'html_custom') !== false;
        if ($custom && get_custom_file_base() != get_file_base()) {
            $out = _find_all_pages($zone, $type, $ext, false, NULL, $show_method, false);
        }
    }
    $stub = $custom ? get_custom_file_base() : get_file_base();
    $dh = @opendir($stub . '/' . $module_path);
    if ($dh !== false) {
        while (($file = readdir($dh)) !== false) {
            if (substr($file, -4) == '.' . $ext && file_exists($stub . '/' . $module_path . '/' . $file) && preg_match('#^[\\w\\-\\.]*$#', substr($file, 0, strlen($file) - 4)) != 0) {
                if (!is_null($cutoff_time)) {
                    if (filectime($stub . '/' . $module_path . '/' . $file) < $cutoff_time) {
                        continue;
                    }
                }
                if ($ext == 'txt') {
                    switch ($show_method) {
                        case FIND_ALL_PAGES__NEWEST:
                            // Only gets newest if it's a large site
                            if (count($out) > 300) {
                                $out = array();
                                $records = $GLOBALS['SITE_DB']->query_select('comcode_pages', array('the_page'), array('the_zone' => $zone), 'ORDER BY p_add_date DESC', 300);
                                foreach ($records as $record) {
                                    $file = $record['the_page'] . '.txt';
                                    if (!file_exists($stub . '/' . $module_path . '/' . $file)) {
                                        continue;
                                    }
                                    if (!is_null($cutoff_time)) {
                                        if (filectime($stub . '/' . $module_path . '/' . $file) < $cutoff_time) {
                                            continue;
                                        }
                                    }
                                    $out[$keep_ext_on ? $file : substr($file, 0, strlen($file) - 4)] = $type;
                                }
                            } else {
                                break;
                            }
                            //break; Actually, no, let it roll on to the next one to get key files too
                        //break; Actually, no, let it roll on to the next one to get key files too
                        case FIND_ALL_PAGES__PERFORMANT:
                            // Default, chooses selection carefully based on site size
                            if ($show_method == FIND_ALL_PAGES__NEWEST || count($out) > 300) {
                                if ($show_method != FIND_ALL_PAGES__NEWEST) {
                                    $out = array();
                                }
                                $records = $GLOBALS['SITE_DB']->query('SELECT the_page FROM ' . get_table_prefix() . 'comcode_pages WHERE ' . db_string_equal_to('the_zone', $zone) . ' AND (' . db_string_equal_to('the_page', get_zone_default_page($zone)) . ' OR the_page LIKE \'' . db_encode_like('panel\\_%') . '\') ORDER BY p_add_date DESC');
                                foreach ($records as $record) {
                                    $file = $record['the_page'] . '.txt';
                                    if (!file_exists($stub . '/' . $module_path . '/' . $file)) {
                                        continue;
                                    }
                                    if (!is_null($cutoff_time)) {
                                        if (filectime($stub . '/' . $module_path . '/' . $file) < $cutoff_time) {
                                            continue;
                                        }
                                    }
                                    $out[$keep_ext_on ? $file : substr($file, 0, strlen($file) - 4)] = $type;
                                }
                                break 2;
                            }
                            break;
                        case FIND_ALL_PAGES__ALL:
                            // Nothing special
                            break;
                    }
                }
                $out[$keep_ext_on ? $file : substr($file, 0, strlen($file) - 4)] = $type;
            }
        }
        closedir($dh);
    }
    if ($zone == '' && get_option('collapse_user_zones', true) === '1') {
        $out += _find_all_pages('site', $type, $ext, $keep_ext_on);
    }
    ksort($out);
    return $out;
}