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.unsafe=registered
|
||||
listUsers=registered
|
||||
favoritePost=registered
|
||||
listComments=registered
|
||||
retrievePost=anonymous
|
||||
listTags=anonymous
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
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)
|
||||
{
|
||||
$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;
|
||||
|
|
|
@ -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
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 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;
|
||||
}
|
||||
|
|
|
@ -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">
|
||||
|
|
34
src/core.php
34
src/core.php
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue