Favorites; gravatar support
This commit is contained in:
parent
67dcc7c4f8
commit
7c5d1b7e34
10 changed files with 244 additions and 39 deletions
|
@ -44,6 +44,7 @@ listPosts=anonymous
|
||||||
listPosts.sketchy=registered
|
listPosts.sketchy=registered
|
||||||
listPosts.unsafe=registered
|
listPosts.unsafe=registered
|
||||||
listUsers=registered
|
listUsers=registered
|
||||||
|
favoritePost=registered
|
||||||
listComments=registered
|
listComments=registered
|
||||||
retrievePost=anonymous
|
retrievePost=anonymous
|
||||||
listTags=anonymous
|
listTags=anonymous
|
||||||
|
|
|
@ -87,8 +87,8 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar .sidebar-unit {
|
#sidebar .sidebar-unit {
|
||||||
margin: 0 0 2em 0;
|
margin: 0 0 1.5em 0;
|
||||||
padding: 1em;
|
padding: 0.75em;
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#sidebar {
|
#sidebar {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
|
line-height: 1.33em;
|
||||||
|
font-size: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-wrapper {
|
.post-wrapper {
|
||||||
|
@ -71,9 +73,24 @@ i.icon-dl {
|
||||||
content: ', ';
|
content: ', ';
|
||||||
}
|
}
|
||||||
|
|
||||||
.details {
|
|
||||||
line-height: 1.33em;
|
|
||||||
}
|
|
||||||
.details .key {
|
.details .key {
|
||||||
margin-right: 0.5em;
|
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;
|
||||||
|
}
|
||||||
|
|
20
public_html/media/js/post-view.js
Normal file
20
public_html/media/js/post-view.js
Normal 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -24,7 +24,6 @@ class Bootstrap
|
||||||
public function workWrapper($workCallback)
|
public function workWrapper($workCallback)
|
||||||
{
|
{
|
||||||
$this->config->chibi->baseUrl = 'http://' . rtrim($_SERVER['HTTP_HOST'], '/') . '/';
|
$this->config->chibi->baseUrl = 'http://' . rtrim($_SERVER['HTTP_HOST'], '/') . '/';
|
||||||
R::setup('sqlite:' . $this->config->main->dbPath);
|
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
$this->context->title = $this->config->main->title;
|
$this->context->title = $this->config->main->title;
|
||||||
|
|
|
@ -188,10 +188,11 @@ class PostController
|
||||||
$dbPost->mime_type = $mimeType;
|
$dbPost->mime_type = $mimeType;
|
||||||
$dbPost->safety = $suppliedSafety;
|
$dbPost->safety = $suppliedSafety;
|
||||||
$dbPost->upload_date = time();
|
$dbPost->upload_date = time();
|
||||||
$dbPost->sharedTag = $dbTags;
|
|
||||||
$dbPost->user = $this->context->user;
|
|
||||||
$dbPost->image_width = $imageWidth;
|
$dbPost->image_width = $imageWidth;
|
||||||
$dbPost->image_height = $imageHeight;
|
$dbPost->image_height = $imageHeight;
|
||||||
|
$dbPost->uploader = $this->context->user;
|
||||||
|
$dbPost->ownFavoritee = [];
|
||||||
|
$dbPost->sharedTag = $dbTags;
|
||||||
|
|
||||||
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
move_uploaded_file($suppliedFile['tmp_name'], $path);
|
||||||
R::store($dbPost);
|
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)
|
public function viewAction($id)
|
||||||
{
|
{
|
||||||
$post = R::findOne('post', 'id = ?', [$id]);
|
$post = self::locatePost($id);
|
||||||
if (!$post)
|
R::preload($post, ['favoritee' => 'user', 'uploader' => 'user', 'tag']);
|
||||||
throw new SimpleException('Invalid post ID "' . $id . '"');
|
|
||||||
R::preload($post, ['user', 'tag']);
|
|
||||||
|
|
||||||
$prevPost = R::findOne('post', 'id < ? ORDER BY id DESC LIMIT 1', [$id]);
|
$prevPost = R::findOne('post', 'id < ? ORDER BY id DESC LIMIT 1', [$id]);
|
||||||
$nextPost = R::findOne('post', 'id > ? ORDER BY id ASC 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);
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
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 = R::$f->begin();
|
||||||
$dbQuery->select('tag.name, COUNT(1) AS count');
|
$dbQuery->select('tag.name, COUNT(1) AS count');
|
||||||
$dbQuery->from('tag');
|
$dbQuery->from('tag');
|
||||||
|
@ -234,9 +287,10 @@ class PostController
|
||||||
$this->context->transport->tagDistribution[$row['name']] = $row['count'];
|
$this->context->transport->tagDistribution[$row['name']] = $row['count'];
|
||||||
|
|
||||||
$this->context->stylesheets []= 'post-view.css';
|
$this->context->stylesheets []= 'post-view.css';
|
||||||
|
$this->context->scripts []= 'post-view.js';
|
||||||
$this->context->subTitle = 'showing @' . $post->id;
|
$this->context->subTitle = 'showing @' . $post->id;
|
||||||
|
$this->context->favorite = $favorite;
|
||||||
$this->context->transport->post = $post;
|
$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->prevPostId = $prevPost ? $prevPost->id : null;
|
||||||
$this->context->transport->nextPostId = $nextPost ? $nextPost->id : null;
|
$this->context->transport->nextPostId = $nextPost ? $nextPost->id : null;
|
||||||
}
|
}
|
||||||
|
@ -250,10 +304,7 @@ class PostController
|
||||||
public function thumbAction($id)
|
public function thumbAction($id)
|
||||||
{
|
{
|
||||||
$this->context->layoutName = 'layout-file';
|
$this->context->layoutName = 'layout-file';
|
||||||
|
$post = self::locatePost($id);
|
||||||
$post = R::findOne('post', 'id = ?', [$id]);
|
|
||||||
if (!$post)
|
|
||||||
throw new SimpleException('Invalid post ID "' . $id . '"');
|
|
||||||
|
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost);
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::ViewPost, PostSafety::toString($post->safety));
|
||||||
|
@ -324,10 +375,7 @@ class PostController
|
||||||
public function retrieveAction($name)
|
public function retrieveAction($name)
|
||||||
{
|
{
|
||||||
$this->context->layoutName = 'layout-file';
|
$this->context->layoutName = 'layout-file';
|
||||||
|
$post = self::locatePost($name);
|
||||||
$post = R::findOne('post', 'name = ?', [$name]);
|
|
||||||
if (!$post)
|
|
||||||
throw new SimpleException('Invalid post name "' . $name . '"');
|
|
||||||
|
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost);
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost);
|
||||||
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost, PostSafety::toString($post->safety));
|
PrivilegesHelper::confirmWithException($this->context->user, Privilege::RetrievePost, PostSafety::toString($post->safety));
|
||||||
|
@ -354,4 +402,21 @@ class PostController
|
||||||
$this->listAction('favmin:1', $page);
|
$this->listAction('favmin:1', $page);
|
||||||
$this->context->viewName = 'post-list';
|
$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
13
src/Models/Model_User.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,7 +5,8 @@ class Privilege extends Enum
|
||||||
const UploadPost = 2;
|
const UploadPost = 2;
|
||||||
const ViewPost = 3;
|
const ViewPost = 3;
|
||||||
const RetrievePost = 4;
|
const RetrievePost = 4;
|
||||||
const ListUsers = 5;
|
const FavoritePost = 5;
|
||||||
const ListComments = 6;
|
const ListUsers = 6;
|
||||||
const ListTags = 7;
|
const ListComments = 7;
|
||||||
|
const ListTags = 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="sidebar-unit tags">
|
<div class="sidebar-unit tags">
|
||||||
<h1>tags</h1>
|
<h1>tags (<?php echo count($this->context->transport->post->sharedTag) ?>)</h1>
|
||||||
<!-- todo: edit tags -->
|
<!-- todo: edit tags -->
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach ($this->context->transport->post->sharedTag as $tag): ?>
|
<?php foreach ($this->context->transport->post->sharedTag as $tag): ?>
|
||||||
|
@ -57,8 +57,8 @@
|
||||||
<div class="uploader">
|
<div class="uploader">
|
||||||
<span class="key">Uploader:</span>
|
<span class="key">Uploader:</span>
|
||||||
<span class="value">
|
<span class="value">
|
||||||
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['id' => $this->context->transport->post->user->id]) ?>">
|
<a href="<?php echo \Chibi\UrlHelper::route('user', 'view', ['name' => $this->context->transport->post->uploader->id]) ?>">
|
||||||
<?php echo $this->context->transport->post->user->name ?>
|
<?php echo $this->context->transport->post->uploader->name ?>
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,9 +90,84 @@
|
||||||
</div>
|
</div>
|
||||||
</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>
|
||||||
|
|
||||||
<div id="inner-content">
|
<div id="inner-content">
|
||||||
|
|
14
src/core.php
14
src/core.php
|
@ -8,6 +8,10 @@ define('DS', DIRECTORY_SEPARATOR);
|
||||||
|
|
||||||
function configFactory()
|
function configFactory()
|
||||||
{
|
{
|
||||||
|
static $config = null;
|
||||||
|
|
||||||
|
if ($config === null)
|
||||||
|
{
|
||||||
$config = new \Chibi\Config();
|
$config = new \Chibi\Config();
|
||||||
$configPaths =
|
$configPaths =
|
||||||
[
|
[
|
||||||
|
@ -21,5 +25,15 @@ function configFactory()
|
||||||
$config->loadIni($path);
|
$config->loadIni($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return $config;
|
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);
|
||||||
|
|
Loading…
Reference in a new issue