User settings: new option to hide disliked posts

This commit is contained in:
Marcin Kurczewski 2013-12-05 22:19:21 +01:00
parent 0d3bb32e9c
commit 40e70c4305
7 changed files with 149 additions and 71 deletions

View file

@ -32,6 +32,7 @@ thumbHeight=150
thumbStyle=outside thumbStyle=outside
endlessScrollingDefault=1 endlessScrollingDefault=1
showPostTagTitlesDefault=0 showPostTagTitlesDefault=0
showDislikedPostsDefault=1
maxSearchTokens=4 maxSearchTokens=4
maxRelatedPosts=50 maxRelatedPosts=50

View file

@ -292,6 +292,7 @@ class UserController
$user->enableEndlessScrolling(InputHelper::get('endless-scrolling')); $user->enableEndlessScrolling(InputHelper::get('endless-scrolling'));
$user->enablePostTagTitles(InputHelper::get('post-tag-titles')); $user->enablePostTagTitles(InputHelper::get('post-tag-titles'));
$user->enableHidingDislikedPosts(InputHelper::get('hide-disliked-posts'));
Model_User::save($user); Model_User::save($user);
if ($user->id == $this->context->user->id) if ($user->id == $this->context->user->id)

View file

@ -234,19 +234,30 @@ class TextHelper
return $path; return $path;
} }
public static function openHtmlTag($tagName, array $attributes) const HTML_OPEN = 1;
const HTML_CLOSE = 2;
const HTML_LEAF = 3;
public static function htmlTag($tagName, $tagStyle, array $attributes = [])
{ {
$html = '<' . $tagName; $html = '<';
if ($tagStyle == self::HTML_CLOSE)
$html .= '/';
foreach ($attributes as $key => $value) $html .= $tagName;
$html .= ' ' . $key . '="' . $value . '"';
if ($tagStyle == self::HTML_OPEN or $tagStyle == self::HTML_LEAF)
{
foreach ($attributes as $key => $value)
{
$html .= ' ' . $key . '="' . $value . '"';
}
}
if ($tagStyle == self::HTML_LEAF)
$html .= '/';
$html .= '>'; $html .= '>';
echo $html;
}
public static function closeHtmlTag($tagName) return $html;
{
echo '</' . $tagName . '>';
} }
} }

View file

