Ejemplo n.º 1
0
function updateStatisticsForPost($post, $new = true)
{
    $postIp = isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR'];
    $postUri = $post['board'];
    $postTime = (int) ($post['time'] / 3600) * 3600;
    $bsQuery = prepare("SELECT * FROM ``board_stats`` WHERE `stat_uri` = :uri AND `stat_hour` = :hour");
    $bsQuery->bindValue(':uri', $postUri);
    $bsQuery->bindValue(':hour', $postTime, PDO::PARAM_INT);
    $bsQuery->execute() or error(db_error($bsQuery));
    $bsResult = $bsQuery->fetchAll(PDO::FETCH_ASSOC);
    // Flesh out the new stats row.
    $boardStats = array();
    // If we already have a row, we're going to be adding this post to it.
    if (count($bsResult)) {
        $boardStats = $bsResult[0];
        $boardStats['stat_uri'] = $postUri;
        $boardStats['stat_hour'] = $postTime;
        $boardStats['post_id_array'] = unserialize($boardStats['post_id_array']);
        $boardStats['author_ip_array'] = unserialize($boardStats['author_ip_array']);
        ++$boardStats['post_count'];
        $boardStats['post_id_array'][] = (int) $post['id'];
        $boardStats['author_ip_array'][] = less_ip($postIp);
        $boardStats['author_ip_array'] = array_unique($boardStats['author_ip_array']);
    } else {
        $boardStats['stat_uri'] = $postUri;
        $boardStats['stat_hour'] = $postTime;
        $boardStats['post_count'] = 1;
        $boardStats['post_id_array'] = array((int) $post['id']);
        $boardStats['author_ip_count'] = 1;
        $boardStats['author_ip_array'] = array(less_ip($postIp));
    }
    // Cleanly serialize our array for insertion.
    $boardStats['post_id_array'] = str_replace("\"", "\\\"", serialize($boardStats['post_id_array']));
    $boardStats['author_ip_array'] = str_replace("\"", "\\\"", serialize($boardStats['author_ip_array']));
    // Insert this data into our statistics table.
    $statsInsert = "VALUES(\"{$boardStats['stat_uri']}\", \"{$boardStats['stat_hour']}\", \"{$boardStats['post_count']}\", \"{$boardStats['post_id_array']}\", \"{$boardStats['author_ip_count']}\", \"{$boardStats['author_ip_array']}\" )";
    $postStatQuery = prepare("REPLACE INTO ``board_stats`` (stat_uri, stat_hour, post_count, post_id_array, author_ip_count, author_ip_array) {$statsInsert}");
    $postStatQuery->execute() or error(db_error($postStatQuery));
    // Update the posts_total tracker on the board.
    if ($new) {
        query("UPDATE ``boards`` SET `posts_total`=`posts_total`+1 WHERE `uri`=\"{$postUri}\"");
    }
    return $boardStats;
}
Ejemplo n.º 2
0
function twig_less_ip($ip, $board = '')
{
    return less_ip($ip, $board);
}
Ejemplo n.º 3
0
 public static function stream_json($out = false, $filter_ips = false, $filter_staff = false, $board_access = false)
 {
     global $config, $pdo;
     if ($board_access && $board_access[0] == '*') {
         $board_access = false;
     }
     $query_addition = "";
     if ($board_access) {
         $boards = implode(", ", array_map(array($pdo, "quote"), $board_access));
         $query_addition .= "WHERE `board` IN (" . $boards . ")";
     }
     if ($board_access !== FALSE) {
         if (!$query_addition) {
             $query_addition .= " WHERE (`public_bans` IS TRUE) OR ``bans``.`board` IS NULL";
         }
     }
     $query = query("SELECT ``bans``.*, `username`, `type` FROM ``bans``\n\t\t\tLEFT JOIN ``mods`` ON ``mods``.`id` = `creator`\n\t\t\tLEFT JOIN ``boards`` ON ``boards``.`uri` = ``bans``.`board`\n\t\t\t\t{$query_addition}\n \t\t\tORDER BY `created` DESC") or error(db_error());
     $bans = $query->fetchAll(PDO::FETCH_ASSOC);
     $out ? fputs($out, "[") : (print "[");
     $end = end($bans);
     foreach ($bans as &$ban) {
         $ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend']));
         if ($ban['post']) {
             $post = json_decode($ban['post']);
             if ($post) {
                 $ban['message'] = $post->body;
             }
         }
         unset($ban['ipstart'], $ban['ipend'], $ban['post'], $ban['creator']);
         if ($board_access === false || in_array($ban['board'], $board_access)) {
             $ban['access'] = true;
         }
         if (filter_var($ban['mask'], FILTER_VALIDATE_IP) !== false) {
             $ban['single_addr'] = true;
         }
         if ($filter_staff || $board_access !== false && !in_array($ban['board'], $board_access)) {
             switch ($ban['type']) {
                 case ADMIN:
                     $ban['username'] = '******';
                     break;
                 case GLOBALVOLUNTEER:
                     $ban['username'] = '******';
                     break;
                 case MOD:
                     $ban['username'] = '******';
                     break;
                 case BOARDVOLUNTEER:
                     $ban['username'] = '******';
                     break;
                 default:
                     $ban['username'] = '******';
             }
             $ban['vstaff'] = true;
         }
         unset($ban['type']);
         if ($filter_ips || $board_access !== false && !in_array($ban['board'], $board_access)) {
             $ban['mask'] = @less_ip($ban['mask'], $ban['board']);
             $ban['masked'] = true;
         }
         $json = json_encode($ban);
         $out ? fputs($out, $json) : (print $json);
         if ($ban['id'] != $end['id']) {
             $out ? fputs($out, ",") : (print ",");
         }
     }
     $out ? fputs($out, "]") : (print "]");
 }
