Public feed implemented.
This commit is contained in:
parent
988ac34752
commit
c0ea97e8f9
|
@ -25,6 +25,7 @@
|
|||
{% block header_navbar_menus %}
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="{{ path('index') }}"><span class="glyphicon glyphicon-home"></span> {{ 'Main'|trans }}</a></li>
|
||||
<li><a href="{{ path('feed_public') }}"><span class="glyphicon glyphicon-bullhorn"></span> {{ 'Public feed'|trans }}</a></li>
|
||||
<li><a href="{{ path('statistics') }}"><span class="glyphicon glyphicon-stats"></span> {{ 'Statistics'|trans }}</a></li>
|
||||
<li><a href="{{ path('events_last') }}"><span class="glyphicon glyphicon-th-list"></span> {{ 'Last'|trans }}</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
|
||||
namespace Skobkin\Bundle\PointToolsBundle\Controller;
|
||||
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\Blogs\Post;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class PublicFeedController extends Controller
|
||||
{
|
||||
private const POSTS_PER_PAGE = 20;
|
||||
|
||||
public function indexAction(Request $request)
|
||||
{
|
||||
// @todo autowire
|
||||
$postRepository = $this->getDoctrine()->getRepository(Post::class);
|
||||
|
||||
$paginator = $this->get('knp_paginator');
|
||||
|
||||
$postsPagination = $paginator->paginate(
|
||||
$postRepository->createPublicFeedPostsQuery(),
|
||||
$request->query->getInt('page', 1),
|
||||
self::POSTS_PER_PAGE
|
||||
);
|
||||
|
||||
return $this->render(
|
||||
'SkobkinPointToolsBundle:Post:feed.html.twig',
|
||||
[
|
||||
// @todo Move to translation
|
||||
'feed_title' => 'All',
|
||||
'posts' => $postsPagination,
|
||||
// Special feed mark (to not show comments and other)
|
||||
'is_feed' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
|
@ -3,13 +3,11 @@
|
|||
namespace Skobkin\Bundle\PointToolsBundle\Controller;
|
||||
|
||||
use Doctrine\ORM\EntityManager;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\DailyEvents;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\TopUserDTO;
|
||||
use Skobkin\Bundle\PointToolsBundle\DTO\{DailyEvents, TopUserDTO};
|
||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||
use Ob\HighchartsBundle\Highcharts\Highchart;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\{Request, Response};
|
||||
|
||||
class UserController extends Controller
|
||||
{
|
||||
|
|
|
@ -89,7 +89,7 @@ class Post
|
|||
private $files;
|
||||
|
||||
/**
|
||||
* @var Tag[]|ArrayCollection
|
||||
* @var PostTag[]|ArrayCollection
|
||||
*
|
||||
* @ORM\OneToMany(targetEntity="Skobkin\Bundle\PointToolsBundle\Entity\Blogs\PostTag", mappedBy="post", fetch="EXTRA_LAZY", cascade={"persist"}, orphanRemoval=true)
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@ class PostRepository extends EntityRepository
|
|||
{
|
||||
/** @var QueryBuilder $qb */
|
||||
$qb = $this->createQueryBuilder('p');
|
||||
|
||||
return $qb
|
||||
->select(['p', 'c', 'a'])
|
||||
->leftJoin('p.comments', 'c')
|
||||
|
@ -28,4 +29,19 @@ class PostRepository extends EntityRepository
|
|||
->getQuery()->getOneOrNullResult()
|
||||
;
|
||||
}
|
||||
|
||||
public function createPublicFeedPostsQuery(): QueryBuilder
|
||||
{
|
||||
$qb = $this->createQueryBuilder('p');
|
||||
|
||||
return $qb
|
||||
// @todo optimize hydration
|
||||
->select(['p', 'pa', 'pt', 'pf'])
|
||||
->innerJoin('p.author', 'pa')
|
||||
->leftJoin('p.postTags', 'pt')
|
||||
->leftJoin('p.files', 'pf')
|
||||
->where('p.private = FALSE')
|
||||
->andWhere('pa.public = TRUE')
|
||||
;
|
||||
}
|
||||
}
|
|
@ -36,6 +36,11 @@ events_last:
|
|||
defaults: { _controller: SkobkinPointToolsBundle:Events:last }
|
||||
methods: [GET]
|
||||
|
||||
feed_public:
|
||||
path: /posts/all
|
||||
defaults: { _controller: SkobkinPointToolsBundle:PublicFeed:index }
|
||||
methods: [GET]
|
||||
|
||||
post_show:
|
||||
path: /{id}
|
||||
defaults: { _controller: SkobkinPointToolsBundle:Post:show }
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
# Header
|
||||
Toggle navigation: Переключить навигацию
|
||||
Main: Главная
|
||||
Public feed: Публичная лента
|
||||
Statistics: Статистика
|
||||
Report a bug: Сообщить об ошибке
|
||||
Telegram Bot: Бот в Telegram
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{% extends "::base.html.twig" %}
|
||||
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
<link href="{{ asset('css/lib/magnific-popup.css') }}" rel="stylesheet">
|
||||
{% endblock %}
|
||||
{% block footer_js %}
|
||||
{{ parent() }}
|
||||
<script src="{{ asset('js/lib/jquery.magnific-popup.min.js') }}"></script>
|
||||
<script src="{{ asset('js/popups.js') }}"></script>
|
||||
{% endblock %}
|
|
@ -0,0 +1,26 @@
|
|||
{% extends 'SkobkinPointToolsBundle:Post:base_feed.html.twig' %}
|
||||
|
||||
{% block header_title %}{{ feed_title }} @ Point Tools{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if is_feed is defined %}
|
||||
<div class="navigation">
|
||||
{{ knp_pagination_render(posts) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% for post in posts %}
|
||||
<div class="feed-post panel panel-default">
|
||||
{% include 'SkobkinPointToolsBundle:Post:post.html.twig' with {
|
||||
'post': post,
|
||||
'is_feed': is_feed
|
||||
} %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% if is_feed is defined %}
|
||||
<div class="navigation">
|
||||
{{ knp_pagination_render(posts) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -0,0 +1,47 @@
|
|||
<div class="container post-block">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
<img src="{{ point_avatar_large(post.author.login) }}" alt="Avatar">
|
||||
</div>
|
||||
<div class="col-xs-11">
|
||||
<div><a href="{{ path('user_show', {'login': post.author.login}) }}">@{{ post.author.login }}</a></div>
|
||||
<div class="post-date">{{ post.createdAt|date('j M Y G:i') }}</div>
|
||||
<div>
|
||||
{% for pt in post.postTags %}
|
||||
<span class="tag">{{ pt.text }}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row post-text">
|
||||
<div class="col-xs-12">
|
||||
{{ post.text|markdown('app.point.markdown_parser') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row post-files">
|
||||
<div class="col-xs-2">
|
||||
{% for file in post.files %}
|
||||
<div class="post-attachment">
|
||||
<a href="{{ file.remoteUrl }}" class="post-image"><img src="{{ file.remoteUrl }}" class="img-thumbnail" /></a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12"><a href="{{ post.id|point_post_url }}" class="post">#{{ post.id }}</a></div>
|
||||
</div>
|
||||
|
||||
{% if is_feed is defined and post.comments|length > 0 %}
|
||||
<div class="row comments">
|
||||
{#
|
||||
{% include '@SkobkinPointTools/Post/comments_tree.html.twig' with {
|
||||
'comments': post.firstLevelComments
|
||||
} only %}
|
||||
#}
|
||||
|
||||
{% include 'SkobkinPointToolsBundle:Post:comments_list.html.twig' with {
|
||||
'comments': post.comments
|
||||
} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
|
@ -1,63 +1,7 @@
|
|||
{% extends "::base.html.twig" %}
|
||||
|
||||
{% block css %}
|
||||
{{ parent() }}
|
||||
<link href="{{ asset('css/lib/magnific-popup.css') }}" rel="stylesheet">
|
||||
{% endblock %}
|
||||
{% block footer_js %}
|
||||
{{ parent() }}
|
||||
<script src="{{ asset('js/lib/jquery.magnific-popup.min.js') }}"></script>
|
||||
<script src="{{ asset('js/popups.js') }}"></script>
|
||||
{% endblock %}
|
||||
{% extends 'SkobkinPointToolsBundle:Post:base_feed.html.twig' %}
|
||||
|
||||
{% block header_title %}#{{ post.id }} @ Point Tools{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container post-block">
|
||||
<div class="row">
|
||||
<div class="col-xs-1">
|
||||
<img src="{{ point_avatar_large(post.author.login) }}" alt="Avatar">
|
||||
</div>
|
||||
<div class="col-xs-11">
|
||||
<div><a href="{{ path('user_show', {'login': post.author.login}) }}">@{{ post.author.login }}</a></div>
|
||||
<div class="post-date">{{ post.createdAt|date('j M Y G:i') }}</div>
|
||||
<div>
|
||||
{% for pt in post.postTags %}
|
||||
<a href="#" class="tag">{{ pt.text }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row post-text">
|
||||
<div class="col-xs-12">
|
||||
{{ post.text|markdown('app.point.markdown_parser') }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row post-files">
|
||||
<div class="col-xs-2">
|
||||
{% for file in post.files %}
|
||||
<div class="post-attachment">
|
||||
<a href="{{ file.remoteUrl }}" class="post-image"><img src="{{ file.remoteUrl }}" class="img-thumbnail" /></a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12"><a href="{{ post.id|point_post_url }}" class="post">#{{ post.id }}</a></div>
|
||||
</div>
|
||||
|
||||
{% if post.comments|length > 0 %}
|
||||
<div class="row comments">
|
||||
{#
|
||||
{% include '@SkobkinPointTools/Post/comments_tree.html.twig' with {
|
||||
'comments': post.firstLevelComments
|
||||
} only %}
|
||||
#}
|
||||
|
||||
{% include '@SkobkinPointTools/Post/comments_list.html.twig' with {
|
||||
'comments': post.comments
|
||||
} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% include 'SkobkinPointToolsBundle:Post:post.html.twig' with {'post': post} %}
|
||||
{% endblock %}
|
||||
|
|
|
@ -106,7 +106,8 @@ ul.users.mosaic li:nth-child(odd) {
|
|||
color: red;
|
||||
}
|
||||
|
||||
a.tag {
|
||||
a.tag,
|
||||
span.tag {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
margin: .8em .8em 0 0;
|
||||
|
@ -117,6 +118,12 @@ a.tag {
|
|||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* Posts */
|
||||
|
||||
.feed-post {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.post-block .post-date {
|
||||
margin-top: 5px;
|
||||
color: #a0a0a0;
|
||||
|
|
Loading…
Reference in a new issue