Top users page. SQL queries optimization.

This commit is contained in:
Alexey Skobkin 2015-05-31 09:16:10 +03:00
parent f19efe8ca1
commit ce0b6e856f
5 changed files with 80 additions and 7 deletions

View File

@ -25,7 +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('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>
{% endblock %}
</div>

View File

@ -2,9 +2,10 @@
namespace Skobkin\Bundle\PointToolsBundle\Controller;
use Doctrine\DBAL\Query\QueryBuilder;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\EntityManager;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Skobkin\Bundle\PointToolsBundle\Entity\TopUserDTO;
use Skobkin\Bundle\PointToolsBundle\Entity\User;
use Skobkin\Bundle\PointToolsBundle\Service\UserApi;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
@ -12,7 +13,7 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class UserController extends Controller
{
/**
* @param
* @param User $user
* @ParamConverter("user", class="SkobkinPointToolsBundle:User", options={"login" = "login"})
*/
public function showAction(User $user)
@ -20,19 +21,30 @@ class UserController extends Controller
$userApi = $this->container->get('skobkin_point_tools.api_user');
/** @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');
$subscriptionsEvents = $qb
->select()
->where('se.author = :author')
->orderBy('se.date', 'desc')
->setMaxResults(30)
->setMaxResults(10)
->setParameter('author', $user)
->getQuery()->getResult()
;
return $this->render('SkobkinPointToolsBundle:User:show.html.twig', [
'user' => $user,
'subscribers' => $subscribers,
'log' => $subscriptionsEvents,
'avatar_url' => $userApi->getAvatarUrl($user, UserApi::AVATAR_SIZE_LARGE),
]);
@ -44,8 +56,20 @@ class UserController extends Controller
$em = $this->getDoctrine()->getManager();
/** @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
]);
}
}

View 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;
}
}

View File

@ -21,8 +21,8 @@
<div id="collapse-subscribers" class="panel-collapse collapse in">
<div class="panel-body">
<ul class="users mosaic">
{% for sub in user.subscribers %}
<li><a href="{{ url('user_show', {login: sub.subscriber.login}) }}">@{{ sub.subscriber.login }}</a></li>
{% for user in subscribers %}
<li><a href="{{ url('user_show', {login: user.login}) }}">@{{ user.login }}</a></li>
{% endfor %}
</ul>
</div>

View File

@ -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 %}