@ -51,7 +51,7 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
->close(); ->close();
} }
protected static function filterTokenId($context, $dbQuery, $val) protected static function filterTokenId($searchContext, $dbQuery, $val)
{ {
$ids = preg_split('/[;,]/', $val); $ids = preg_split('/[;,]/', $val);
$ids = array_map('intval', $ids); $ids = array_map('intval', $ids);
@ -60,57 +60,57 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
$dbQuery->put($id); $dbQuery->put($id);
} }
protected static function filterTokenIdMin($context, $dbQuery, $val) protected static function filterTokenIdMin($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('id >= ?')->put(intval($val)); $dbQuery->addSql('id >= ?')->put(intval($val));
} }
protected static function filterTokenIdMax($context, $dbQuery, $val) protected static function filterTokenIdMax($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('id <= ?')->put(intval($val)); $dbQuery->addSql('id <= ?')->put(intval($val));
} }
protected static function filterTokenScoreMin($context, $dbQuery, $val) protected static function filterTokenScoreMin($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('score >= ?')->put(intval($val)); $dbQuery->addSql('score >= ?')->put(intval($val));
} }
protected static function filterTokenScoreMax($context, $dbQuery, $val) protected static function filterTokenScoreMax($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('score <= ?')->put(intval($val)); $dbQuery->addSql('score <= ?')->put(intval($val));
} }
protected static function filterTokenTagMin($context, $dbQuery, $val) protected static function filterTokenTagMin($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('tag_count >= ?')->put(intval($val)); $dbQuery->addSql('tag_count >= ?')->put(intval($val));
} }
protected static function filterTokenTagMax($context, $dbQuery, $val) protected static function filterTokenTagMax($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('tag_count <= ?')->put(intval($val)); $dbQuery->addSql('tag_count <= ?')->put(intval($val));
} }
protected static function filterTokenFavMin($context, $dbQuery, $val) protected static function filterTokenFavMin($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('fav_count >= ?')->put(intval($val)); $dbQuery->addSql('fav_count >= ?')->put(intval($val));
} }
protected static function filterTokenFavMax($context, $dbQuery, $val) protected static function filterTokenFavMax($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('fav_count <= ?')->put(intval($val)); $dbQuery->addSql('fav_count <= ?')->put(intval($val));
} }
protected static function filterTokenCommentMin($context, $dbQuery, $val) protected static function filterTokenCommentMin($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('comment_count >= ?')->put(intval($val)); $dbQuery->addSql('comment_count >= ?')->put(intval($val));
} }
protected static function filterTokenCommentMax($context, $dbQuery, $val) protected static function filterTokenCommentMax($searchContext, $dbQuery, $val)
{ {
$dbQuery->addSql('comment_count <= ?')->put(intval($val)); $dbQuery->addSql('comment_count <= ?')->put(intval($val));
} }
protected static function filterTokenSpecial($context, $dbQuery, $val) protected static function filterTokenSpecial($searchContext, $dbQuery, $val)
{ {
$context = \Chibi\Registry::getContext(); $context = \Chibi\Registry::getContext();
@ -147,7 +147,7 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
} }
} }
protected static function filterTokenType($context, $dbQuery, $val) protected static function filterTokenType($searchContext, $dbQuery, $val)
{ {
switch (strtolower($val)) switch (strtolower($val))
{ {
@ -182,7 +182,7 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
return [$timeMin, $timeMax]; return [$timeMin, $timeMax];
} }
protected static function filterTokenDate($context, $dbQuery, $val) protected static function filterTokenDate($searchContext, $dbQuery, $val)
{ {
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val); list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
$dbQuery $dbQuery
@ -190,19 +190,19 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
->and('upload_date <= ?')->put($timeMax); ->and('upload_date <= ?')->put($timeMax);
} }
protected static function filterTokenDateMin($context, $dbQuery, $val) protected static function filterTokenDateMin($searchContext, $dbQuery, $val)
{ {
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val); list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
$dbQuery->addSql('upload_date >= ?')->put($timeMin); $dbQuery->addSql('upload_date >= ?')->put($timeMin);
} }
protected static function filterTokenDateMax($context, $dbQuery, $val) protected static function filterTokenDateMax($searchContext, $dbQuery, $val)
{ {
list ($timeMin, $timeMax) = self::__filterTokenDateParser($val); list ($timeMin, $timeMax) = self::__filterTokenDateParser($val);
$dbQuery->addSql('upload_date <= ?')->put($timeMax); $dbQuery->addSql('upload_date <= ?')->put($timeMax);
} }
protected static function filterTokenFav($context, $dbQuery, $val) protected static function filterTokenFav($searchContext, $dbQuery, $val)
{ {
$user = Model_User::locate($val); $user = Model_User::locate($val);
$dbQuery $dbQuery
@ -215,12 +215,12 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
->close(); ->close();
} }
protected static function filterTokenFavs($context, $dbQuery, $val) protected static function filterTokenFavs($searchContext, $dbQuery, $val)
{ {
return self::filterTokenFav($context, $dbQuery, $val); return self::filterTokenFav($searchContext, $dbQuery, $val);
} }
protected static function filterTokenComment($context, $dbQuery, $val) protected static function filterTokenComment($searchContext, $dbQuery, $val)
{ {
$user = Model_User::locate($val); $user = Model_User::locate($val);
$dbQuery $dbQuery
@ -233,53 +233,53 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
->close(); ->close();
} }
protected static function filterTokenCommenter($context, $dbQuery, $val) protected static function filterTokenCommenter($searchContext, $dbQuery, $val)
{ {
return self::filterTokenComment($context, $dbQuery, $val); return self::filterTokenComment($searchContext, $dbQuery, $val);
} }
protected static function filterTokenSubmit($context, $dbQuery, $val) protected static function filterTokenSubmit($searchContext, $dbQuery, $val)
{ {
$user = Model_User::locate($val); $user = Model_User::locate($val);
$dbQuery->addSql('uploader_id = ?')->put($user->id); $dbQuery->addSql('uploader_id = ?')->put($user->id);
} }
protected static function filterTokenUploader($context, $dbQuery, $val) protected static function filterTokenUploader($searchContext, $dbQuery, $val)
{ {
return self::filterTokenSubmit($context, $dbQuery, $val); return self::filterTokenSubmit($searchContext, $dbQuery, $val);
} }
protected static function filterTokenUpload($context, $dbQuery, $val) protected static function filterTokenUpload($searchContext, $dbQuery, $val)
{ {
return self::filterTokenSubmit($context, $dbQuery, $val); return self::filterTokenSubmit($searchContext, $dbQuery, $val);
} }
protected static function filterTokenUploaded($context, $dbQuery, $val) protected static function filterTokenUploaded($searchContext, $dbQuery, $val)
{ {
return self::filterTokenSubmit($context, $dbQuery, $val); return self::filterTokenSubmit($searchContext, $dbQuery, $val);
} }
protected static function filterTokenPrev($context, $dbQuery, $val) protected static function filterTokenPrev($searchContext, $dbQuery, $val)
{ {
self::__filterTokenPrevNext($context, $dbQuery, $val); self::__filterTokenPrevNext($searchContext, $dbQuery, $val);
} }
protected static function filterTokenNext($context, $dbQuery, $val) protected static function filterTokenNext($searchContext, $dbQuery, $val)
{ {
$context->orderDir *= -1; $searchContext->orderDir *= -1;
self::__filterTokenPrevNext($context, $dbQuery, $val); self::__filterTokenPrevNext($searchContext, $dbQuery, $val);
} }
protected static function __filterTokenPrevNext($context, $dbQuery, $val) protected static function __filterTokenPrevNext($searchContext, $dbQuery, $val)
{ {
$op1 = $context->orderDir == 1 ? '<' : '>'; $op1 = $searchContext->orderDir == 1 ? '<' : '>';
$op2 = $context->orderDir != 1 ? '<' : '>'; $op2 = $searchContext->orderDir != 1 ? '<' : '>';
$dbQuery $dbQuery
->open() ->open()
->open() ->open()
->addSql($context->orderColumn . ' ' . $op1 . ' ') ->addSql($searchContext->orderColumn . ' ' . $op1 . ' ')
->open() ->open()
->select($context->orderColumn) ->select($searchContext->orderColumn)
->from('post p2') ->from('post p2')
->where('p2.id = ?')->put(intval($val)) ->where('p2.id = ?')->put(intval($val))
->close() ->close()
@ -287,9 +287,9 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
->close() ->close()
->or() ->or()
->open() ->open()
->addSql($context->orderColumn . ' = ') ->addSql($searchContext->orderColumn . ' = ')
->open() ->open()
->select($context->orderColumn) ->select($searchContext->orderColumn)
->from('post p2') ->from('post p2')
->where('p2.id = ?')->put(intval($val)) ->where('p2.id = ?')->put(intval($val))
->close() ->close()
@ -299,7 +299,7 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
} }
protected static function parseOrderToken($context, $val) protected static function parseOrderToken($searchContext, $val)
{ {
$randomReset = true; $randomReset = true;
@ -365,8 +365,8 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
if ($randomReset and isset($_SESSION['browsing-seed'])) if ($randomReset and isset($_SESSION['browsing-seed']))
unset($_SESSION['browsing-seed']); unset($_SESSION['browsing-seed']);
$context->orderColumn = $orderColumn; $searchContext->orderColumn = $orderColumn;
$context->orderDir = $orderDir; $searchContext->orderDir = $orderDir;
} }
@ -421,11 +421,14 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
if (self::$enableTokenLimit and count($tokens) > $config->browsing->maxSearchTokens) if (self::$enableTokenLimit and count($tokens) > $config->browsing->maxSearchTokens)
throw new SimpleException('Too many search tokens (maximum: ' . $config->browsing->maxSearchTokens . ')'); throw new SimpleException('Too many search tokens (maximum: ' . $config->browsing->maxSearchTokens . ')');
$context = new StdClass; if (\Chibi\Registry::getContext()->user->hasEnabledHidingDislikedPosts())
$context->orderColumn = 'id'; $tokens []= '-special:disliked';
$context->orderDir = 1;
$tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($context, $dbQuery, &$orderToken) $searchContext = new StdClass;
$searchContext->orderColumn = 'id';
$searchContext->orderDir = 1;
$tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($searchContext, $dbQuery, &$orderToken)
{ {
if ($key != 'order') if ($key != 'order')
return false; return false;
@ -434,13 +437,13 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
$orderToken = '-' . $val; $orderToken = '-' . $val;
else else
$orderToken = $val; $orderToken = $val;
self::parseOrderToken($context, $orderToken); self::parseOrderToken($searchContext, $orderToken);
return true; return true;
}); });
$tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($context, $dbQuery) $tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($searchContext, $dbQuery)
{ {
if ($key !== null) if ($key !== null)
return false; return false;
@ -452,7 +455,7 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
return true; return true;
}); });
$tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($context, $dbQuery) $tokens = self::iterateTokens($tokens, function($neg, $key, $val) use ($searchContext, $dbQuery)
{ {
$methodName = 'filterToken' . TextHelper::kebabCaseToCamelCase($key); $methodName = 'filterToken' . TextHelper::kebabCaseToCamelCase($key);
if (!method_exists(__CLASS__, $methodName)) if (!method_exists(__CLASS__, $methodName))
@ -461,23 +464,23 @@ class Model_Post_QueryBuilder implements AbstractQueryBuilder
self::filterChain($dbQuery); self::filterChain($dbQuery);
if ($neg) if ($neg)
self::filterNegate($dbQuery); self::filterNegate($dbQuery);
self::$methodName($context, $dbQuery, $val); self::$methodName($searchContext, $dbQuery, $val);
return true; return true;
}); });
if (!empty($tokens)) if (!empty($tokens))
throw new SimpleException('Unknown search token "' . array_shift($tokens) . '"'); throw new SimpleException('Unknown search token "' . array_shift($tokens) . '"');
$dbQuery->orderBy($context->orderColumn); $dbQuery->orderBy($searchContext->orderColumn);
if ($context->orderDir == 1) if ($searchContext->orderDir == 1)
$dbQuery->desc(); $dbQuery->desc();
else else
$dbQuery->asc(); $dbQuery->asc();
if ($context->orderColumn != 'id') if ($searchContext->orderColumn != 'id')
{ {
$dbQuery->addSql(', id'); $dbQuery->addSql(', id');
if ($context->orderDir == 1) if ($searchContext->orderDir == 1)
$dbQuery->desc(); $dbQuery->desc();
else else
$dbQuery->asc(); $dbQuery->asc();

View file

@ -4,6 +4,7 @@ class Model_User extends AbstractModel
const SETTING_SAFETY = 1; const SETTING_SAFETY = 1;
const SETTING_ENDLESS_SCROLLING = 2; const SETTING_ENDLESS_SCROLLING = 2;
const SETTING_POST_TAG_TITLES = 3; const SETTING_POST_TAG_TITLES = 3;
const SETTING_HIDE_DISLIKED_POSTS = 4;
@ -207,6 +208,19 @@ class Model_User extends AbstractModel
$this->setSetting(self::SETTING_SAFETY, $new); $this->setSetting(self::SETTING_SAFETY, $new);
} }
public function hasEnabledHidingDislikedPosts()
{
$ret = $this->getSetting(self::SETTING_HIDE_DISLIKED_POSTS);
if ($ret === null)
$ret = !\Chibi\Registry::getConfig()->browsing->showDislikedPostsDefault;
return $ret;
}
public function enableHidingDislikedPosts($enabled)
{
$this->setSetting(self::SETTING_HIDE_DISLIKED_POSTS, $enabled ? 1 : 0);
}
public function hasEnabledPostTagTitles() public function hasEnabledPostTagTitles()
{ {
$ret = $this->getSetting(self::SETTING_POST_TAG_TITLES); $ret = $this->getSetting(self::SETTING_POST_TAG_TITLES);

View file

@ -33,9 +33,9 @@
if (!empty($class)) if (!empty($class))
$attrs['class'] = join(' ', $class); $attrs['class'] = join(' ', $class);
TextHelper::openHtmlTag('a', $attrs); echo TextHelper::htmlTag('a', TextHelper::HTML_OPEN, $attrs);
echo $option['text']; echo $option['text'];
TextHelper::closeHtmlTag('a'); echo TextHelper::htmlTag('a', TextHelper::HTML_CLOSE);
?> ?>
</li> </li>
<?php endforeach ?> <?php endforeach ?>

View file

@ -4,8 +4,19 @@
<div class="input-wrapper"> <div class="input-wrapper">
<?php foreach (PostSafety::getAll() as $safety): ?> <?php foreach (PostSafety::getAll() as $safety): ?>
<?php if (PrivilegesHelper::confirm(Privilege::ListPosts, PostSafety::toString($safety))): ?> <?php if (PrivilegesHelper::confirm(Privilege::ListPosts, PostSafety::toString($safety))): ?>
<label><input type="checkbox" name="safety[]" value="<?php echo $safety ?>"<?php if ($this->context->transport->user->hasEnabledSafety($safety)) echo ' checked="checked"' ?>/> <label>
<?php echo TextHelper::camelCaseToHumanCase(PostSafety::toString($safety), true) ?></label> <?php
$attrs = [];
$attrs['type'] = 'checkbox';
$attrs['name'] = 'safety[]';
$attrs['value'] = $safety;
if ($this->context->transport->user->hasEnabledSafety($safety))
$attrs['checked'] = 'checked';
echo TextHelper::htmlTag('input', TextHelper::HTML_LEAF, $attrs);
?>
<?php echo TextHelper::camelCaseToHumanCase(PostSafety::toString($safety), true) ?>
</label>
<?php endif ?> <?php endif ?>
<?php endforeach ?> <?php endforeach ?>
</div> </div>
@ -15,7 +26,16 @@
<label class="left" for="endless-scrolling">Endless scrolling:</label> <label class="left" for="endless-scrolling">Endless scrolling:</label>
<div class="input-wrapper"> <div class="input-wrapper">
<label> <label>
<input type="checkbox" id="endless-scrolling" name="endless-scrolling" <?php if ($this->context->transport->user->hasEnabledEndlessScrolling()) echo ' checked="checked"' ?>/> <?php
$attrs = [];
$attrs['type'] = 'checkbox';
$attrs['id'] = 'endless-scrolling';
$attrs['name'] = 'endless-scrolling';
if ($this->context->transport->user->hasEnabledEndlessScrolling())
$attrs['checked'] = 'checked';
echo TextHelper::htmlTag('input', TextHelper::HTML_LEAF, $attrs);
?>
Enabled Enabled
</label> </label>
</div> </div>
@ -25,7 +45,35 @@
<label class="left" for="post-tag-titles">Tags in thumbs:</label> <label class="left" for="post-tag-titles">Tags in thumbs:</label>
<div class="input-wrapper"> <div class="input-wrapper">
<label> <label>
<input type="checkbox" id="post-tag-titles" name="post-tag-titles" <?php if ($this->context->transport->user->hasEnabledPostTagTitles()) echo ' checked="checked"' ?>/> <?php
$attrs = [];
$attrs['type'] = 'checkbox';
$attrs['id'] = 'post-tag-titles';
$attrs['name'] = 'post-tag-titles';
if ($this->context->transport->user->hasEnabledPostTagTitles())
$attrs['checked'] = 'checked';
echo TextHelper::htmlTag('input', TextHelper::HTML_LEAF, $attrs);
?>
Enabled
</label>
</div>
</div>
<div class="hide-disliked-posts">
<label class="left" for="hide-disliked-posts">Hide down-voted:</label>
<div class="input-wrapper">
<label>
<?php
$attrs = [];
$attrs['type'] = 'checkbox';
$attrs['id'] = 'hide-disliked-posts';
$attrs['name'] = 'hide-disliked-posts';
if ($this->context->transport->user->hasEnabledHidingDislikedPosts())
$attrs['checked'] = 'checked';
echo TextHelper::htmlTag('input', TextHelper::HTML_LEAF, $attrs);
?>
Enabled Enabled
</label> </label>
</div> </div>