Merged in feature_users (pull request #4)

Simple user invtes interface.
This commit is contained in:
Alexey Eschenko 2018-06-28 19:24:23 +00:00
commit 719e552088
7 changed files with 84 additions and 10 deletions

View file

@ -23,6 +23,12 @@ user_register:
method: GET method: GET
inviteCode: \w{32} inviteCode: \w{32}
user_account_invites:
path: /account/invites
controller: App\Controller\AccountController::invites
requirements:
method: GET
user_login: user_login:
path: /login path: /login
controller: App\Controller\SecurityController::login controller: App\Controller\SecurityController::login

View file

@ -0,0 +1,23 @@
<?php
namespace App\Controller;
use App\Entity\User;
use App\Repository\InviteRepository;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class AccountController extends Controller
{
public function invites(InviteRepository $inviteRepo): Response
{
/** @var User $user */
if (null === $user = $this->getUser()) {
throw $this->createAccessDeniedException('User not found exception');
}
return $this->render('Account/invites.html.twig', [
'invites' => $inviteRepo->findInvitesByUser($user),
]);
}
}

View file

@ -22,7 +22,7 @@ class Invite
/** /**
* @var User * @var User
* *
* @ORM\ManyToOne(targetEntity="App\Entity\User") * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="invites")
* @ORM\JoinColumn(name="user_id", nullable=false) * @ORM\JoinColumn(name="user_id", nullable=false)
*/ */
private $user; private $user;

View file

@ -2,7 +2,7 @@
namespace App\Repository; namespace App\Repository;
use App\Entity\Invite; use App\Entity\{Invite, User};
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Bridge\Doctrine\RegistryInterface; use Symfony\Bridge\Doctrine\RegistryInterface;
@ -17,4 +17,16 @@ class InviteRepository extends ServiceEntityRepository
{ {
$this->getEntityManager()->persist($invite); $this->getEntityManager()->persist($invite);
} }
/** @return Invite[] */
public function findInvitesByUser(User $user): iterable
{
$qb = $this->createQueryBuilder('i');
$qb
->select(['i', 'uu'])
->leftJoin('i.usedBy', 'uu')
;
return $qb->getQuery()->getResult();
}
} }

View file

@ -0,0 +1,30 @@
{% extends 'base.html.twig' %}
{% block content %}
<h1>Your invites</h1>
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th><i class="icon-external-link"></i></th>
</tr>
</thead>
<tbody>
{# @var invite \App\Entity\Invite #}
{% for invite in invites %}
<tr>
<th scope="row">{{ loop.index }}</th>
<td>
{% if invite.usedBy %}
Used by <strong>{{ invite.usedBy.username }}</strong>.
{% else %}
{% set invite_url = url('user_register', { inviteCode: invite.code }) %}
<input class="form-control" type="url" value="{{ invite_url }}" readonly="readonly" onclick="this.select()">
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -13,6 +13,8 @@
{% block css %} {% block css %}
<!-- Bootstrap core CSS --> <!-- Bootstrap core CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet"> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet">
<!-- Font Awesome -->
<link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.css" rel="stylesheet">
<link href="/css/style.css" rel="stylesheet"> <link href="/css/style.css" rel="stylesheet">
{% endblock %} {% endblock %}
</head> </head>
@ -20,7 +22,7 @@
<body> <body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"> <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="{{ path('index') }}">Magnetico Web</a> <a class="navbar-brand" href="{{ path('index') }}"><i class="icon-magnet"></i> Magnetico Search</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation"> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>
@ -30,10 +32,11 @@
<ul class="navbar-nav mr-auto"> <ul class="navbar-nav mr-auto">
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a href="#" class="nav-link dropdown-toggle" role="button" data-toggle="dropdown"> <a href="#" class="nav-link dropdown-toggle" role="button" data-toggle="dropdown">
{{ app.user.username }} <i class="icon-user"></i> {{ app.user.username }}
</a> </a>
<div class="dropdown-menu"> <div class="dropdown-menu">
<a href="{{ path('user_logout') }}" class="dropdown-item">Logout</a> <a href="{{ path('user_account_invites') }}" class="dropdown-item"><i class="icon-group"></i> Invites</a>
<a href="{{ path('user_logout') }}" class="dropdown-item"><i class="icon-signout"></i> Logout</a>
</div> </div>
</li> </li>
</ul> </ul>
@ -42,7 +45,7 @@
<form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get"> <form class="form-inline my-2 my-lg-0" action="{{ path('torrents_search') }}" method="get">
<input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" <input name="query" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search"
value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}"> value="{% if searchQuery is defined %}{{ searchQuery }}{% endif %}">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> <button class="btn btn-outline-success my-2 my-sm-0" type="submit"><i class="icon-search"></i> Search</button>
</form> </form>
{% endif %} {% endif %}
</div> </div>
@ -53,10 +56,10 @@
</main><!-- /.container --> </main><!-- /.container -->
{% block javascript %} {% block javascript %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script> <script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="../../assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View file

@ -3,7 +3,7 @@
{% block content %} {% block content %}
<div class="well"> <div class="well">
{% if not is_granted('ROLE_USER') %} {% if not is_granted('ROLE_USER') %}
<a href="{{ path('user_login') }}" class="btn btn-lg btn-primary">Login</a> <a href="{{ path('user_login') }}" class="btn btn-lg btn-primary"><i class="icon-signin"></i> Login</a>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}