From 30dc89278674b8bc83b4e44db920a1c7654c7cdd Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Fri, 19 Jul 2013 18:36:12 -0400 Subject: Only store video URLs in database, instead of the generated player HTML. --- inc/display.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'inc') diff --git a/inc/display.php b/inc/display.php index 2021dc8f..a7e4826e 100644 --- a/inc/display.php +++ b/inc/display.php @@ -241,6 +241,29 @@ function secure_link($href) { return $href . '/' . make_secure_link_token($href); } +function embed_html($link) { + global $config; + + foreach ($config['embedding'] as $embed) { + if ($html = preg_replace($embed[0], $embed[1], $link)) { + if ($html == $link) + continue; // Nope + + $html = str_replace('%%tb_width%%', $config['embed_width'], $html); + $html = str_replace('%%tb_height%%', $config['embed_height'], $html); + + return $html; + } + } + + if ($link[0] == '<') { + // Prior to v0.9.6-dev-8, HTML code for embedding was stored in the database instead of the link. + return $link; + } + + return 'Embedding error.'; +} + class Post { public function __construct($id, $thread, $subject, $email, $name, $trip, $capcode, $body, $time, $thumb, $thumbx, $thumby, $file, $filex, $filey, $filesize, $filename, $ip, $embed, $root=null, $mod=false) { global $config; @@ -269,6 +292,9 @@ class Post { $this->root = $root; $this->mod = $mod; + if ($this->embed) + $this->embed = embed_html($this->embed); + if ($this->mod) // Fix internal links // Very complicated regex @@ -365,6 +391,9 @@ class Thread { $this->mod = $mod; $this->hr = $hr; + if ($this->embed) + $this->embed = embed_html($this->embed); + if ($this->mod) // Fix internal links // Very complicated regex -- cgit v1.3 From e62b83e79c8ed3b9ddf6e7e4b8bdeedc0d319ff4 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 20 Jul 2013 07:50:33 -0400 Subject: Bring back search (searching posts not implemented yet) --- inc/config.php | 2 +- inc/mod/pages.php | 106 +++++++++++++++++++++++++++++++ mod.php | 3 + templates/mod/dashboard.html | 11 +--- templates/mod/search_form.html | 15 +++++ templates/mod/search_results.html | 129 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 257 insertions(+), 9 deletions(-) create mode 100644 templates/mod/search_form.html create mode 100644 templates/mod/search_results.html (limited to 'inc') diff --git a/inc/config.php b/inc/config.php index b7f6d220..9706178c 100644 --- a/inc/config.php +++ b/inc/config.php @@ -1015,7 +1015,7 @@ $config['mod']['master_pm'] = ADMIN; // Rebuild everything $config['mod']['rebuild'] = ADMIN; - // Search through posts + // Search through posts, IP address notes and bans $config['mod']['search'] = JANITOR; // Read the moderator noticeboard $config['mod']['noticeboard'] = JANITOR; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 3f823d3d..fc5577bc 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -162,6 +162,112 @@ function mod_dashboard() { mod_page(_('Dashboard'), 'mod/dashboard.html', $args); } +function mod_search_redirect() { + global $config; + + if (!hasPermission($config['mod']['search'])) + error($config['error']['noaccess']); + + if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans'))) { + $query = $_POST['query']; + $query = urlencode($query); + $query = str_replace('_', '%5F', $query); + $query = str_replace('+', '_', $query); + + header('Location: ?/search/' . $_POST['type'] . '/' . $query, true, $config['redirect_http']); + } else { + header('Location: ?/', true, $config['redirect_http']); + } +} + +function mod_search($type, $query) { + global $pdo, $config; + + if (!hasPermission($config['mod']['search'])) + error($config['error']['noaccess']); + + // Unescape query + $query = str_replace('_', ' ', $query); + $query = urldecode($query); + $search_query = $query; + + // Form a series of LIKE clauses for the query. + // This gets a little complicated. + + // Escape "escape" character + $query = str_replace('!', '!!', $query); + + // Escape SQL wildcard + $query = str_replace('%', '!%', $query); + + // Use asterisk as wildcard instead + $query = str_replace('*', '%', $query); + + // Array of phrases to match + $match = array(); + + // Exact phrases ("like this") + if (preg_match_all('/"(.+?)"/', $query, $matches)) { + foreach ($matches[1] as $phrase) { + $query = str_replace("\"{$phrase}\"", '', $query); + $match[] = $pdo->quote($phrase); + } + } + + // Non-exact phrases (ie. plain keywords) + $keywords = explode(' ', $query); + foreach ($keywords as $word) { + if (empty($word)) + continue; + $match[] = $pdo->quote($word); + } + + // Which `field` to search? + if ($type == 'posts') + $sql_field = 'body'; + if ($type == 'IP_notes') + $sql_field = 'body'; + if ($type == 'bans') + $sql_field = 'reason'; + + // Build the "LIKE 'this' AND LIKE 'that'" etc. part of the SQL query + $sql_like = ''; + foreach ($match as $phrase) { + if (!empty($sql_like)) + $sql_like .= ' AND '; + $phrase = preg_replace('/^\'(.+)\'$/', '\'%$1%\'', $phrase); + $sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\''; + } + + if ($type == 'posts') { + error('Searching posts is under development. Sorry.'); + } + + if ($type == 'IP_notes') { + $query = query('SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC') or error(db_error()); + $results = $query->fetchAll(PDO::FETCH_ASSOC); + } + + if ($type == 'bans') { + $query = query('SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set`') or error(db_error()); + $results = $query->fetchAll(PDO::FETCH_ASSOC); + + foreach ($results as &$ban) { + if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false) + $ban['real_ip'] = true; + } + } + + // $results now contains the search results + + mod_page(_('Search results'), 'mod/search_results.html', array( + 'search_type' => $type, + 'search_query' => $search_query, + 'result_count' => count($results), + 'results' => $results + )); +} + function mod_edit_board($boardName) { global $board, $config; diff --git a/mod.php b/mod.php index 42196ef2..2523658c 100644 --- a/mod.php +++ b/mod.php @@ -56,6 +56,9 @@ $pages = array( '/IP/([\w.:]+)/remove_note/(\d+)' => 'ip_remove_note', // remove note from ip address '/bans' => 'bans', // ban list '/bans/(\d+)' => 'bans', // ban list + + '/search' => 'search_redirect', // search + '/search/(posts|IP_notes|bans)/(.+)' => 'search', // search // CSRF-protected moderator actions '/ban' => 'secure_POST ban', // new ban diff --git a/templates/mod/dashboard.html b/templates/mod/dashboard.html index e54b3cd3..619663f5 100644 --- a/templates/mod/dashboard.html +++ b/templates/mod/dashboard.html @@ -101,22 +101,17 @@ -{# +{% if mod|hasPermission(config.mod.search) %}
{% trans 'Search' %}
  • -
    - - - -
    -

    {% trans '(Search is case-insensitive, and based on keywords. To match exact phrases, use "quotes". Use an asterisk (*) for wildcard.)' %}

    + {% include 'mod/search_form.html' %}
-#} +{% endif %} {% if config.debug %}
diff --git a/templates/mod/search_form.html b/templates/mod/search_form.html new file mode 100644 index 00000000..c74121fd --- /dev/null +++ b/templates/mod/search_form.html @@ -0,0 +1,15 @@ +
+ + + + +
+

{% trans '(Search is case-insensitive and based on keywords. To match exact phrases, use "quotes". Use an asterisk (*) for wildcard.)' %}

\ No newline at end of file diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html new file mode 100644 index 00000000..84de8969 --- /dev/null +++ b/templates/mod/search_results.html @@ -0,0 +1,129 @@ +
+ {% trans 'Search' %} + +
    +
  • + {% include 'mod/search_form.html' %} +
  • +
+
+ +

Showing {{ result_count }} result{% if result_count != 1 %}s{% endif %}.

+ +{% if search_type == 'IP_notes' %} + + + + + + + + {% for note in results %} + + + + + + + {% endfor %} +
{% trans 'IP address' %}{% trans 'Staff' %}{% trans 'Note' %}{% trans 'Date' %}
+ {{ note.ip }} + + {% if note.username %} + {{ note.username|e }} + {% else %} + {% trans 'deleted?' %} + {% endif %} + + {{ note.body }} + + {{ note.time|date(config.post_date) }} +
+{% endif %} + + +{% if search_type == 'bans' %} + + + + + + + + + + + + {% for ban in results %} + + + + + + + + + + + {% endfor %} +
{% trans 'IP address/mask' %}{% trans 'Reason' %}{% trans 'Board' %}{% trans 'Set' %}{% trans 'Duration' %}{% trans 'Expires' %}{% trans 'Seen' %}{% trans 'Staff' %}
+ {% if ban.real_ip %} + {{ ban.ip }} + {% else %} + {{ ban.ip|e }} + {% endif %} + + {% if ban.reason %} + {{ ban.reason }} + {% else %} + - + {% endif %} + + {% if ban.board %} + {{ config.board_abbreviation|sprintf(ban.board) }} + {% else %} + {% trans 'all boards' %} + {% endif %} + + + {{ ban.set|ago }} ago + + + {% if ban.expires == 0 %} + - + {% else %} + {{ (ban.expires - ban.set + time()) | until }} + {% endif %} + + {% if ban.expires == 0 %} + {% trans 'never' %} + {% else %} + {{ ban.expires|date(config.post_date) }} + {% if ban.expires > time() %} + (in {{ ban.expires|until }}) + {% endif %} + {% endif %} + + {% if ban.seen %} + {% trans 'Yes' %} + {% else %} + {% trans 'No' %} + {% endif %} + + {% if ban.username %} + {% if mod|hasPermission(config.mod.view_banstaff) %} + {{ ban.username|e }} + {% else %} + {% if mod|hasPermission(config.mod.view_banquestionmark) %} + ? + {% else %} + + {% endif %} + {% endif %} + {% elseif ban.mod == -1 %} + system + {% else %} + {% trans 'deleted?' %} + {% endif %} +
+{% endif %} \ No newline at end of file -- cgit v1.3 From b776e0a7f005846d80716febc12f8cdf40d1d149 Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 20 Jul 2013 12:05:42 -0400 Subject: Search update --- inc/config.php | 4 +-- inc/mod/pages.php | 44 ++++++++++++++++++++++++--------- mod.php | 3 ++- templates/mod/search_form.html | 9 ++++--- templates/mod/search_results.html | 52 +++++++++++++++++++++++++++++++++++++-- 5 files changed, 93 insertions(+), 19 deletions(-) (limited to 'inc') diff --git a/inc/config.php b/inc/config.php index 9706178c..424d07d6 100644 --- a/inc/config.php +++ b/inc/config.php @@ -857,8 +857,8 @@ // Number of news entries to display per page $config['mod']['news_page'] = 40; - // Maximum number of results to display for a search, per board - $config['mod']['search_results'] = 75; + // Number of results to dispaly per page + $config['mod']['search_page'] = 200; // How many entries to show per page in the moderator noticeboard $config['mod']['noticeboard_page'] = 50; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index fc5577bc..79d87ba1 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -168,7 +168,7 @@ function mod_search_redirect() { if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); - if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans'))) { + if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans', 'log'))) { $query = $_POST['query']; $query = urlencode($query); $query = str_replace('_', '%5F', $query); @@ -180,14 +180,14 @@ function mod_search_redirect() { } } -function mod_search($type, $query) { +function mod_search($type, $search_query_escaped, $page_no = 1) { global $pdo, $config; if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); // Unescape query - $query = str_replace('_', ' ', $query); + $query = str_replace('_', ' ', $search_query_escaped); $query = urldecode($query); $search_query = $query; @@ -207,8 +207,9 @@ function mod_search($type, $query) { $match = array(); // Exact phrases ("like this") - if (preg_match_all('/"(.+?)"/', $query, $matches)) { - foreach ($matches[1] as $phrase) { + if (preg_match_all('/"(.+?)"/', $query, $exact_phrases)) { + $exact_phrases = $exact_phrases[1]; + foreach ($exact_phrases as $phrase) { $query = str_replace("\"{$phrase}\"", '', $query); $match[] = $pdo->quote($phrase); } @@ -229,6 +230,8 @@ function mod_search($type, $query) { $sql_field = 'body'; if ($type == 'bans') $sql_field = 'reason'; + if ($type == 'log') + $sql_field = 'text'; // Build the "LIKE 'this' AND LIKE 'that'" etc. part of the SQL query $sql_like = ''; @@ -239,19 +242,37 @@ function mod_search($type, $query) { $sql_like .= '`' . $sql_field . '` LIKE ' . $phrase . ' ESCAPE \'!\''; } + + // Compile SQL query + if ($type == 'posts') { error('Searching posts is under development. Sorry.'); } if ($type == 'IP_notes') { - $query = query('SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC') or error(db_error()); - $results = $query->fetchAll(PDO::FETCH_ASSOC); + $query = 'SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; + $sql_table = 'ip_notes'; } if ($type == 'bans') { - $query = query('SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set`') or error(db_error()); - $results = $query->fetchAll(PDO::FETCH_ASSOC); + $query = 'SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set` DESC'; + $sql_table = 'bans'; + } + + if ($type == 'log') { + $query = 'SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; + $sql_table = 'modlogs'; + } + // Execute SQL query (with pages) + $q = query($query . ' LIMIT ' . (($page_no - 1) * $config['mod']['search_page']) . ', ' . $config['mod']['search_page']) or error(db_error()); + $results = $q->fetchAll(PDO::FETCH_ASSOC); + + // Get total result count + $q = query('SELECT COUNT(*) FROM `' . $sql_table . '` WHERE ' . $sql_like) or error(db_error()); + $result_count = $q->fetchColumn(); + + if ($type == 'bans') { foreach ($results as &$ban) { if (filter_var($ban['ip'], FILTER_VALIDATE_IP) !== false) $ban['real_ip'] = true; @@ -259,11 +280,12 @@ function mod_search($type, $query) { } // $results now contains the search results - + mod_page(_('Search results'), 'mod/search_results.html', array( 'search_type' => $type, 'search_query' => $search_query, - 'result_count' => count($results), + 'search_query_escaped' => $search_query_escaped, + 'result_count' => $result_count, 'results' => $results )); } diff --git a/mod.php b/mod.php index 2523658c..4c26b559 100644 --- a/mod.php +++ b/mod.php @@ -58,7 +58,8 @@ $pages = array( '/bans/(\d+)' => 'bans', // ban list '/search' => 'search_redirect', // search - '/search/(posts|IP_notes|bans)/(.+)' => 'search', // search + '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search + '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search // CSRF-protected moderator actions '/ban' => 'secure_POST ban', // new ban diff --git a/templates/mod/search_form.html b/templates/mod/search_form.html index c74121fd..d8a2fed4 100644 --- a/templates/mod/search_form.html +++ b/templates/mod/search_form.html @@ -2,12 +2,15 @@ diff --git a/templates/mod/search_results.html b/templates/mod/search_results.html index 84de8969..b441a28f 100644 --- a/templates/mod/search_results.html +++ b/templates/mod/search_results.html @@ -41,7 +41,6 @@ {% endif %} - {% if search_type == 'bans' %} @@ -126,4 +125,53 @@ {% endfor %}
-{% endif %} \ No newline at end of file +{% endif %} + +{% if search_type == 'log' %} + + + + + + + + + {% for log in results %} + + + + + + + + {% endfor %} +
{% trans 'Staff' %}{% trans 'IP address' %}{% trans 'Time' %}{% trans 'Board' %}{% trans 'Action' %}
+ {% if log.username %} + {{ log.username|e }} + {% elseif log.mod == -1 %} + system + {% else %} + {% trans 'deleted?' %} + {% endif %} + + {{ log.ip }} + + {{ log.time|ago }} + + {% if log.board %} + {{ config.board_abbreviation|sprintf(log.board) }} + {% else %} + - + {% endif %} + + {{ log.text }} +
+{% endif %} + +{% if result_count > results|count %} +

+ {% for i in range(0, (result_count - 1) / config.mod.search_page) %} + [{{ i + 1 }}] + {% endfor %} +

+{% endif %} \ No newline at end of file -- cgit v1.3 From 67cbc2b1aaf285c604c618de646d6d6e1e930b7a Mon Sep 17 00:00:00 2001 From: Michael Foster Date: Sat, 20 Jul 2013 13:15:44 -0400 Subject: Fix permissions with search --- inc/mod/pages.php | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'inc') diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 79d87ba1..cddecad0 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -252,16 +252,22 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { if ($type == 'IP_notes') { $query = 'SELECT * FROM `ip_notes` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; $sql_table = 'ip_notes'; + if (!hasPermission($config['mod']['view_notes']) || !hasPermission($config['mod']['show_ip'])) + error($config['error']['noaccess']); } if ($type == 'bans') { $query = 'SELECT `bans`.*, `username` FROM `bans` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY (`expires` IS NOT NULL AND `expires` < UNIX_TIMESTAMP()), `set` DESC'; $sql_table = 'bans'; + if (!hasPermission($config['mod']['view_banlist'])) + error($config['error']['noaccess']); } if ($type == 'log') { $query = 'SELECT `username`, `mod`, `ip`, `board`, `time`, `text` FROM `modlogs` LEFT JOIN `mods` ON `mod` = `mods`.`id` WHERE ' . $sql_like . ' ORDER BY `time` DESC'; $sql_table = 'modlogs'; + if (!hasPermission($config['mod']['modlog'])) + error($config['error']['noaccess']); } // Execute SQL query (with pages) -- cgit v1.3