From ec90c96459792bb41aaecb8ce7a1aeaa91612d0d Mon Sep 17 00:00:00 2001 From: 8n-tech <8n-tech@users.noreply.github.com> Date: Thu, 16 Apr 2015 05:46:48 +1000 Subject: [PATCH] - board-search.php Now properly calculates tag weight. - boards.php Passes $search parameters into Twig. - js/board-reictory.js Stores last search parameters and handles tag click events. - Twig now passes old search parameters into the search form. - Tags now link in such a way that they will preserve form data and other tags when clicked in a browser without JavaScript. Signed-off-by: 8n-tech <8n-tech@users.noreply.github.com> --- board-search.php | 56 ++++++++++++++++-- boards.php | 23 ++++++-- js/board-directory.js | 93 ++++++++++++++++++++---------- templates/8chan/boards-search.html | 8 +-- templates/8chan/boards-table.html | 2 +- templates/8chan/boards-tags.html | 2 +- 6 files changed, 139 insertions(+), 45 deletions(-) diff --git a/board-search.php b/board-search.php index f6d08766..7e088c05 100644 --- a/board-search.php +++ b/board-search.php @@ -25,6 +25,7 @@ $languages = array( $search = array( 'lang' => false, 'nsfw' => true, + 'page' => 0, 'tags' => false, 'time' => ( (int)( time() / 3600 ) * 3600 ) - 3600, 'title' => false, @@ -37,6 +38,15 @@ if (isset( $_GET['sfw'] ) && $_GET['sfw'] != "") { $search['nsfw'] = !$_GET['sfw']; } +// Bringing up more results +if (isset( $_GET['page'] ) && $_GET['page'] != "") { + $search['page'] = (int) $_GET['page']; + + if ($search['page'] < 0) { + $search['page'] = 0; + } +} + // Include what language (if the language is not blank and we recognize it)? if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['lang']])) { $search['lang'] = $_GET['lang']; @@ -44,7 +54,8 @@ if (isset( $_GET['lang'] ) && $_GET['lang'] != "" && isset($languages[$search['l // Include what tag? if (isset( $_GET['tags'] ) && $_GET['tags'] != "") { - $search['tags'] = $_GET['tags']; + $search['tags'] = explode( " ", $_GET['tags'] ); + $search['tags'] = array_splice( $search['tags'], 0, 5 ); } // What time range? @@ -73,6 +84,31 @@ foreach ($boards as $board) { continue; } + // Are we searching by title? + if ($search['title'] !== false) { + // This checks each component of the board's identity against our search terms. + // The weight determines order. + // "left" would match /leftypol/ and /nkvd/ which has /leftypol/ in the title. + // /leftypol/ would always appear above it but it would match both. + if (strpos("/{$board['uri']}/", $search['title']) !== false) { + $board['weight'] = 30; + } + else if (strpos($board['title'], $search['title']) !== false) { + $board['weight'] = 20; + } + else if (strpos($board['subtitle'], $search['title']) !== false) { + $board['weight'] = 10; + } + else { + continue; + } + + unset( $boardTitleString ); + } + else { + $board['weight'] = 0; + } + // Load board config. $boardConfig = loadBoardConfig( $board['uri'] ); @@ -101,7 +137,7 @@ $boardTags = fetchBoardTags( array_keys( $response['boards'] ) ); // Loop through each board and determine if there are tag matches. foreach ($response['boards'] as $boardUri => &$board) { // If we are filtering by tag and there is no match, remove from the response. - if ( $search['tags'] !== false && ( !isset( $boardTags[ $boardUri ] ) || !in_array( $search['tags'], $boardTags[ $boardUri ] )) ) { + if ( $search['tags'] !== false && ( !isset( $boardTags[ $boardUri ] ) || count(array_intersect($search['tags'], $boardTags[ $boardUri ])) !== count($search['tags']) ) ) { unset( $response['boards'][$boardUri] ); } // If we aren't filtering / there is a match AND we have tags, set the tags. @@ -145,13 +181,16 @@ foreach ($response['boards'] as $boardUri => &$board) { // Sort boards by their popularity, then by their total posts. $boardActivityValues = array(); $boardTotalPostsValues = array(); +$boardWeightValues = array(); foreach ($response['boards'] as $boardUri => &$board) { $boardActivityValues[$boardUri] = (int) $board['active']; $boardTotalPostsValues[$boardUri] = (int) $board['posts_total']; + $boardWeightValues[$boardUri] = (int) $board['weight']; } array_multisort( + $boardWeightValues, SORT_DESC, SORT_NUMERIC, // Sort by weight $boardActivityValues, SORT_DESC, SORT_NUMERIC, // Sort by number of active posters $boardTotalPostsValues, SORT_DESC, SORT_NUMERIC, // Then, sort by total number of posts $response['boards'] @@ -159,8 +198,8 @@ array_multisort( $boardLimit = $search['index'] ? 50 : 100; -$response['omitted'] = $search['index'] ? 0 : count( $response['boards'] ) - $boardLimit; -$response['boards'] = array_splice( $response['boards'], 0, $boardLimit ); +$response['omitted'] = count( $response['boards'] ) - $boardLimit; +$response['boards'] = array_splice( $response['boards'], $search['page'], $boardLimit ); $response['order'] = array_keys( $response['boards'] ); @@ -216,8 +255,13 @@ if (count($response['tags']) > 0) { } foreach ($tagUsage['users'] as $tagName => $tagUsers) { - $weightDeparture = abs( $tagUsers - $tagsAvgUsers ); - $response['tagWeight'][$tagName] = 75 + round( 100 * ( $weightDeparture / $weightDepartureFurthest ), 0); + if ($weightDepartureFurthest != 0) { + $weightDeparture = abs( $tagUsers - $tagsAvgUsers ); + $response['tagWeight'][$tagName] = 75 + round( 100 * ( $weightDeparture / $weightDepartureFurthest ), 0); + } + else { + $response['tagWeight'][$tagName] = 0; + } } } diff --git a/boards.php b/boards.php index 923971b6..5dd5fa97 100644 --- a/boards.php +++ b/boards.php @@ -36,6 +36,16 @@ $boards_omitted = (int) $searchJson['omitted']; $posts_hour = number_format( fetchBoardActivity(), 0 ); $posts_total = number_format( $boardResult['posts_total'], 0 ); +// This incredibly stupid looking chunk of code builds a query string using existing information. +// It's used to make clickable tags for users without JavaScript for graceful degredation. +// Because of how it orders tags, what you end up with is a prefix that always ends in tags=x+ +// ?tags= or ?sfw=1&tags= or ?title=foo&tags=bar+ - etc +$tagQueryGet = $_GET; +$tagQueryTags = isset($tagQueryGet['tags']) ? $tagQueryGet['tags'] : ""; +unset($tagQueryGet['tags']); +$tagQueryGet['tags'] = $tagQueryTags; +$tag_query = "?" . http_build_query( $tagQueryGet ) . ($tagQueryTags != "" ? "+" : ""); + /* Create and distribute page */ $config['additional_javascript'] = array( 'js/jquery.min.js', @@ -43,19 +53,24 @@ $config['additional_javascript'] = array( ); $boardsHTML = Element("8chan/boards-table.html", array( - "config" => $config, - "boards" => $boards, + "config" => $config, + "boards" => $boards, + "tag_query" => $tag_query, + ) ); $tagsHTML = Element("8chan/boards-tags.html", array( - "config" => $config, - "tags" => $tags, + "config" => $config, + "tags" => $tags, + "tag_query" => $tag_query, + ) ); $searchHTML = Element("8chan/boards-search.html", array( "config" => $config, + "search" => $searchJson['search'], "boards_total" => $boards_total, "boards_public" => $boards_public, diff --git a/js/board-directory.js b/js/board-directory.js index 6fe7edee..f22b686b 100644 --- a/js/board-directory.js +++ b/js/board-directory.js @@ -22,6 +22,8 @@ 'search-tag' : "#search-tag-input", 'search-title' : "#search-title-input", 'search-submit' : "#search-submit", + + 'tag-link' : ".tag-link" }, // HTML Templates for dynamic construction @@ -50,6 +52,8 @@ } }, + lastSearch : {}, + bind : { form : function() { var selectors = boardlist.options.selector; @@ -71,11 +75,17 @@ 'searchSubmit' : $searchSubmit }; - if ($search.length > 0) { // Bind form events. - $search.on( 'submit', searchForms, boardlist.events.searchSubmit ); - $searchSubmit.prop( 'disabled', false ).on( 'click', searchForms, boardlist.events.searchSubmit ); + boardlist.$boardlist + // Tag click + .on( 'click', selectors['tag-link'], searchForms, boardlist.events.tagClick ) + // Form Submission + .on( 'submit', selectors['search'], searchForms, boardlist.events.searchSubmit ) + // Submit click + .on( 'click', selectors['search-submit'], searchForms, boardlist.events.searchSubmit ); + + $searchSubmit.prop( 'disabled', false ); } } }, @@ -83,6 +93,7 @@ build : { boardlist : function(data) { boardlist.build.boards(data['boards'], data['order']); + boardlist.build.lastSearch(data['search']); boardlist.build.tags(data['tags']); }, @@ -101,12 +112,10 @@ boardlist.build.board( row, col ).appendTo( $row ); } ); - if( index >= 100 ) return false; - $row.appendTo( $body ); } ); }, - board : function( row, col ) { + board : function(row, col) { var $col = $(col), column = $col.attr('data-column'), value = row[column] @@ -150,10 +159,10 @@ return $cell; }, boardcell : { - 'meta' : function( row, value ) { + 'meta' : function(row, value) { return $( boardlist.options.template['board-datum-lang'] ).text( row['locale'] ); }, - 'uri' : function( row, value ) { + 'uri' : function(row, value) { var $link = $( boardlist.options.template['board-datum-uri'] ), $sfw = $( boardlist.options.template['board-datum-' + (row['sfw'] == 1 ? "sfw" : "nsfw")] ); @@ -172,8 +181,18 @@ } }, + lastSearch : function(search) { + return boardlist.lastSearch = { + 'lang' : search.lang === false ? "" : search.lang, + 'page' : search.page, + 'tags' : search.tags === false ? "" : search.tags.join(" "), + 'time' : search.time, + 'title' : search.title === false ? "" : search.title, + 'sfw' : search.nsfw ? 0 : 1 + }; + }, + tags : function(data) { - } }, @@ -181,32 +200,49 @@ searchSubmit : function(event) { event.preventDefault(); - var $boardlist = event.data.boardlist, - $boardbody = $( boardlist.options.selector['board-body'], $boardlist ), - $boardload = $( boardlist.options.selector['board-loading'], $boardlist ); + boardlist.submit( { + 'lang' : event.data.searchLang.val(), + 'tags' : event.data.searchTag.val(), + 'title' : event.data.searchTitle.val(), + 'sfw' : event.data.searchSfw.prop('checked') ? 1 : 0 + } ); - $boardbody.html(""); - $boardload.show(); + return false; + }, + + tagClick : function(event) { + event.preventDefault(); - $.get( - "/board-search.php", - { - 'lang' : event.data.searchLang.val(), - 'tags' : event.data.searchTag.val(), - //'time' : event.data.searchTag.val(), - 'title' : event.data.searchTitle.val(), - 'sfw' : event.data.searchSfw.prop('checked') ? 1 : 0 - }, - function(data) { - $boardload.hide(); - boardlist.build.boardlist( $.parseJSON(data) ); - } - ); + var $this = $(this), + $input = $( boardlist.options.selector['search-tag'] ); + + $input + .val( ( $input.val() + " " + $this.text() ).replace(/\s+/g, " ").trim() ) + .trigger( 'change' ) + .focus(); return false; } }, + submit : function( parameters ) { + var $boardlist = boardlist.$boardlist, + $boardbody = $( boardlist.options.selector['board-body'], $boardlist ), + $boardload = $( boardlist.options.selector['board-loading'], $boardlist ); + + $boardbody.html(""); + $boardload.show(); + + $.get( + "/board-search.php", + parameters, + function(data) { + $boardload.hide(); + boardlist.build.boardlist( $.parseJSON(data) ); + } + ); + }, + init : function( target ) { if (typeof target !== "string") { target = boardlist.options.selector.boardlist; @@ -217,7 +253,6 @@ if ($boardlist.length > 0 ) { $( boardlist.options.selector['board-loading'], $boardlist ).hide(); - boardlist.$boardlist = $boardlist; boardlist.bind.form(); } diff --git a/templates/8chan/boards-search.html b/templates/8chan/boards-search.html index 39c3f4c2..b4d17d65 100644 --- a/templates/8chan/boards-search.html +++ b/templates/8chan/boards-search.html @@ -8,16 +8,16 @@