Favorites; gravatar support

This commit is contained in:
Marcin Kurczewski 2013-10-12 14:53:47 +02:00
parent 67dcc7c4f8
commit 7c5d1b7e34
10 changed files with 244 additions and 39 deletions

View file

@ -44,6 +44,7 @@ listPosts=anonymous
listPosts.sketchy=registered
listPosts.unsafe=registered
listUsers=registered
favoritePost=registered
listComments=registered
retrievePost=anonymous
listTags=anonymous

View file

@ -87,8 +87,8 @@ body {
}
#sidebar .sidebar-unit {
margin: 0 0 2em 0;
padding: 1em;
margin: 0 0 1.5em 0;
padding: 0.75em;
border: 1px solid #eee;
padding-left: 0;
border-left: 0;

View file

@ -1,5 +1,7 @@
#sidebar {
width: 200px;
line-height: 1.33em;
font-size: 90%;
}
.post-wrapper {
@ -71,9 +73,24 @@ i.icon-dl {
content: ', ';
}
.details {
line-height: 1.33em;
}
.details .key {
margin-right: 0.5em;
}
.options nav ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.favorites ul {
list-style-type: none;
margin: 0;
padding: 0;
}
.favorites li {
display: inline-block;
}
.favorites a {
margin: 2px;
}

View file

@ -0,0 +1,20 @@
$(function()
{
$('.add-fav a, .rem-fav a').click(function(e)
{
e.preventDefault();
var url = $(this).attr('href');
url += '?json';
$.get(url, function(data)
{
if (data['errorMessage'])
{
alert(data['errorMessage']);
}
else
{
window.location.reload();
}
});
});
});

View file

@ -24,7 +24,6 @@ class Bootstrap
public function workWrapper($workCallback)
{
$this->config->chibi->baseUrl = 'http://' . rtrim($_SERVER['HTTP_HOST'], '/') . '/';
R::setup('sqlite:' . $this->config->main->dbPath);
session_start();
$this->context->title = $this->config->main->title;

View file

@ -188,10 +188,11 @@ class PostController
$dbPost->mime_type = $mimeType;
$dbPost->safety = $suppliedSafety;
$dbPost->upload_date = time();
$dbPost->sharedTag = $dbTags;
$dbPost->user = $this->context->user;
$dbPost->image_width = $imageWidth;
$dbPost->image_height = $imageHeight;
$dbPost->uploader = $this->context->user;
$dbPost->ownFavoritee = [];
$dbPost->sharedTag = $dbTags;
move_uploaded_file($suppliedFile['tmp_name'], $path);
R::store($dbPost);
@ -200,6 +201,54 @@ class PostController
}
}
/**
* @route /post/add-fav/{id}
* @route /post/fav-add/{id}
*/
public function addFavoriteAction($id)
{
$post = self::locatePost($id);
R::preload($post, ['favoritee' => 'user']);
if (!$this->context->loggedIn)
throw new SimpleException('Not logged in');
foreach ($post->via('favoritee')->sharedUser as $fav)
if ($fav->id == $this->context->user->id)
throw new SimpleException('Already in favorites');
PrivilegesHelper::confirmWithException($this->context->user, Privilege::FavoritePost);
$post->link('favoritee')->user = $this->context->user;
R::store($post);
$this->context->transport->success = true;
}
/**
* @route /post/rem-fav/{id}
* @route /post/fav-rem/{id}
*/
public function remFavoriteAction($id)
{
$post = self::locatePost($id);
R::preload($post, ['favoritee' => 'user']);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::FavoritePost);
if (!$this->context->loggedIn)
throw new SimpleException('Not logged in');
$finalKey = null;
foreach ($post->ownFavoritee as $key => $fav)
if ($fav->user->id == $this->context->user->id)
$finalKey = $key;
if ($finalKey === null)
throw new SimpleException('Not in favorites');
unset ($post->ownFavoritee[$key]);
R::store($post);
$this->context->transport->success = true;
}
/**
@ -208,10 +257,8 @@ class PostController
*/
public function viewAction($id)
{
$post = R::findOne('post', 'id = ?', [$id]);
if (!$post)
throw new SimpleException('Invalid post ID "' . $id . '"');
R::preload($post, ['user', 'tag']);
$post = self::locatePost($id);
R::preload($post, ['favoritee' => 'user', 'uploader' => 'user', 'tag']);
$prevPost = R::findOne('post', 'id < ? ORDER BY id DESC LIMIT 1', [$id]);
$nextPost = R::findOne('post', 'id > ? ORDER BY id ASC LIMIT 1', [$id]);
@ -219,6 +266,12 @@ class PostController
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
$favorite = false;
if ($this->context->loggedIn)
foreach ($post->ownFavoritee as $fav)
if ($fav->user->id == $this->context->user->id)
$favorite = true;
$dbQuery = R::$f->begin();
$dbQuery->select('tag.name, COUNT(1) AS count');
$dbQuery->from('tag');
@ -234,9 +287,10 @@ class PostController
$this->context->transport->tagDistribution[$row['name']] = $row['count'];
$this->context->stylesheets []= 'post-view.css';
$this->context->scripts []= 'post-view.js';
$this->context->subTitle = 'showing @' . $post->id;
$this->context->favorite = $favorite;
$this->context->transport->post = $post;
$this->context->transport->uploader = R::load('user', $post->user_id);
$this->context->transport->prevPostId = $prevPost ? $prevPost->id : null;
$this->context->transport->nextPostId = $nextPost ? $nextPost->id : null;
}
@ -250,10 +304,7 @@ class PostController
public function thumbAction($id)
{
$this->context->layoutName = 'layout-file';
$post = R::findOne('post', 'id = ?', [$id]);
if (!$post)
throw new SimpleException('Invalid post ID "' . $id . '"');
$post = self::locatePost($id);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
@ -324,10 +375,7 @@ class PostController
public function retrieveAction($name)
{
$this->context->layoutName = 'layout-file';
$post = R::findOne('post', 'name = ?', [$name]);
if (!$post)
throw new SimpleException('Invalid post name "' . $name . '"');
$post = self::locatePost($name);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost);
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost, PostSafety::toString($post->safety));
@ -354,4 +402,21 @@ class PostController
$this->listAction('favmin:1', $page);
$this->context->viewName = 'post-list';
}
public static function locatePost($key)
{
if (is_numeric($key))
{
$post = R::findOne('post', 'id = ?', [$key]);
if (!$post)
throw new SimpleException('Invalid post ID "' . $key . '"');
}
else
{
$post = R::findOne('post', 'name = ?', [$key]);
if (!$post)
throw new SimpleException('Invalid post name "' . $key . '"');
}
return $post;
}
}