Ejemplo n.º 4
0
function mod_reports()
{
    global $config, $mod;
    // Parse arguments.
    $urlArgs = func_get_args();
    $global = in_array("global", $urlArgs);
    $json = in_array("json", $urlArgs);
    if (!hasPermission($config['mod']['reports'])) {
        error($config['error']['noaccess']);
    }
    if ($mod['type'] < GLOBALVOLUNTEER and $global) {
        error($config['error']['noaccess']);
    }
    // Limit reports to ONLY those in our scope.
    $report_scope = $global ? "global" : "local";
    // Get REPORTS.
    $query = prepare("SELECT * FROM ``reports`` WHERE " . ($mod["type"] < GLOBALVOLUNTEER ? "board = :board AND" : "") . " ``" . ($global ? "global" : "local") . "`` = TRUE  LIMIT :limit");
    // Limit reports by board if the moderator is local.
    if ($mod['type'] < GLOBALVOLUNTEER) {
        $query->bindValue(':board', $mod['boards'][0]);
    }
    // Limit by config ceiling.
    $query->bindValue(':limit', $config['mod']['recent_reports'], PDO::PARAM_INT);
    $query->execute() or error(db_error($query));
    $reports = $query->fetchAll(PDO::FETCH_ASSOC);
    // Cut off here if we don't have any reports.
    $reportCount = 0;
    $reportHTML = '';
    if (count($reports) > 0) {
        // Build queries to fetch content.
        $report_queries = array();
        foreach ($reports as $report) {
            if (!isset($report_queries[$report['board']])) {
                $report_queries[$report['board']] = array();
            }
            $report_queries[$report['board']][] = $report['post'];
        }
        // Get reported CONTENT.
        $report_posts = array();
        foreach ($report_queries as $board => $posts) {
            $report_posts[$board] = array();
            $query = query(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error());
            while ($post = $query->fetch(PDO::FETCH_ASSOC)) {
                $report_posts[$board][$post['id']] = $post;
            }
        }
        // Develop an associative array of posts to reports.
        $report_index = array();
        foreach ($reports as &$report) {
            // Delete reports which are for removed content.
            if (!isset($report_posts[$report['board']][$report['post']])) {
                // Invalid report (post has since been deleted)
                $query = prepare("DELETE FROM ``reports`` WHERE `post` = :id AND `board` = :board");
                $query->bindValue(':id', $report['post'], PDO::PARAM_INT);
                $query->bindValue(':board', $report['board']);
                $query->execute() or error(db_error($query));
                continue;
            }
            // Build a unique ID.
            $content_key = "{$report['board']}.{$report['post']}";
            // Create a dummy array if it doesn't already exist.
            if (!isset($report_index[$content_key])) {
                $report_index[$content_key] = array("board_id" => $report['board'], "post_id" => $report['post'], "content" => $report_posts[$report['board']][$report['post']], "reports" => array());
            }
            // Add the report to the list of reports.
            $report_index[$content_key]['reports'][$report['id']] = $report;
            // Increment the total report count.
            ++$reportCount;
        }
        // Only continue if we have something to do.
        // If there are no valid reports left, we're done.
        if ($reportCount > 0 && !$json) {
            // Sort this report index by number of reports, desc.
            usort($report_index, function ($a, $b) {
                $ra = count($a['reports']);
                $rb = count($b['reports']);
                if ($ra < $rb) {
                    return 1;
                } else {
                    if ($rb > $ra) {
                        return -1;
                    } else {
                        return 0;
                    }
                }
            });
            // Loop through the custom index.
            foreach ($report_index as &$report_item) {
                $content = $report_item['content'];
                // Load board content.
                openBoard($report_item['board_id']);
                // Load the reported content.
                if (!$content['thread']) {
                    // Still need to fix this:
                    $po = new Thread($content, '?/', $mod, false);
                } else {
                    $po = new Post($content, '?/', $mod);
                }
                // Fetch clean status.
                $po->getClean(true);
                $clean = $po->clean;
                // Add each report's template to this container.
                $report_html = "";
                $reports_can_demote = false;
                $reports_can_promote = false;
                $content_reports = 0;
                foreach ($report_item['reports'] as $report) {
                    $uri_report_base = "reports/" . ($global ? "global/" : "") . $report['id'];
                    $report_html .= Element('mod/report.html', array('report' => $report, 'config' => $config, 'mod' => $mod, 'global' => $global, 'clean' => $clean, 'uri_dismiss' => "?/{$uri_report_base}/dismiss", 'uri_ip' => "?/{$uri_report_base}/dismissall", 'uri_demote' => "?/{$uri_report_base}/demote", 'uri_promote' => "?/{$uri_report_base}/promote", 'token_dismiss' => make_secure_link_token($uri_report_base . '/dismiss'), 'token_ip' => make_secure_link_token($uri_report_base . '/dismissall'), 'token_demote' => make_secure_link_token($uri_report_base . '/demote'), 'token_promote' => make_secure_link_token($uri_report_base . '/promote')));
                    // Determines if we can "Demote All" / "Promote All"
                    // This logic only needs one instance of a demotable or promotable report to work.
                    // DEMOTE can occur when we're global and the report has a 1 for local (meaning locally, it's not dismissed)
                    // PROMOTE can occur when we're local and the report has a 0 for global (meaning it's not global).
                    if ($global && $report['local'] == "1") {
                        $reports_can_demote = true;
                    } else {
                        if (!$global && $report['global'] != "1") {
                            $reports_can_promote = true;
                        }
                    }
                    ++$content_reports;
                }
                // Build the ">>>/b/ thread reported 3 times" title.
                $report_title = sprintf(_('<a href="%s" title="View content" target="_new">&gt;&gt;&gt;/%s/</a> %s reported %d time(s).'), "?/{$report_item['board_id']}/res/" . ($content['thread'] ?: $content['id']) . ".html#{$content['thread']}", $report_item['board_id'], _($content['thread'] ? "reply" : "thread"), $content_reports);
                // Figure out some stuff we need for the page.
                $reports_can_demote = $clean['clean_local'] ? false : $reports_can_demote;
                $reports_can_promote = $clean['clean_global'] ? false : $reports_can_promote;
                $uri_content_base = "reports/" . ($global ? "global/" : "") . "content/";
                $uri_clean_base = "reports/" . ($global ? "global/" : "") . "{$report_item['board_id']}/clean/{$content['id']}";
                // Build the actions page.
                $content_html = Element('mod/report_content.html', array('reports_html' => $report_html, 'reports_can_demote' => $reports_can_demote, 'reports_can_promote' => $reports_can_promote, 'report_count' => $content_reports, 'report_title' => $report_title, 'content_html' => $po->build(true), 'content_board' => $report_item['board_id'], 'content' => (array) $content, 'clean' => $clean, 'uri_content_demote' => "?/{$uri_content_base}{$report_item['board_id']}/{$content['id']}/demote", 'uri_content_promote' => "?/{$uri_content_base}{$report_item['board_id']}/{$content['id']}/promote", 'uri_content_dismiss' => "?/{$uri_content_base}{$report_item['board_id']}/{$content['id']}/dismiss", 'token_content_demote' => make_secure_link_token("{$uri_content_base}{$report_item['board_id']}/{$content['id']}/demote"), 'token_content_promote' => make_secure_link_token("{$uri_content_base}{$report_item['board_id']}/{$content['id']}/promote"), 'token_content_dismiss' => make_secure_link_token("{$uri_content_base}{$report_item['board_id']}/{$content['id']}/dismiss"), 'uri_clean' => "?/{$uri_clean_base}/local", 'uri_clean_global' => "?/{$uri_clean_base}/global", 'uri_clean_both' => "?/{$uri_clean_base}/global+local", 'token_clean' => make_secure_link_token($uri_clean_base . '/local'), 'token_clean_global' => make_secure_link_token($uri_clean_base . '/global'), 'token_clean_both' => make_secure_link_token($uri_clean_base . '/global+local'), 'global' => $global, 'config' => $config, 'mod' => $mod));
                $reportHTML .= $content_html;
            }
        }
        if ($reportCount > 0 && $json) {
            array_walk($reports, function (&$v, $k, $ud) {
                $global = $ud['global'];
                $report_posts = $ud['report_posts'];
                $board = $v['board'] ? $v['board'] : NULL;
                if (isset($v['ip']) && !$global) {
                    $v['ip'] = less_ip($v['ip'], $board ? $board : '');
                }
                if (isset($report_posts[$v['board']][$v['post']])) {
                    $post_content = $report_posts[$v['board']][$v['post']];
                    unset($post_content['password']);
                    if (!$global) {
                        $post_content['ip'] = less_ip($post_content['ip'], $board ? $board : '');
                    }
                    $v['post_content'] = $post_content;
                }
            }, array('global' => $global, 'report_posts' => $report_posts));
        }
    }
    $pageArgs = array('count' => $reportCount, 'reports' => $reportHTML, 'global' => $global);
    if ($json) {
        header('Content-Type: application/json');
        echo json_encode($reports);
    } else {
        mod_page(sprintf('%s (%d)', _($global ? 'Global report queue' : 'Report queue'), $reportCount), 'mod/reports.html', $pageArgs);
    }
}
Ejemplo n.º 5
0
     if (!isset($postDatum['post_count'])) {
         $postDatum['post_count'] = 1;
     } else {
         ++$postDatum['post_count'];
     }
     // Add to post id array.
     if (!isset($postDatum['post_id_array'])) {
         $postDatum['post_id_array'] = array((int) $post['id']);
     } else {
         $postDatum['post_id_array'][] = (int) $post['id'];
     }
     // Add to ip array.
     if (!isset($postDatum['author_ip_array'])) {
         $postDatum['author_ip_array'] = array();
     }
     $postDatum['author_ip_array'][less_ip($post['ip'])] = 1;
     unset($postHourTime);
 }
 // Prep data for insert.
 foreach ($postHour as $postHourTime => &$postHourData) {
     $postDatum =& $postHour[$postHourTime];
     // Serialize arrays for TEXT insert.
     $postDatum['post_id_array'] = str_replace("\"", "\\\"", serialize($postDatum['post_id_array']));
     $postDatum['author_ip_count'] = count(array_keys($postDatum['author_ip_array']));
     $postDatum['author_ip_array'] = str_replace("\"", "\\\"", serialize(array_keys($postDatum['author_ip_array'])));
 }
 // Bash this shit together into a set of insert statements.
 $statsInserts = array();
 foreach ($postHour as $postHourTime => $postHourData) {
     $statsInserts[] = "(\"{$board['uri']}\", \"{$postHourTime}\", \"{$postHourData['post_count']}\", \"{$postHourData['post_id_array']}\", \"{$postHourData['author_ip_count']}\", \"{$postHourData['author_ip_array']}\" )";
 }