Empty commit

This commit is contained in:
Git 2014-04-06 08:00:49 +00:00
parent e22d400a95
commit 25c6f2a1c3
12 changed files with 261 additions and 287 deletions

View File

@ -404,11 +404,11 @@ public static function form($Index, $Return = false) {
/** /**
* Convenience function to echo out selected="selected" and checked="checked" so you don't have to. * Convenience function to echo out selected="selected" and checked="checked" so you don't have to.
* *
* @param $Name the name of the option in the select (or field in $Array) * @param string $Name the name of the option in the select (or field in $Array)
* @param $Value the value that the option must be for the option to be marked as selected or checked * @param mixed $Value the value that the option must be for the option to be marked as selected or checked
* @param $Attribute The value returned/echoed is $Attribute="$Attribute" with a leading space * @param string $Attribute The value returned/echoed is $Attribute="$Attribute" with a leading space
* @param $Array The array the option is in, defaults to GET. * @param array $Array The array the option is in, defaults to GET.
* @return * @return void
*/ */
public static function selected($Name, $Value, $Attribute = 'selected', $Array = array()) { public static function selected($Name, $Value, $Attribute = 'selected', $Array = array()) {
if (empty($Array)) { if (empty($Array)) {

View File

@ -367,7 +367,7 @@ public static function assert_isset_request($Request, $Keys = null, $AllowEmpty
/** /**
* Given an array of tags, return an array of their IDs. * Given an array of tags, return an array of their IDs.
* *
* @param arary $TagNames * @param array $TagNames
* @return array IDs * @return array IDs
*/ */
public static function get_tags($TagNames) { public static function get_tags($TagNames) {

View File

@ -7,15 +7,24 @@ class Requests {
*/ */
public static function update_sphinx_requests($RequestID) { public static function update_sphinx_requests($RequestID) {
$QueryID = G::$DB->get_query_id(); $QueryID = G::$DB->get_query_id();
G::$DB->query("
SELECT REPLACE(t.Name, '.', '_')
FROM tags AS t
JOIN requests_tags AS rt ON t.ID = rt.TagID
WHERE rt.RequestID = $RequestID");
$TagList = G::$DB->collect(0, false);
$TagList = db_string(implode(' ', $TagList));
G::$DB->query(" G::$DB->query("
REPLACE INTO sphinx_requests_delta ( REPLACE INTO sphinx_requests_delta (
ID, UserID, TimeAdded, LastVote, CategoryID, Title, ID, UserID, TimeAdded, LastVote, CategoryID, Title, TagList,
Year, ReleaseType, CatalogueNumber, RecordLabel, BitrateList, Year, ReleaseType, CatalogueNumber, RecordLabel, BitrateList,
FormatList, MediaList, LogCue, FillerID, TorrentID, FormatList, MediaList, LogCue, FillerID, TorrentID,
TimeFilled, Visible, Votes, Bounty) TimeFilled, Visible, Votes, Bounty)
SELECT SELECT
ID, r.UserID, UNIX_TIMESTAMP(TimeAdded) AS TimeAdded, ID, r.UserID, UNIX_TIMESTAMP(TimeAdded) AS TimeAdded,
UNIX_TIMESTAMP(LastVote) AS LastVote, CategoryID, Title, UNIX_TIMESTAMP(LastVote) AS LastVote, CategoryID, Title, '$TagList',
Year, ReleaseType, CatalogueNumber, RecordLabel, BitrateList, Year, ReleaseType, CatalogueNumber, RecordLabel, BitrateList,
FormatList, MediaList, LogCue, FillerID, TorrentID, FormatList, MediaList, LogCue, FillerID, TorrentID,
UNIX_TIMESTAMP(TimeFilled) AS TimeFilled, Visible, UNIX_TIMESTAMP(TimeFilled) AS TimeFilled, Visible,
@ -233,4 +242,3 @@ public static function get_votes_array($RequestID) {
} }
} }
?>

View File

@ -22,7 +22,7 @@
* indie (1) * indie (1)
* *
* Each time a new Tags object is instantiated, the tag list is merged with the * Each time a new Tags object is instantiated, the tag list is merged with the
* overall total amount of tags to provide the top tags. Merging is optional. * overall total amount of tags to provide a Top Tags list. Merging is optional.
*/ */
class Tags { class Tags {
/** /**
@ -145,6 +145,8 @@ public function format($Link = 'torrents.php?taglist=', $ArtistName = '') {
/** /**
* Format a list of top tags * Format a list of top tags
* @param int $Max Max number of items to get * @param int $Max Max number of items to get
* @param string $Link Page query where more items of this tag type can be found
* @param string $ArtistName Optional artist
*/ */
public static function format_top($Max = 5, $Link = 'torrents.php?taglist=', $ArtistName = '') { public static function format_top($Max = 5, $Link = 'torrents.php?taglist=', $ArtistName = '') {
if (empty(self::$All)) { ?> if (empty(self::$All)) { ?>
@ -159,4 +161,115 @@ public static function format_top($Max = 5, $Link = 'torrents.php?taglist=', $Ar
<li><a href="<?=$Link . display_str($TagName) . $ArtistName?>"><?=display_str($TagName)?></a> (<?=$Total?>)</li> <li><a href="<?=$Link . display_str($TagName) . $ArtistName?>"><?=display_str($TagName)?></a> (<?=$Total?>)</li>
<? } <? }
} }
/**
* General purpose method to get all tag aliases from the DB
* @return array
*/
public static function get_aliases() {
$TagAliases = G::$Cache->get_value('tag_aliases_search');
if ($TagAliases === false) {
G::$DB->query('
SELECT ID, BadTag, AliasTag
FROM tag_aliases
ORDER BY BadTag');
$TagAliases = G::$DB->to_array(false, MYSQLI_ASSOC, false);
// Unify tag aliases to be in_this_format as tags not in.this.format
array_walk_recursive($TagAliases, create_function('&$val', '$val = preg_replace("/\./","_", $val);'));
// Clean up the array for smaller cache size
foreach ($TagAliases as &$TagAlias) {
foreach (array_keys($TagAlias) as $Key) {
if (is_numeric($Key)) {
unset($TagAlias[$Key]);
}
}
}
G::$Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days
}
return $TagAliases;
}
/**
* Replace bad tags with tag aliases
* @param array $Tags Array with sub-arrays 'include' and 'exclude'
* @return array
*/
public static function remove_aliases($Tags) {
$TagAliases = self::get_aliases();
$End = count($Tags['include']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if ($Tags['include'][$i] === $TagAlias['BadTag']) {
$Tags['include'][$i] = $TagAlias['AliasTag'];
break;
}
}
}
$End = count($Tags['exclude']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) {
$Tags['exclude'][$i] = '!'.$TagAlias['AliasTag'];
break;
}
}
}
// Only keep unique entries after unifying tag standard
$Tags['include'] = array_unique($Tags['include']);
$Tags['exclude'] = array_unique($Tags['exclude']);
return $Tags;
}
/**
* Filters a list of include and exclude tags to be used in a Sphinx search
* @param array $Tags An array of tags with sub-arrays 'include' and 'exclude'
* @param boolean $EnableNegation Sphinx needs at least one positive search condition to support the NOT operator
* @param integer $TagType Search for Any or All of these tags.
* @return array Array keys predicate and input
* Predicate for a Sphinx 'taglist' query
* Input contains clean, aliased tags. Use it in a form instead of the user submitted string
*/
public static function tag_filter_sph($Tags, $EnableNegation, $TagType) {
$QueryParts = [];
$Tags = Tags::remove_aliases($Tags);
$TagList = str_replace('_', '.', implode(', ', array_merge($Tags['include'], $Tags['exclude'])));
if (!$EnableNegation && !empty($Tags['exclude'])) {
$Tags['include'] = array_merge($Tags['include'], $Tags['exclude']);
unset($Tags['exclude']);
}
foreach ($Tags['include'] as &$Tag) {
$Tag = Sphinxql::sph_escape_string($Tag);
}
if (!empty($Tags['exclude'])) {
foreach ($Tags['exclude'] as &$Tag) {
$Tag = '!' . Sphinxql::sph_escape_string(substr($Tag, 1));
}
}
// 'All' tags
if (!isset($TagType) || $TagType == 1) {
$SearchWords = array_merge($Tags['include'], $Tags['exclude']);
if (!empty($Tags)) {
$QueryParts[] = implode(' ', $SearchWords);
}
}
// 'Any' tags
else {
if (!empty($Tags['include'])) {
$QueryParts[] = '( ' . implode(' | ', $Tags['include']) . ' )';
}
if (!empty($Tags['exclude'])) {
$QueryParts[] = implode(' ', $Tags['exclude']);
}
}
return ['input' => $TagList, 'predicate' => implode(' ', $QueryParts)];
}
} }

View File

@ -1,5 +1,11 @@
CHANGE LOG CHANGE LOG
2014-04-06 by hateradio
Add wildcard support to taglist in request search
2014-04-05 by DutchDude
Make blog post author name link to author profile
2014-03-31 by Ajax 2014-03-31 by Ajax
Pushbullet support for push notifications Pushbullet support for push notifications

View File

@ -261,95 +261,22 @@
// Tag list // Tag list
if (!empty($SearchWords['taglist'])) { if (!empty($SearchWords['taglist'])) {
//Get tag aliases. $_GET['tags_type'] = (!isset($_GET['tags_type']) || $_GET['tags_type'] == 1) ? '1' : '0';
$TagAliases = $Cache->get_value('tag_aliases_search'); $TagType = (int)$_GET['tags_type'];
if ($TagAliases === false) {
$DB->query('
SELECT ID, BadTag, AliasTag
FROM tag_aliases
ORDER BY BadTag');
$TagAliases = $DB->to_array(false, MYSQLI_ASSOC, false);
//Unify tag aliases to be in_this_format as tags not in.this.format
array_walk_recursive($TagAliases, create_function('&$val', '$val = preg_replace("/\./","_", $val);'));
//Clean up the array for smaller cache size
foreach ($TagAliases as &$TagAlias) {
foreach (array_keys($TagAlias) as $Key) {
if (is_numeric($Key)) {
unset($TagAlias[$Key]);
}
}
}
$Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days
}
//Get tags //Get tags
$Tags = $SearchWords['taglist']; $Tags = $SearchWords['taglist'];
//Replace bad tags with tag aliases
$End = count($Tags['include']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if ($Tags['include'][$i] === $TagAlias['BadTag']) {
$Tags['include'][$i] = $TagAlias['AliasTag'];
break;
}
}
}
$End = count($Tags['exclude']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) {
$Tags['exclude'][$i] = '!'.$TagAlias['AliasTag'];
break;
}
}
}
//Only keep unique entries after unifying tag standard
$Tags['include'] = array_unique($Tags['include']);
$Tags['exclude'] = array_unique($Tags['exclude']);
$TagListString = implode(', ', array_merge($Tags['include'], $Tags['exclude']));
if (!$EnableNegation && !empty($Tags['exclude'])) {
$Tags['include'] = array_merge($Tags['include'], $Tags['exclude']);
unset($Tags['exclude']);
}
foreach ($Tags['include'] as &$Tag) {
$Tag = Sphinxql::sph_escape_string($Tag);
}
if (!empty($Tags['exclude'])) {
foreach ($Tags['exclude'] as &$Tag) {
$Tag = '!'.Sphinxql::sph_escape_string(substr($Tag, 1));
}
}
$QueryParts = array(); $TagFilter = Tags::tag_filter_sph($Tags, $EnableNegation, $TagType);
// 'All' tags if (!empty($TagFilter['predicate'])) {
if (!isset($_GET['tags_type']) || $_GET['tags_type'] == 1) { $SphQL->where_match($TagFilter['predicate'], 'taglist', false);
$_GET['tags_type'] = '1'; $SphQLTor->where_match($TagFilter['predicate'], 'taglist', false);
$Tags = array_merge($Tags['include'], $Tags['exclude']);
if (!empty($Tags)) {
$QueryParts[] = implode(' ', $Tags);
}
}
// 'Any' tags
else {
$_GET['tags_type'] = '0';
if (!empty($Tags['include'])) {
$QueryParts[] = '( '.implode(' | ', $Tags['include']).' )';
}
if (!empty($Tags['exclude'])) {
$QueryParts[] = implode(' ', $Tags['exclude']);
}
}
if (!empty($QueryParts)) {
$SphQL->where_match(implode(' ', $QueryParts), 'taglist', false);
$SphQLTor->where_match(implode(' ', $QueryParts), 'taglist', false);
} }
unset($SearchWords['taglist']); unset($SearchWords['taglist']);
} }
elseif (!isset($_GET['tags_type'])) { elseif (!isset($_GET['tags_type'])) {
$_GET['tags_type'] = '1'; $_GET['tags_type'] = '1';
} }
if (!isset($TagListString)) {
$TagListString = "";
}
foreach ($SearchWords as $Search => $Words) { foreach ($SearchWords as $Search => $Words) {
$QueryParts = array(); $QueryParts = array();

View File

@ -194,23 +194,6 @@
$EnableNegation = true; $EnableNegation = true;
} }
} }
$QueryParts = array();
if (!$EnableNegation && !empty($SearchWords['exclude'])) {
$SearchWords['include'] = array_merge($SearchWords['include'], $SearchWords['exclude']);
unset($SearchWords['exclude']);
}
foreach ($SearchWords['include'] as $Word) {
$QueryParts[] = Sphinxql::sph_escape_string($Word);
}
if (!empty($SearchWords['exclude'])) {
foreach ($SearchWords['exclude'] as $Word) {
$QueryParts[] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
}
}
if (!empty($QueryParts)) {
$SearchString = implode(' ', $QueryParts);
$SphQL->where_match($SearchString, '*', false);
}
} }
} }
@ -222,29 +205,27 @@
$_GET['tags_type'] = '0'; $_GET['tags_type'] = '0';
} }
if (!empty($_GET['tags'])) { if (!empty($_GET['tags'])) {
$SearchTags = array('include' => array(), 'exclude' => array());
$Tags = explode(',', $_GET['tags']); $Tags = explode(',', $_GET['tags']);
$TagNames = $TagsExclude = array();
// Remove illegal characters from the given tag names
foreach ($Tags as $Tag) { foreach ($Tags as $Tag) {
$Tag = ltrim($Tag); $Tag = trim($Tag);
$Exclude = ($Tag[0] === '!'); if ($Tag[0] === '!' && strlen($Tag) >= 2) {
$Tag = Misc::sanitize_tag($Tag); if (strpos($Tag, '!', 1) === false) {
if (!empty($Tag)) { $SearchTags['exclude'][] = $Tag;
$TagNames[] = $Tag; } else {
$TagsExclude[$Tag] = $Exclude; $SearchTags['include'][] = $Tag;
$EnableNegation = true;
}
} elseif ($Tag !== '') {
$SearchTags['include'][] = $Tag;
$EnableNegation = true;
} }
} }
$AllNegative = !in_array(false, $TagsExclude, true);
$Tags = Misc::get_tags($TagNames);
// Replace the ! characters that sanitize_tag removed $TagFilter = Tags::tag_filter_sph($SearchTags, $EnableNegation, $TagType);
if ($TagType === 1 || $AllNegative) {
foreach ($TagNames as &$TagName) { if (!empty($TagFilter['predicate'])) {
if ($TagsExclude[$TagName]) { $SphQL->where_match($TagFilter['predicate'], 'taglist', false);
$TagName = "!$TagName";
}
}
unset($TagName);
} }
} elseif (!isset($_GET['tags_type']) || $_GET['tags_type'] !== '0') { } elseif (!isset($_GET['tags_type']) || $_GET['tags_type'] !== '0') {
$_GET['tags_type'] = 1; $_GET['tags_type'] = 1;
@ -252,13 +233,24 @@
$_GET['tags_type'] = 0; $_GET['tags_type'] = 0;
} }
// 'All' tags if (isset($SearchWords)) {
if ($TagType === 1 && !empty($Tags)) { $QueryParts = array();
foreach ($Tags as $TagID => $TagName) { if (!$EnableNegation && !empty($SearchWords['exclude'])) {
$SphQL->where('tagid', $TagID, $TagsExclude[$TagName]); $SearchWords['include'] = array_merge($SearchWords['include'], $SearchWords['exclude']);
unset($SearchWords['exclude']);
}
foreach ($SearchWords['include'] as $Word) {
$QueryParts[] = Sphinxql::sph_escape_string($Word);
}
if (!empty($SearchWords['exclude'])) {
foreach ($SearchWords['exclude'] as $Word) {
$QueryParts[] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
}
}
if (!empty($QueryParts)) {
$SearchString = implode(' ', $QueryParts);
$SphQL->where_match($SearchString, '*', false);
} }
} elseif (!empty($Tags)) {
$SphQL->where('tagid', array_keys($Tags), $AllNegative);
} }
if (!empty($_GET['filter_cat'])) { if (!empty($_GET['filter_cat'])) {

View File

@ -147,6 +147,7 @@
SELECT SELECT
b.ID, b.ID,
um.Username, um.Username,
b.UserID,
b.Title, b.Title,
b.Body, b.Body,
b.Time, b.Time,
@ -156,7 +157,7 @@
ORDER BY Time DESC ORDER BY Time DESC
LIMIT 20"); LIMIT 20");
$Blog = $DB->to_array(); $Blog = $DB->to_array();
$Cache->cache_value('Blog', $Blog, 1209600); $Cache->cache_value('blog', $Blog, 1209600);
} }
if ($LoggedUser['LastReadBlog'] < $Blog[0][0]) { if ($LoggedUser['LastReadBlog'] < $Blog[0][0]) {
@ -171,11 +172,11 @@
} }
foreach ($Blog as $BlogItem) { foreach ($Blog as $BlogItem) {
list($BlogID, $Author, $Title, $Body, $BlogTime, $ThreadID) = $BlogItem; list($BlogID, $Author, $AuthorID, $Title, $Body, $BlogTime, $ThreadID) = $BlogItem;
?> ?>
<div id="blog<?=$BlogID?>" class="box blog_post"> <div id="blog<?=$BlogID?>" class="box blog_post">
<div class="head"> <div class="head">
<strong><?=$Title?></strong> - posted <?=time_diff($BlogTime);?> by <?=$Author?> <strong><?=$Title?></strong> - posted <?=time_diff($BlogTime);?> by <a href="user.php?id=<?=$AuthorID?>"><?=$Author?></a>
<? if (check_perms('admin_manage_blog')) { ?> <? if (check_perms('admin_manage_blog')) { ?>
- <a href="blog.php?action=editblog&amp;id=<?=$BlogID?>" class="brackets">Edit</a> - <a href="blog.php?action=editblog&amp;id=<?=$BlogID?>" class="brackets">Edit</a>
<a href="blog.php?action=deleteblog&amp;id=<?=$BlogID?>&amp;auth=<?=$LoggedUser['AuthKey']?>" class="brackets">Delete</a> <a href="blog.php?action=deleteblog&amp;id=<?=$BlogID?>&amp;auth=<?=$LoggedUser['AuthKey']?>" class="brackets">Delete</a>

View File

@ -97,6 +97,7 @@
SELECT SELECT
b.ID, b.ID,
um.Username, um.Username,
b.UserID,
b.Title, b.Title,
b.Body, b.Body,
b.Time, b.Time,
@ -117,7 +118,7 @@
$Limit = 5; $Limit = 5;
} }
for ($i = 0; $i < $Limit; $i++) { for ($i = 0; $i < $Limit; $i++) {
list($BlogID, $Author, $Title, $Body, $BlogTime, $ThreadID) = $Blog[$i]; list($BlogID, $Author, $AuthorID, $Title, $Body, $BlogTime, $ThreadID) = $Blog[$i];
?> ?>
<li> <li>
<?=($i + 1)?>. <a href="blog.php#blog<?=$BlogID?>"><?=$Title?></a> <?=($i + 1)?>. <a href="blog.php#blog<?=$BlogID?>"><?=$Title?></a>

View File

@ -195,23 +195,6 @@
$EnableNegation = true; $EnableNegation = true;
} }
} }
$QueryParts = array();
if (!$EnableNegation && !empty($SearchWords['exclude'])) {
$SearchWords['include'] = array_merge($SearchWords['include'], $SearchWords['exclude']);
unset($SearchWords['exclude']);
}
foreach ($SearchWords['include'] as $Word) {
$QueryParts[] = Sphinxql::sph_escape_string($Word);
}
if (!empty($SearchWords['exclude'])) {
foreach ($SearchWords['exclude'] as $Word) {
$QueryParts[] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
}
}
if (!empty($QueryParts)) {
$SearchString = implode(' ', $QueryParts);
$SphQL->where_match($SearchString, '*', false);
}
} }
} }
@ -224,43 +207,54 @@
} }
if (!empty($_GET['tags'])) { if (!empty($_GET['tags'])) {
$Tags = explode(',', $_GET['tags']); $SearchTags = array('include' => array(), 'exclude' => array());
$TagNames = $TagsExclude = array(); $Tags = explode(',', str_replace('.', '_', $_GET['tags']));
// Remove illegal characters from the given tag names
foreach ($Tags as $Tag) { foreach ($Tags as $Tag) {
$Tag = ltrim($Tag); $Tag = trim($Tag);
$Exclude = ($Tag[0] === '!'); if ($Tag[0] === '!' && strlen($Tag) >= 2) {
$Tag = Misc::sanitize_tag($Tag); if (strpos($Tag, '!', 1) === false) {
if (!empty($Tag)) { $SearchTags['exclude'][] = $Tag;
$TagNames[] = $Tag; } else {
$TagsExclude[$Tag] = $Exclude; $SearchTags['include'][] = $Tag;
} $EnableNegation = true;
}
$AllNegative = !in_array(false, $TagsExclude, true);
$Tags = Misc::get_tags($TagNames);
// Replace the ! characters that sanitize_tag removed
if ($TagType === 1 || $AllNegative) {
foreach ($TagNames as &$TagName) {
if ($TagsExclude[$TagName]) {
$TagName = "!$TagName";
} }
} elseif ($Tag !== '') {
$SearchTags['include'][] = $Tag;
$EnableNegation = true;
} }
unset($TagName);
} }
$TagFilter = Tags::tag_filter_sph($SearchTags, $EnableNegation, $TagType);
$TagNames = $TagFilter['input'];
if (!empty($TagFilter['predicate'])) {
$SphQL->where_match($TagFilter['predicate'], 'taglist', false);
}
} elseif (!isset($_GET['tags_type']) || $_GET['tags_type'] !== '0') { } elseif (!isset($_GET['tags_type']) || $_GET['tags_type'] !== '0') {
$_GET['tags_type'] = 1; $_GET['tags_type'] = 1;
} else { } else {
$_GET['tags_type'] = 0; $_GET['tags_type'] = 0;
} }
// 'All' tags if (isset($SearchWords)) {
if ($TagType === 1 && !empty($Tags)) { $QueryParts = array();
foreach ($Tags as $TagID => $TagName) { if (!$EnableNegation && !empty($SearchWords['exclude'])) {
$SphQL->where('tagid', $TagID, $TagsExclude[$TagName]); $SearchWords['include'] = array_merge($SearchWords['include'], $SearchWords['exclude']);
unset($SearchWords['exclude']);
}
foreach ($SearchWords['include'] as $Word) {
$QueryParts[] = Sphinxql::sph_escape_string($Word);
}
if (!empty($SearchWords['exclude'])) {
foreach ($SearchWords['exclude'] as $Word) {
$QueryParts[] = '!' . Sphinxql::sph_escape_string(substr($Word, 1));
}
}
if (!empty($QueryParts)) {
$SearchString = implode(' ', $QueryParts);
$SphQL->where_match($SearchString, '*', false);
} }
} elseif (!empty($Tags)) {
$SphQL->where('tagid', array_keys($Tags), $AllNegative);
} }
if (!empty($_GET['filter_cat'])) { if (!empty($_GET['filter_cat'])) {
@ -382,7 +376,7 @@
<tr id="tagfilter"> <tr id="tagfilter">
<td class="label">Tags (comma-separated):</td> <td class="label">Tags (comma-separated):</td>
<td> <td>
<input type="search" name="tags" id="tags" size="60" value="<?=(!empty($TagNames) ? display_str(implode(', ', $TagNames)) : '') ?>"<? Users::has_autocomplete_enabled('other'); ?> />&nbsp; <input type="search" name="tags" id="tags" size="60" value="<?=!empty($TagNames) ? display_str($TagNames) : ''?>"<? Users::has_autocomplete_enabled('other'); ?> />&nbsp;
<input type="radio" name="tags_type" id="tags_type0" value="0"<? Format::selected('tags_type', 0, 'checked')?> /><label for="tags_type0"> Any</label>&nbsp;&nbsp; <input type="radio" name="tags_type" id="tags_type0" value="0"<? Format::selected('tags_type', 0, 'checked')?> /><label for="tags_type0"> Any</label>&nbsp;&nbsp;
<input type="radio" name="tags_type" id="tags_type1" value="1"<? Format::selected('tags_type', 1, 'checked')?> /><label for="tags_type1"> All</label> <input type="radio" name="tags_type" id="tags_type1" value="1"<? Format::selected('tags_type', 1, 'checked')?> /><label for="tags_type1"> All</label>
</td> </td>

View File

@ -322,96 +322,26 @@ function header_link($SortKey, $DefaultWay = 'desc') {
// Tag list // Tag list
if (!empty($SearchWords['taglist'])) { if (!empty($SearchWords['taglist'])) {
// Get tag aliases. $_GET['tags_type'] = (!isset($_GET['tags_type']) || $_GET['tags_type'] == 1) ? '1' : '0';
$TagAliases = $Cache->get_value('tag_aliases_search'); $TagType = (int)$_GET['tags_type'];
if ($TagAliases === false) {
$DB->query('
SELECT ID, BadTag, AliasTag
FROM tag_aliases
ORDER BY BadTag');
$TagAliases = $DB->to_array(false, MYSQLI_ASSOC, false);
// Unify tag aliases to be in_this_format as tags not in.this.format
array_walk_recursive($TagAliases, create_function('&$val', '$val = preg_replace("/\./","_", $val);'));
// Clean up the array for smaller cache size
foreach ($TagAliases as &$TagAlias) {
foreach (array_keys($TagAlias) as $Key) {
if (is_numeric($Key)) {
unset($TagAlias[$Key]);
}
}
}
$Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days
}
// Get tags
$Tags = $SearchWords['taglist'];
// Replace bad tags with tag aliases
$End = count($Tags['include']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if ($Tags['include'][$i] === $TagAlias['BadTag']) {
$Tags['include'][$i] = $TagAlias['AliasTag'];
break;
}
}
}
$End = count($Tags['exclude']);
for ($i = 0; $i < $End; $i++) {
foreach ($TagAliases as $TagAlias) {
if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) {
$Tags['exclude'][$i] = '!'.$TagAlias['AliasTag'];
break;
}
}
}
// Only keep unique entries after unifying tag standard
$Tags['include'] = array_unique($Tags['include']);
$Tags['exclude'] = array_unique($Tags['exclude']);
$TagListString = implode(', ', array_merge($Tags['include'], $Tags['exclude']));
if (!$EnableNegation && !empty($Tags['exclude'])) {
$Tags['include'] = array_merge($Tags['include'], $Tags['exclude']);
unset($Tags['exclude']);
}
foreach ($Tags['include'] as &$Tag) {
$Tag = Sphinxql::sph_escape_string($Tag);
}
if (!empty($Tags['exclude'])) {
foreach ($Tags['exclude'] as &$Tag) {
$Tag = '!'.Sphinxql::sph_escape_string(substr($Tag, 1));
}
}
$QueryParts = array(); //Get tags
// 'All' tags $Tags = $SearchWords['taglist'];
if (!isset($_GET['tags_type']) || $_GET['tags_type'] == 1) {
$_GET['tags_type'] = '1'; $TagFilter = Tags::tag_filter_sph($Tags, $EnableNegation, $TagType);
$Tags = array_merge($Tags['include'], $Tags['exclude']); $TagListString = $TagFilter['input'];
if (!empty($Tags)) {
$QueryParts[] = implode(' ', $Tags); if (!empty($TagFilter['predicate'])) {
} $SphQL->where_match($TagFilter['predicate'], 'taglist', false);
} $SphQLTor->where_match($TagFilter['predicate'], 'taglist', false);
// 'Any' tags
else {
$_GET['tags_type'] = '0';
if (!empty($Tags['include'])) {
$QueryParts[] = '( '.implode(' | ', $Tags['include']).' )';
}
if (!empty($Tags['exclude'])) {
$QueryParts[] = implode(' ', $Tags['exclude']);
}
}
if (!empty($QueryParts)) {
$SphQL->where_match(implode(' ', $QueryParts), 'taglist', false);
$SphQLTor->where_match(implode(' ', $QueryParts), 'taglist', false);
$Filtered = true; $Filtered = true;
} }
unset($SearchWords['taglist']); unset($SearchWords['taglist']);
} }
elseif (!isset($_GET['tags_type'])) { elseif (!isset($_GET['tags_type'])) {
$_GET['tags_type'] = '1'; $_GET['tags_type'] = '1';
} }
if (!isset($TagListString)) {
$TagListString = "";
}
foreach ($SearchWords as $Search => $Words) { foreach ($SearchWords as $Search => $Words) {
$QueryParts = array(); $QueryParts = array();
@ -786,7 +716,7 @@ function header_link($SortKey, $DefaultWay = 'desc') {
<tr id="tagfilter"> <tr id="tagfilter">
<td class="label"><span title="Use !tag to exclude tag" class="tooltip">Tags (comma-separated):</span></td> <td class="label"><span title="Use !tag to exclude tag" class="tooltip">Tags (comma-separated):</span></td>
<td colspan="3" class="ft_taglist"> <td colspan="3" class="ft_taglist">
<input type="search" size="40" id="tags" name="taglist" class="inputtext smaller" value="<?=str_replace('_', '.', display_str($TagListString)) /* Use aliased tags, not actual query string. */ ?>" />&nbsp; <input type="search" size="40" id="tags" name="taglist" class="inputtext smaller" value="<?=!empty($TagListString) ? display_str($TagListString) : ''?>"<? Users::has_autocomplete_enabled('other'); ?> />&nbsp;
<input type="radio" name="tags_type" id="tags_type0" value="0"<?Format::selected('tags_type', 0, 'checked')?> /><label for="tags_type0"> Any</label>&nbsp;&nbsp; <input type="radio" name="tags_type" id="tags_type0" value="0"<?Format::selected('tags_type', 0, 'checked')?> /><label for="tags_type0"> Any</label>&nbsp;&nbsp;
<input type="radio" name="tags_type" id="tags_type1" value="1"<?Format::selected('tags_type', 1, 'checked')?> /><label for="tags_type1"> All</label> <input type="radio" name="tags_type" id="tags_type1" value="1"<?Format::selected('tags_type', 1, 'checked')?> /><label for="tags_type1"> All</label>
</td> </td>

View File

@ -93,6 +93,7 @@ source torrents : torrents_base {
index torrents { index torrents {
source = torrents source = torrents
path = /var/lib/sphinx/torrents path = /var/lib/sphinx/torrents
dict = crc
# stopwords = /etc/sphinx/stopwords.txt # Path to file containing a space separated list of words not to index # stopwords = /etc/sphinx/stopwords.txt # Path to file containing a space separated list of words not to index
preopen = 1 preopen = 1
morphology = none morphology = none
@ -309,7 +310,7 @@ index delta : torrents {
path = /var/lib/sphinx/delta path = /var/lib/sphinx/delta
} }
source requests : connect { source requests_base : connect {
sql_attr_uint = UserID sql_attr_uint = UserID
sql_attr_uint = TimeAdded sql_attr_uint = TimeAdded
sql_attr_uint = LastVote sql_attr_uint = LastVote
@ -322,7 +323,9 @@ source requests : connect {
sql_attr_uint = Visible sql_attr_uint = Visible
sql_attr_uint = Votes sql_attr_uint = Votes
sql_attr_uint = Bounty sql_attr_uint = Bounty
}
source requests : requests_base {
sql_query_pre = TRUNCATE TABLE sphinx_requests sql_query_pre = TRUNCATE TABLE sphinx_requests
sql_query_pre = SET group_concat_max_len = 10140 sql_query_pre = SET group_concat_max_len = 10140
sql_query_pre = SET @starttime = NOW() sql_query_pre = SET @starttime = NOW()
@ -363,49 +366,45 @@ source requests : connect {
Year AS YearFullText \ Year AS YearFullText \
FROM sphinx_requests FROM sphinx_requests
sql_query_post_index = DELETE FROM sphinx_requests_delta WHERE TimeAdded <= \ sql_joined_field = taglist from query; \
(SELECT ID FROM sphinx_index_last_pos WHERE type = 'requests') SELECT rt.RequestID, REPLACE(t.Name, '.', '_') \
FROM requests_tags AS rt \
sql_attr_multi = uint TagID from query; \ JOIN tags AS t ON TagID = ID \
SELECT RequestID AS ID, TagID FROM requests_tags ORDER BY requestid ASC;
sql_attr_multi = uint Voter from query; \ sql_attr_multi = uint Voter from query; \
SELECT RequestID AS ID, UserID FROM requests_votes SELECT RequestID AS ID, UserID FROM requests_votes
sql_attr_multi = uint Bookmarker from query; \ sql_attr_multi = uint Bookmarker from query; \
SELECT RequestID AS ID, UserID FROM bookmarks_requests SELECT RequestID AS ID, UserID FROM bookmarks_requests
sql_query_info = SELECT * FROM sphinx_requests WHERE ID = $id sql_query_post_index = DELETE FROM sphinx_requests_delta WHERE TimeAdded <= \
(SELECT ID FROM sphinx_index_last_pos WHERE type = 'requests')
} }
source requests_delta : requests { source requests_delta : requests_base {
sql_query_pre = SET @nothing = 0 sql_query = SELECT ID, UserID, TimeAdded, LastVote, CategoryID, Title, TagList, \
sql_query = SELECT ID, UserID, TimeAdded, LastVote, CategoryID, Title, \
Year, ArtistList, ReleaseType, RecordLabel, CatalogueNumber, \ Year, ArtistList, ReleaseType, RecordLabel, CatalogueNumber, \
BitrateList, FormatList, MediaList, LogCue, FillerID, \ BitrateList, FormatList, MediaList, LogCue, FillerID, \
TorrentID, TimeFilled, Visible, Votes, Bounty, \ TorrentID, TimeFilled, Visible, Votes, Bounty, \
Year AS YearFullText \ Year AS YearFullText \
FROM sphinx_requests_delta FROM sphinx_requests_delta
sql_query_post_index = SET @nothing = 0
sql_query_info = SELECT * FROM sphinx_requests_delta WHERE ID = $id
sql_query_killlist = SELECT ID FROM sphinx_requests_delta sql_query_killlist = SELECT ID FROM sphinx_requests_delta
sql_attr_multi = uint TagID from query; \
SELECT t.RequestID, t.TagID FROM requests_tags AS t\
JOIN sphinx_requests_delta AS d ON d.ID = t.RequestID
sql_attr_multi = uint Voter from query; \ sql_attr_multi = uint Voter from query; \
SELECT v.RequestID, v.UserID FROM requests_votes AS v \ SELECT v.RequestID, v.UserID FROM requests_votes AS v \
JOIN sphinx_requests_delta AS d ON d.ID = v.RequestID JOIN sphinx_requests_delta AS d ON d.ID = v.RequestID
sql_attr_multi = uint Bookmarker from query; \ sql_attr_multi = uint Bookmarker from query; \
SELECT b.RequestID, b.UserID FROM bookmarks_requests AS b \ SELECT b.RequestID, b.UserID FROM bookmarks_requests AS b \
JOIN sphinx_requests_delta AS d ON d.ID = b.RequestID JOIN sphinx_requests_delta AS d ON d.ID = b.RequestID
} }
index requests : torrents { index requests : torrents {
source = requests source = requests
path = /var/lib/sphinx/requests path = /var/lib/sphinx/requests
infix_fields = taglist
min_infix_len = 3
enable_star = 1
} }
index requests_delta : requests { index requests_delta : requests {
source = requests_delta source = requests_delta
@ -415,7 +414,6 @@ index requests_delta : requests {
source log : connect { source log : connect {
sql_attr_uint = Time sql_attr_uint = Time
sql_query = SELECT ID, UNIX_TIMESTAMP(Time) AS Time, Message FROM log sql_query = SELECT ID, UNIX_TIMESTAMP(Time) AS Time, Message FROM log
sql_query_info = SELECT * FROM log WHERE ID = $id
sql_query_post_index = REPLACE INTO sphinx_index_last_pos VALUES ('log', $maxid) sql_query_post_index = REPLACE INTO sphinx_index_last_pos VALUES ('log', $maxid)
} }
source log_delta : log { source log_delta : log {
@ -425,8 +423,10 @@ source log_delta : log {
} }
index log : torrents { index log : torrents {
source = log source = log
min_word_len = 1
path = /var/lib/sphinx/log path = /var/lib/sphinx/log
min_word_len = 1
min_infix_len = 0
infix_fields =
} }
index log_delta : log { index log_delta : log {
source = log_delta source = log_delta
@ -462,6 +462,8 @@ index better_transcode : torrents {
source = better_transcode source = better_transcode
path = /var/lib/sphinx/better_transcode path = /var/lib/sphinx/better_transcode
phrase_boundary = phrase_boundary =
min_infix_len = 0
infix_fields =
} }
indexer { indexer {