13
src/Models/Model_User.php Normal file
View file

@ -0,0 +1,13 @@
<?php
class Model_User extends RedBean_SimpleModel
{
public function avatarUrl($size = 32)
{
$subject = !empty($this->email)
? $this->email
: $this->name;
$hash = md5(strtolower(trim($subject)));
$url = 'http://www.gravatar.com/avatar/' . $hash . '?s=' . $size . '&d=retro';
return $url;
}
}

View file

@ -5,7 +5,8 @@ class Privilege extends Enum
const UploadPost = 2;
const ViewPost = 3;
const RetrievePost = 4;
const ListUsers = 5;
const ListComments = 6;
const ListTags = 7;
const FavoritePost = 5;
const ListUsers = 6;
const ListComments = 7;
const ListTags = 8;
}

View file

@ -30,7 +30,7 @@
</nav>
<div class="sidebar-unit tags">
<h1>tags</h1>
<h1>tags (<?php echo count($this->context->transport->post->sharedTag) ?>)</h1>
<!-- todo: edit tags -->
<ul>
<?php foreach ($this->context->transport->post->sharedTag as $tag): ?>
@ -57,8 +57,8 @@
<div class="uploader">
<span class="key">Uploader:</span>
<span class="value">
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['id' => $this->context->transport->post->user->id]) ?>">
<?php echo $this->context->transport->post->user->name ?>
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['name' => $this->context->transport->post->uploader->id]) ?>">
<?php echo $this->context->transport->post->uploader->name ?>
</a>
</span>
</div>
@ -90,9 +90,84 @@
</div>
</div>
<!-- todo: favorites -->
<div class="sidebar-unit favorites">
<?php if (count($this->context->transport->post->ownFavoritee) == 0): ?>
<h1>favorites</h1>
<p>None yet.</p>
<?php else: ?>
<h1>favorites (<?php echo count($this->context->transport->post->ownFavoritee) ?>)</h1>
<ul>
<?php foreach ($this->context->transport->post->via('favoritee')->sharedUser as $user): ?>
<li>
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['name' => $user->name]) ?>">
<img src="<?php echo $user->avatarUrl() ?>" alt="<?php echo $user->name ?>">
</a>
</li>
<?php endforeach ?>
</ul>
<?php endif ?>
</div>
<!-- todo: control -->
<div class="sidebar-unit options">
<h1>options</h1>
<nav>
<ul>
<?php if (PrivilegesHelper::confirm($this->context->user, Privilege::FavoritePost)): ?>
<?php if (!$this->context->favorite): ?>
<li class="add-fav">
<a href="<?php echo \Chibi\UrlHelper::route('post', 'add-favorite', ['id' => $this->context->transport->post->id]) ?>">
Add to favorites
</a>
</li>
<?php else: ?>
<li class="rem-fav">
<a href="<?php echo \Chibi\UrlHelper::route('post', 'rem-favorite', ['id' => $this->context->transport->post->id]) ?>">
Remove from favorites
</a>
</li>
<?php endif ?>
<?php endif ?>
<!--
<li>
<a href="#">
Edit tags
</a>
</li>
<li>
<a href="#">
Change safety
</a>
</li>
<li>
<a href="#">
Show on main page
</a>
</li>
<li>
<a href="#">
Hide from main page
</a>
</li>
<li>
<a href="#">
Remove
</a>
</li>
-->
</ul>
</nav>
<script type="text/javascript">
if (!$('.options ul li').length)
$('.options').hide();
</script>
</div>
</div>
<div id="inner-content">

View file

@ -8,18 +8,32 @@ define('DS', DIRECTORY_SEPARATOR);
function configFactory()
{
$config = new \Chibi\Config();
$configPaths =
[
__DIR__ . DS . '../config.ini',
__DIR__ . DS . '../local.ini'
];
$configPaths = array_filter($configPaths, 'file_exists');
static $config = null;
foreach ($configPaths as $path)
if ($config === null)
{
$config->loadIni($path);
}
$config = new \Chibi\Config();
$configPaths =
[
__DIR__ . DS . '../config.ini',
__DIR__ . DS . '../local.ini'
];
$configPaths = array_filter($configPaths, 'file_exists');
foreach ($configPaths as $path)
{
$config->loadIni($path);
}
}
return $config;
}
$config = configFactory();
R::setup('sqlite:' . $config->main->dbPath);
//wire models
\Chibi\AutoLoader::init([$config->chibi->userCodeDir, __DIR__]);
foreach (\Chibi\AutoLoader::getAllIncludablePaths() as $path)
if (preg_match('/Model/', $path))
\Chibi\AutoLoader::safeInclude($path);