Top users page. SQL queries optimization.
This commit is contained in:
parent
f19efe8ca1
commit
ce0b6e856f
|
@ -25,7 +25,7 @@
|
||||||
{% block header_navbar_menus %}
|
{% block header_navbar_menus %}
|
||||||
<ul class="nav navbar-nav">
|
<ul class="nav navbar-nav">
|
||||||
<li><a href="{{ path('index') }}"><span class="glyphicon glyphicon-home"></span> {{ 'Main'|trans }}</a></li>
|
<li><a href="{{ path('index') }}"><span class="glyphicon glyphicon-home"></span> {{ 'Main'|trans }}</a></li>
|
||||||
<li><a href="{{ path('users_top') }}"><span class="glyphicon glyphicon-stats"></span> TOP</a></li>
|
<li><a href="{{ path('users_top') }}"><span class="glyphicon glyphicon-stats"></span> {{ 'Top'|trans }}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,9 +2,10 @@
|
||||||
|
|
||||||
namespace Skobkin\Bundle\PointToolsBundle\Controller;
|
namespace Skobkin\Bundle\PointToolsBundle\Controller;
|
||||||
|
|
||||||
use Doctrine\DBAL\Query\QueryBuilder;
|
use Doctrine\ORM\QueryBuilder;
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
|
||||||
|
use Skobkin\Bundle\PointToolsBundle\Entity\TopUserDTO;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
use Skobkin\Bundle\PointToolsBundle\Entity\User;
|
||||||
use Skobkin\Bundle\PointToolsBundle\Service\UserApi;
|
use Skobkin\Bundle\PointToolsBundle\Service\UserApi;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
|
@ -12,7 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param
|
* @param User $user
|
||||||
* @ParamConverter("user", class="SkobkinPointToolsBundle:User", options={"login" = "login"})
|
* @ParamConverter("user", class="SkobkinPointToolsBundle:User", options={"login" = "login"})
|
||||||
*/
|
*/
|
||||||
public function showAction(User $user)
|
public function showAction(User $user)
|
||||||
|
@ -20,19 +21,30 @@ class UserController extends Controller
|
||||||
$userApi = $this->container->get('skobkin_point_tools.api_user');
|
$userApi = $this->container->get('skobkin_point_tools.api_user');
|
||||||
|
|
||||||
/** @var QueryBuilder $qb */
|
/** @var QueryBuilder $qb */
|
||||||
|
$qb = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:User')->createQueryBuilder('u');
|
||||||
|
|
||||||
|
$subscribers = $qb
|
||||||
|
->select('u')
|
||||||
|
->innerJoin('u.subscriptions', 's')
|
||||||
|
->where('s.author = :author')
|
||||||
|
->setParameter('author', $user->getId())
|
||||||
|
->getQuery()->getResult()
|
||||||
|
;
|
||||||
|
|
||||||
$qb = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:SubscriptionEvent')->createQueryBuilder('se');
|
$qb = $this->getDoctrine()->getManager()->getRepository('SkobkinPointToolsBundle:SubscriptionEvent')->createQueryBuilder('se');
|
||||||
|
|
||||||
$subscriptionsEvents = $qb
|
$subscriptionsEvents = $qb
|
||||||
->select()
|
->select()
|
||||||
->where('se.author = :author')
|
->where('se.author = :author')
|
||||||
->orderBy('se.date', 'desc')
|
->orderBy('se.date', 'desc')
|
||||||
->setMaxResults(30)
|
->setMaxResults(10)
|
||||||
->setParameter('author', $user)
|
->setParameter('author', $user)
|
||||||
->getQuery()->getResult()
|
->getQuery()->getResult()
|
||||||
;
|
;
|
||||||
|
|
||||||
return $this->render('SkobkinPointToolsBundle:User:show.html.twig', [
|
return $this->render('SkobkinPointToolsBundle:User:show.html.twig', [
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
|
'subscribers' => $subscribers,
|
||||||
'log' => $subscriptionsEvents,
|
'log' => $subscriptionsEvents,
|
||||||
'avatar_url' => $userApi->getAvatarUrl($user, UserApi::AVATAR_SIZE_LARGE),
|
'avatar_url' => $userApi->getAvatarUrl($user, UserApi::AVATAR_SIZE_LARGE),
|
||||||
]);
|
]);
|
||||||
|
@ -44,8 +56,20 @@ class UserController extends Controller
|
||||||
$em = $this->getDoctrine()->getManager();
|
$em = $this->getDoctrine()->getManager();
|
||||||
|
|
||||||
/** @var QueryBuilder $qb */
|
/** @var QueryBuilder $qb */
|
||||||
$qb = $em->getRepository('SkobkinPointToolsBundle:Subscription')->createQueryBuilder('us');
|
$qb = $em->getRepository('SkobkinPointToolsBundle:Subscription')->createQueryBuilder('s');
|
||||||
|
|
||||||
|
/** @var TopUserDTO[] $topUsers */
|
||||||
|
$topUsers = $qb
|
||||||
|
->select(['COUNT(s.subscriber) as cnt', 'NEW SkobkinPointToolsBundle:TopUserDTO(a.login, COUNT(s.subscriber))'])
|
||||||
|
->innerJoin('s.author', 'a')
|
||||||
|
->orderBy('cnt', 'desc')
|
||||||
|
->groupBy('a.id')
|
||||||
|
->setMaxResults(30)
|
||||||
|
->getQuery()->getResult()
|
||||||
|
;
|
||||||
|
|
||||||
|
return $this->render('@SkobkinPointTools/User/top.html.twig', [
|
||||||
|
'top_users' => $topUsers
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
src/Skobkin/Bundle/PointToolsBundle/Entity/TopUserDTO.php
Normal file
25
src/Skobkin/Bundle/PointToolsBundle/Entity/TopUserDTO.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Skobkin\Bundle\PointToolsBundle\Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Transfer Object for top users list
|
||||||
|
*/
|
||||||
|
class TopUserDTO
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $login;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $subscribersCount;
|
||||||
|
|
||||||
|
public function __construct($login, $subscribersCount)
|
||||||
|
{
|
||||||
|
$this->login = $login;
|
||||||
|
$this->subscribersCount = $subscribersCount;
|
||||||
|
}
|
||||||
|
}
|
|
@ -21,8 +21,8 @@
|
||||||
<div id="collapse-subscribers" class="panel-collapse collapse in">
|
<div id="collapse-subscribers" class="panel-collapse collapse in">
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<ul class="users mosaic">
|
<ul class="users mosaic">
|
||||||
{% for sub in user.subscribers %}
|
{% for user in subscribers %}
|
||||||
<li><a href="{{ url('user_show', {login: sub.subscriber.login}) }}">@{{ sub.subscriber.login }}</a></li>
|
<li><a href="{{ url('user_show', {login: user.login}) }}">@{{ user.login }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
{% extends "::base.html.twig" %}
|
||||||
|
|
||||||
|
{% block header_title %}Top @ Point Tools{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ 'Top users'|trans }}</h1>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>{{ 'User'|trans }}</td>
|
||||||
|
<td>{{ 'Subscribers count'|trans }}</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for user in top_users %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{ url('user_show', {login: user.login}) }}">@{{ user.login }}</a></td>
|
||||||
|
<td>{{ user.subscribersCount }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue