use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Exception\OutOfRangeCurrentPageException;
+use Pagerfanta\Pagerfanta;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Form\Type\EditGroupSharesType;
use Wallabag\CoreBundle\Form\Type\EntryFilterType;
use Wallabag\CoreBundle\Form\Type\EditEntryType;
use Wallabag\CoreBundle\Form\Type\NewEntryType;
use Wallabag\CoreBundle\Event\EntrySavedEvent;
use Wallabag\CoreBundle\Event\EntryDeletedEvent;
use Wallabag\CoreBundle\Form\Type\SearchEntryType;
+use Wallabag\GroupBundle\Entity\Group;
class EntryController extends Controller
{
{
return $this->showEntries('untagged', $request, $page);
}
+
+ /**
+ * @Route("/group-articles/{group}/{page}", name="group-presentations", defaults={"page" = "1"}, requirements={"page": "\d+", "group": "\d+"})
+ *
+ * @param Request $request
+ * @param Group $group
+ * @param int $page
+ * @return Response
+ */
+ public function showGroupSharedTemplatesAction(Request $request, Group $group, int $page)
+ {
+ if (!$this->getUser()->inGroup($group)) {
+ throw $this->createAccessDeniedException();
+ }
+
+ $repository = $this->get('wallabag_core.entry_repository');
+
+ /** @var QueryBuilder $entries */
+ $entries = $repository->findByGroup($group->getId());
+
+ $pagerAdapter = new DoctrineORMAdapter($entries->getQuery(), true, false);
+ $pagerFanta = new Pagerfanta($pagerAdapter);
+ $pagerFanta->setMaxPerPage(9);
+
+ $form = $this->createForm(EntryFilterType::class);
+
+ if ($request->query->has($form->getName())) {
+ // manually bind values from the request
+ $form->submit($request->query->get($form->getName()));
+
+ // build the query from the given form object
+ $this->get('lexik_form_filter.query_builder_updater')->addFilterConditions($form, $qb);
+ }
+
+ $searchTerm = (isset($request->get('search_entry')['term']) ? $request->get('search_entry')['term'] : '');
+
+ try {
+ $pagerFanta->setCurrentPage($page);
+ } catch (OutOfRangeCurrentPageException $e) {
+ if ($page > 1) {
+ return $this->redirect($this->generateUrl('group-presentations', [
+ 'page' => $pagerFanta->getNbPages(),
+ 'group' => $group->getId()
+ ]), 302);
+ }
+ }
+
+ return $this->render('WallabagCoreBundle:Entry:entries.html.twig', [
+ 'form' => $form->createView(),
+ 'entries' => $pagerFanta,
+ 'currentPage' => $page,
+ 'searchTerm' => $searchTerm,
+ ]);
+ }
+
+ /**
+ *
+ * @Route("/entry/group-shares/{entry}", name="group-shares-entry")
+ *
+ * @param Request $request
+ * @param Entry $entry
+ * @return Response
+ */
+ public function groupShareAction(Request $request, Entry $entry)
+ {
+ $this->checkUserAction($entry);
+
+ $form = $this->createForm(EditGroupSharesType::class, $entry, ['groups' => $this->getUser()->getGroups()]);
+
+ $form->handleRequest($request);
+
+ if ($form->isSubmitted() && $form->isValid()) {
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($entry);
+ $em->flush();
+
+ return $this->redirect($this->generateUrl('view', ['id' => $entry->getId()]));
+ }
+
+ return $this->render('WallabagCoreBundle:Entry:_share_groups.html.twig', [
+ 'form' => $form->createView(),
+ 'entry' => $entry,
+ ]);
+ }
}
*
* @Route("/export/{category}.{format}", name="export_entries", requirements={
* "format": "epub|mobi|pdf|json|xml|txt|csv",
- * "category": "all|unread|starred|archive|tag_entries|untagged|search"
+ * "category": "all|unread|starred|archive|tag_entries|untagged|search|group-presentations"
* })
*
* @return \Symfony\Component\HttpFoundation\Response
/**
* @var ArrayCollection
- * @ORM\ManyToMany(targetEntity="Wallabag\GroupBundle\Entity\Group", inversedBy="presentations", cascade={"persist"})
+ * @ORM\ManyToMany(targetEntity="Wallabag\GroupBundle\Entity\Group", inversedBy="entries", cascade={"persist"})
*/
private $groupShares;
return $this;
}
+
+ /**
+ * @return ArrayCollection
+ */
+ public function getGroupShares()
+ {
+ return $this->groupShares;
+ }
+
+ /**
+ * @param ArrayCollection $groupShares
+ */
+ public function setGroupShares($groupShares)
+ {
+ $this->groupShares = $groupShares;
+ }
}
--- /dev/null
+<?php
+
+namespace Wallabag\CoreBundle\Form\Type;
+
+use Symfony\Bridge\Doctrine\Form\Type\EntityType;
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\GroupBundle\Entity\Group;
+
+class EditGroupSharesType extends AbstractType
+{
+ public function buildForm(FormBuilderInterface $builder, array $options)
+ {
+ $builder
+ ->add('groupshares', EntityType::class, [
+ 'required' => true,
+ 'class' => Group::class,
+ 'choices' => $options['groups'],
+ 'multiple' => true,
+ 'expanded' => true,
+ ])
+ ->add('save', SubmitType::class, [
+ 'label' => 'Share',
+ ])
+ ;
+ }
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver->setDefaults([
+ 'data_class' => Entry::class,
+ ]);
+ $resolver->setRequired('groups');
+ }
+
+ public function getBlockPrefix()
+ {
+ return 'group_shares';
+ }
+}
->getQuery()
->getResult();
}
+
+ /**
+ * Find all entries for a group
+ *
+ * @param $groupId
+ * @return \Doctrine\ORM\QueryBuilder
+ */
+ public function findByGroup($groupId)
+ {
+ return $this->createQueryBuilder('p')
+ ->innerJoin('p.groupShares', 'g', 'WITH', 'g.id = :group')
+ ->setParameter(':group', $groupId);
+ }
}
delete_public_link: 'delete public link'
export: 'Export'
print: 'Print'
+ groups: Groups
problem:
label: 'Problems?'
description: 'Does this article appear wrong?'
delete: Delete
delete_confirm: Are you sure?
back_to_list: Back to list
+ role_label: Default roles
+ access_label: Access
+ password_label: Password (if applicable)
+
+ roles:
+ readonly: Read only
+ write: Write access
+ manage_entries: Managing articles
+ manage_users: Managing members
+ admin: Administrator
+ access:
+ open: Open
+ request: On request
+ password: With password
+ invitation: Upon invitation
+ hidden: Upon invitation and private
+ tab_menu:
+ public: Public groups
+ own: My groups
+ manage:
+ label: Manage this group
+ entries:
+ label: Entries shared with this group
+ leave:
+ label: Leave
user:
page_title: Users management
delete_public_link: "Supprimer le lien public"
export: "Exporter"
print: "Imprimer"
+ groups: Groupes
problem:
label: "Un problème ?"
description: "Est-ce que cet article s’affiche mal ?"
tab_menu:
public: Groupes publics
own: Mes groupes
+ requests:
+ list: Liste des requêtes
+ sent: Requête envoyée
+ username: Utilisateur
+ action: Action
+ manage:
+ label: Gérer le groupe
+ title: Gérer le groupe
+ entries:
+ label: Liste des articles partagés avec ce groupe
+ leave:
+ label: Sortir de ce groupe
+ user:
+ inGroup: "{0}Il n'y a personne dans ce groupe|{1}Vous êtes tout seul dans ce groupe|]1,Inf[Vous êtes %count% utilisateurs dans ce groupe"
+ notInGroup: "{0}Il n'y a personne dans ce groupe|{1}Il y a un seul utilisateur dans ce groupe|]1,Inf[%count% utilisateurs dans ce groupe"
+ members:
+ empty: Le groupe est vide
+ name: Nom d'utilisateur
+ role: Rôle
+ action: Action
+ edit: Modifier les droits de l'utilisateur
+ exclude: Exclure l'utilisateur
+ edit_user:
+ title: Édition des droits de l'utilisateur
+ role: Rôle
+ cancel: Annuler
user:
page_title: "Gestion des utilisateurs"
--- /dev/null
+<!-- Groups Modal -->
+<div id="groups-modal" class="modal bottom-sheet">
+ <div class="modal-content">
+ <div class="row">
+ <h4>Groups</h4>
+ <p>Select the groups you want to share this article with</p>
+ <form name="search" method="POST" action="{{ path('group-shares-entry', {'entry': entry.id})}}">
+ {% if form_errors(form) %}
+ <span class="black-text">{{ form_errors(form) }}</span>
+ {% endif %}
+
+ {% if form_errors(form.groupshares) %}
+ <span class="black-text">{{ form_errors(form.groupshares) }}</span>
+ {% endif %}
+
+ {{ form_widget(form.groupshares) }}
+ {{ form_widget(form.save, {'attr': {'class': 'modal-action modal-close waves-effect waves-light btn'}}) }}
+
+ {{ form_rest(form) }}
+ </form>
+
+ </div>
+ </div>
+</div>
</div>
</li>
+ {#{% if craue_setting('groups') %}#}
+ <li class="bold border-bottom hide-on-med-and-down">
+ <a class="waves-effect groups-button" onclick="$('#groups-modal').openModal();" title="{{ 'entry.view.left_menu.group'|trans }}">
+ <i class="material-icons small">group</i>
+ <span>{{ 'entry.view.left_menu.groups'|trans }}</span>
+ </a>
+ </li>
+ {#{% endif %}#}
+
{% if craue_setting('show_printlink') %}
<li class="bold border-bottom hide-on-med-and-down">
<a class="waves-effect collapsible-header" title="{{ 'entry.view.left_menu.print'|trans }}" href="javascript: window.print();">
</div>
</div>
+ {{ render(controller( "WallabagCoreBundle:Entry:GroupShare", { 'entry': entry.id } )) }}
+
<script id="annotationroutes" type="application/json">
{
"prefix": "",
<li class="bold {% if currentRoute starts with 'user_' %}active{% endif %}">
<a class="waves-effect" href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a>
</li>
- <li class="bold {% if currentRoute starts with 'group_' %}active{% endif %}">
- <a class="waves-effect" href="{{ path('group_index') }}">{{ 'menu.left.groups_management'|trans }}</a>
- </li>
<li class="bold border-bottom {% if currentRoute == 'craue_config_settings_modify' %}active{% endif %}">
<a class="waves-effect" href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a>
</li>
{% endif %}
+ <li class="bold {% if currentRoute starts with 'group_' %}active{% endif %}">
+ <a class="waves-effect" href="{{ path('group_index') }}">{{ 'menu.left.groups_management'|trans }}</a>
+ </li>
<li class="bold {% if currentRoute == 'import' %}active{% endif %}">
<a class="waves-effect" href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a>
</li>
namespace Wallabag\GroupBundle\Controller;
+use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Exception\OutOfRangeCurrentPageException;
use Pagerfanta\Pagerfanta;
use Wallabag\GroupBundle\Entity\UserGroup;
use Wallabag\GroupBundle\Form\GroupType;
use Wallabag\GroupBundle\Form\NewGroupType;
+use Wallabag\GroupBundle\Form\UserGroupType;
use Wallabag\UserBundle\Entity\User;
/**
}
throw $this->createAccessDeniedException();
}
+
+ /**
+ * @Route("/join/{group}", name="group_join")
+ * @param Group $group
+ * @return Response
+ */
+ public function joinGroupAction(Group $group): Response
+ {
+ $em = $this->getDoctrine()->getManager();
+
+ if ($group->getAcceptSystem() === Group::ACCESS_PASSWORD) {
+ return $this->redirectToRoute('group_password', ['group' => $group->getId()]);
+ }
+ $this->getUser()->addAGroup($group, $group->getDefaultRole());
+
+ $em->flush();
+
+ return $this->redirect($this->generateUrl('group_index'), 302);
+ }
+
+ /**
+ * @Route("/manage/{group}/{page}", name="group-manage", defaults={"page" = "1"})
+ * @param Group $group
+ * @return Response
+ */
+ public function manageGroupUsersAction(Group $group, int $page): Response
+ {
+ if ($this->getUser()->getGroupRoleForUser($group) < Group::ROLE_MANAGE_USERS) {
+ $this->createAccessDeniedException();
+ }
+
+ $members = $this->get('wallabag_user.user_repository')->findGroupMembers($group->getId());
+
+ $pagerAdapter = new DoctrineORMAdapter($members->getQuery(), true, false);
+ $pagerFanta = new Pagerfanta($pagerAdapter);
+ $pagerFanta->setMaxPerPage(9);
+
+ try {
+ $pagerFanta->setCurrentPage($page);
+ } catch (OutOfRangeCurrentPageException $e) {
+ if ($page > 1) {
+ return $this->redirect($this->generateUrl('groups', ['page' => $pagerFanta->getNbPages()]), 302);
+ }
+ }
+
+ return $this->render('WallabagGroupBundle:Manage:manage.html.twig', [
+ 'members' => $pagerFanta,
+ 'group' => $group,
+ 'currentPage' => $page,
+ ]);
+ }
+
+ /**
+ * @Route("/leave/{group}", name="group_leave")
+ * @param Group $group
+ * @return Response
+ */
+ public function leaveGroupAction(Group $group): Response
+ {
+ $logger = $this->get('logger');
+ $em = $this->getDoctrine()->getManager();
+ $removeGroup = false;
+
+ if ($this->getUser()->getGroupRoleForUser($group) == Group::ROLE_ADMIN) {
+ $logger->info('User ' . $this->getUser()->getUsername() . ' is the admin for group ' . $group->getName());
+ $newUser = $group->getUsers()->first();
+ $newUser->setGroupRole($group, Group::ROLE_ADMIN);
+ $logger->info('The new admin for group ' . $group->getName() . ' is user ' . $newUser->getUsername());
+ }
+
+ if ($group->getUsers()->count() <= 1) {
+ $logger->info('User ' . $this->getUser()->getUsername() . ' was the last one on the group ' . $group->getName() . ' so it will be deleted');
+ $removeGroup = true;
+ }
+
+ $logger->info('Removing user ' . $this->getUser()->getUsername() . ' from group ' . $group->getName());
+ $em->remove($this->getUser()->getUserGroupFromGroup($group));
+
+ if ($removeGroup) {
+ $logger->info("Removing group " . $group->getName() . " as it doesn't contains users anymore");
+ $em->remove($group);
+ }
+
+ $em->flush();
+ return $this->redirect($this->generateUrl('groups'), 302);
+ }
+
+ /**
+ * @Route("/requests/{group}/{page}", name="group-requests", defaults={"page" = "1"})
+ * @param Request $request
+ * @param int $page
+ * @return Response
+ */
+ public function showRequestsAction(Group $group, int $page): Response
+ {
+ if ($this->getUser()->getGroupRoleForUser($group) < Group::ROLE_MANAGE_USERS) {
+ $this->createAccessDeniedException();
+ }
+
+ $requests = $group->getRequests();
+ $pagerAdapter = new ArrayAdapter($requests->toArray());
+
+ $pagerFanta = new Pagerfanta($pagerAdapter);
+ $pagerFanta->setMaxPerPage(9);
+
+ try {
+ $pagerFanta->setCurrentPage($page);
+ } catch (OutOfRangeCurrentPageException $e) {
+ if ($page > 1) {
+ return $this->redirect($this->generateUrl('groups', ['page' => $pagerFanta->getNbPages()]), 302);
+ }
+ }
+
+ return $this->render('WallabagGroupBundle:Manage:requests.html.twig', [
+ 'requests' => $pagerFanta,
+ 'group' => $group,
+ 'currentPage' => $page,
+ ]);
+ }
+
+ /**
+ * @Route("/activate/{group}/{user}/{accept}", name="group-activate", requirements={"accept" = "\d+"})
+ * @param Group $group
+ * @param User $user
+ * @param $accept
+ * @return Response
+ */
+ public function postRequestAction(Group $group, User $user, $accept): Response
+ {
+ if (!$this->getUser() < Group::ROLE_MANAGE_USERS) {
+ $this->createAccessDeniedException("You don't have the rights to do this");
+ }
+
+ $em = $this->getDoctrine()->getManager();
+
+ $accept = $accept == 1;
+ $user->getUserGroupFromGroup($group)->setAccepted($accept);
+ if (!$accept) {
+ $em->remove($user->getUserGroupFromGroup($group));
+ }
+
+ $em->flush();
+
+ return $this->redirectToRoute('group_index');
+ }
+
+ /**
+ * @Route("/user-edit/{group}/{user}", name="group-user-edit")
+ * @param Request $request
+ * @param Group $group
+ * @param User $user
+ * @return Response
+ */
+ public function editGroupUsersAction(Request $request, Group $group, User $user): Response
+ {
+ if ($this->getUser()->getGroupRoleForUser($group) < Group::ROLE_MANAGE_USERS) {
+ $this->createAccessDeniedException();
+ }
+
+ $groupUser = $user->getUserGroupFromGroup($group);
+ $editForm = $this->createForm(UserGroupType::class, $groupUser);
+ $editForm->handleRequest($request);
+
+ if ($editForm->isSubmitted() && $editForm->isValid()) {
+ $em = $this->getDoctrine()->getManager();
+ $em->persist($groupUser);
+ $em->flush();
+
+ $this->get('session')->getFlashBag()->add(
+ 'notice',
+ $this->get('translator')->trans('flashes.group.notice.user.edited', ['%user%' => $user->getUsername(), '%group%' => $group->getName()])
+ );
+
+ return $this->redirectToRoute('group-manage', ['group' => $group->getId()]);
+ }
+
+ return $this->render('WallabagGroupBundle:Manage:edit_user.html.twig', array(
+ 'user' => $user,
+ 'group' => $group,
+ 'edit_form' => $editForm->createView(),
+ ));
+ }
}
<?php
-namespace Wallabag\GroupBundle\Form\Type;
+namespace Wallabag\GroupBundle\Form;
use Wallabag\GroupBundle\Entity\Group;
use Symfony\Component\Form\AbstractType;
'choices' => [
'group.roles.readonly' => Group::ROLE_READ_ONLY,
'group.roles.write' => Group::ROLE_WRITE,
- 'group.roles.manage_prez' => Group::ROLE_MANAGE_PREZ,
+ 'group.roles.manage_entries' => Group::ROLE_MANAGE_ENTRIES,
'group.roles.manage_users' => Group::ROLE_MANAGE_USERS,
'group.roles.admin' => Group::ROLE_ADMIN,
],
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
- 'data_class' => 'Strut\StrutBundle\Entity\UserGroup',
+ 'data_class' => 'Wallabag\GroupBundle\Entity\UserGroup',
));
}
}
services:
sha256salted_encoder:
- class: Strut\StrutBundle\Service\Sha256Salted
\ No newline at end of file
+ class: Wallabag\GroupBundle\Service\Sha256Salted
+
+ wallabag_core.filter.type.entry:
+ class: Wallabag\GroupBundle\Form\UserGroupType
+ tags:
+ - { name: form.type }
\ No newline at end of file
--- /dev/null
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.edit_user.title'|trans }}{% endblock %}
+
+{% block content %}
+
+<div class="row">
+ <div class="col-md-6">
+
+ {{ form_start(edit_form) }}
+ {{ form_errors(edit_form) }}
+
+ <div class="form-group">
+ {{ form_label(edit_form.role) }}
+ {{ form_errors(edit_form.role) }}
+ {{ form_widget(edit_form.role) }}
+ </div>
+
+ {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect'}}) }}
+ <a class="btn btn-default" href="{{ path('group-manage', {'group': group.id}) }}">{{ 'group.edit_user.cancel' | trans }}</a>
+ {{ form_widget(edit_form._token) }}
+ {{ form_end(edit_form) }}
+ </div>
+</div>
+
+{% endblock %}
<p class="help">{{ 'group.description'|trans|raw }}</p>
{% if groups is not empty %}
- <table class="bordered">
+ <table class="bordered responsive-table">
<thead>
<tr>
<th>{{ 'group.form.name_label'|trans }}</th>
{% for group in groups %}
<tr>
<td>{{ group.name }}</td>
- <td></td>
<td>
- <a href="{{ path('group_edit', { 'id': group.id }) }}">{{ 'group.list.edit_action'|trans }}</a>
+ {% if app.user in group.users and app.user.inGroup(group) %}
+ {{ 'group.user.inGroup' | transchoice(group.users | length) }}
+ {% else %}
+ {{ 'group.user.notInGroup' | transchoice(group.users | length) }}
+ {% endif %}
+ </td>
+ <td>
+ {% if app.user in group.users and app.user.inGroup(group) %}
+ {% if app.user.getGroupRoleForUser(group) >= 5 %}
+ <a href="{{ path('group_edit', { 'id': group.id }) }}" class="waves-effect waves-light btn tooltipped" data-delay="50" data-position="bottom" data-tooltip="{{ 'group.list.edit_action'|trans }}"><i class="material-icons">edit</i></a>
+ <a href="{{ path('group-manage', { 'group': group.id }) }}" class="waves-effect waves-light btn tooltipped" data-delay="50" data-position="bottom" data-tooltip="{{ 'group.manage.label'|trans }}"><i class="material-icons">settings_applications</i></a>
+ {% endif %}
+ <a href="{{ path('group-presentations', { 'group': group.id }) }}" class="waves-effect waves-light btn tooltipped" data-delay="50" data-position="bottom" data-tooltip="{{ 'group.entries.label'|trans }}"><i class="material-icons">view_list</i></a>
+ <a href="{{ path('group_leave', { 'group': group.id }) }}" class="waves-effect waves-light btn red tooltipped" data-delay="50" data-position="bottom" data-tooltip="{{ 'group.leave.label'|trans }}"><i class="material-icons">clear</i></a>
+ {% elseif app.user in group.users and not app.user.inGroup(group) %}
+ {{ 'group.requests.sent' | trans }}
+ {% else %}
+ <a href="{{ path('group_join', { 'group': group.id }) }}" class="waves-effect waves-light btn tooltipped" data-tooltip="{{ 'group.join.label'|trans }}" data-delay="50" data-position="bottom">
+ {% if group.acceptSystem == 3 %}
+ <i class="material-icons md-18 vertical-align-middle" data-toggle="tooltip" data-placement="bottom" title="{{ 'group.join'|trans }}">lock</i>
+ {% else %}
+ <i class="material-icons" data-toggle="tooltip" data-placement="bottom" title="{{ 'group.join'|trans }}">input</i>
+ {% endif %}
+ </a>
+ {% endif %}
</td>
</tr>
{% endfor %}
--- /dev/null
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.manage.title' |trans({ '%group%': group.name }) }}{% endblock %}
+
+{% block content %}
+
+<div class="row">
+ <div class="input-field col s12">
+ <p>
+ {{ 'group.form.role_label' |trans }}:
+ <em>
+ {% if group.defaultRole == 1 %}
+ {{ 'group.roles.readonly' | trans }}
+ {% elseif group.defaultRole == 2 %}
+ {{ 'group.roles.write' | trans }}
+ {% elseif group.defaultRole == 3 %}
+ {{ 'group.roles.manage_prez' | trans }}
+ {% elseif group.defaultRole == 5 %}
+ {{ 'group.roles.manage_users' | trans }}
+ {% elseif group.defaultRole == 10 %}
+ {{ 'group.roles.admin' | trans }}
+ {% else %}
+ {{ 'group.roles.unknown' | trans }}
+ {% endif %}
+ </em>
+ </p>
+ <p>
+ {{ 'group.form.access_label' | trans }}:
+ <em>
+ {% if group.acceptSystem == 1 %}
+ {{ 'group.access.open' | trans }}
+ {% elseif group.acceptSystem == 2 %}
+ {{ 'group.access.request' | trans }}
+ {% elseif group.acceptSystem == 3 %}
+ {{ 'group.access.password' | trans }}
+ {% elseif group.acceptSystem == 4 %}
+ {{ 'group.access.invitation' | trans }}
+ {% elseif group.acceptSystem == 10 %}
+ {{ 'group.access.hidden' | trans }}
+ {% else %}
+ {{ 'group.access.unknown' | trans }}
+ {% endif %}
+ </em>
+ </p>
+ <a href="{{ path('group_edit', {'id' : group.id}) }}" class="btn waves-effect">{{ 'group.edit_group' | trans }}</a>
+ {% if group.acceptSystem == 2 %}
+ <a href="{{ path('group-requests', {'group' : group.id}) }}" class="btn waves-effect">{{ 'group.requests.list' | trans }} <span class="badge">{{ group.getRequests() | length }}</span></a>
+ {% elseif group.acceptSystem >= 4 %}
+ <a href="{{ path('group-invitations', {'group' : group.id}) }}" class="btn waves-effect">{{ 'group.edit.invitations' | trans }} <span class="badge">{{ group.getInvited() | length }}</span></a>
+ {% endif %}
+ <a href="{{ path('group_delete', { 'id': group.id }) }}" class="btn waves-effect red"><i class="material-icons md-18" data-toggle="tooltip" data-placement="bottom" title="{{ 'group.form.delete'|trans }}">delete</i></a>
+
+ {% if members | length > 1 %}
+ <table class="table">
+ <thead>
+ <tr>
+ <th>{{ 'group.members.name'|trans }}</th>
+ <th>{{ 'group.members.role' | trans }}</th>
+ <th>{{ 'group.members.action'|trans }}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for user in members %}
+ {% if user != app.user %}
+ <tr>
+ <td>{{ user.username }}</td>
+ <td>
+ {% if user.getGroupRoleForUser(group) == 1 %}
+ {{ 'group.roles.readonly' | trans }}
+ {% elseif user.getGroupRoleForUser(group) == 2 %}
+ {{ 'group.roles.write' | trans }}
+ {% elseif user.getGroupRoleForUser(group) == 3 %}
+ {{ 'group.roles.manage_prez' | trans }}
+ {% elseif user.getGroupRoleForUser(group) == 5 %}
+ {{ 'group.roles.manage_users' | trans }}
+ {% elseif user.getGroupRoleForUser(group) == 10 %}
+ {{ 'group.roles.admin' | trans }}
+ {% else %}
+ {{ 'group.roles.unknown' | trans }}
+ {% endif %}
+ </td>
+ <td>
+ <a href="{{ path('group-user-edit', { 'group': group.id, 'user': user.id }) }}" class="btn waves-effect"><i class="material-icons md-18" data-toggle="tooltip" data-placement="bottom" title="{{ 'group.members.edit'|trans }}">edit</i></a>
+ <a class="btn waves-effect red" href="{{ path('group-user-exclude', { 'group': group.id, 'user': user.id }) }}"><i class="material-icons md-18" data-toggle="tooltip" data-placement="bottom" title="{{ 'group.members.exclude'|trans }}">clear</i></a>
+ </td>
+ </tr>
+ {% endif %}
+ {% endfor %}
+ </tbody>
+ </table>
+ {% else %}
+ <p>{{ 'group.members.empty' | trans }}</p>
+ {% endif %}
+ <div class="pull-right">
+ {% if members.getNbPages > 1 %}
+ {{ pagerfanta(members, 'twitter_bootstrap3', {'proximity': 1}) }}
+ {% endif %}
+ </div>
+ </div>
+</div>
+{% endblock %}
--- /dev/null
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.requests.list'|trans }}{% endblock %}
+
+{% block content %}
+<div class="row">
+ <div class="col s12">
+
+ <table class="table">
+ <thead>
+ <tr>
+ <th>{{ 'group.requests.username'|trans }}</th>
+ <th>{{ 'group.requests.action'|trans }}</th>
+ </tr>
+ </thead>
+
+ <tbody>
+ {% for request in requests %}
+ <tr>
+ <td>{{ request.username }}</td>
+ <td>
+ <a class="btn waves-effect" href="{{ path('group-activate', {'group': group.id, 'user': request.id, 'accept': 1}) }}"><i class="material-icons">check</i></a>
+ <a class="btn waves-effect red" href="{{ path('group-activate', {'group': group.id, 'user': request.id, 'accept': 2}) }}"><i class="material-icons">close</i></a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+</div>
+{% endblock %}
return $groups;
}
+
+ /**
+ * @param Group $group
+ * @param $role
+ */
+ public function addAGroup(Group $group, $role)
+ {
+ $this->userGroups->add(new UserGroup($this, $group, $role));
+ }
}
*
* @param string $term
*
- * @return QueryBuilder
+ * @return \Doctrine\ORM\QueryBuilder
*/
public function getQueryBuilderForSearch($term)
{
return $this->createQueryBuilder('u')
->andWhere('lower(u.username) LIKE lower(:term) OR lower(u.email) LIKE lower(:term) OR lower(u.name) LIKE lower(:term)')->setParameter('term', '%'.$term.'%');
}
+
+ public function findGroupMembers($groupid)
+ {
+ return $this->createQueryBuilder('u')
+ ->leftJoin('u.userGroups', 'usergroup')
+ ->where('usergroup.group = :group')->setParameter(':group', $groupid)
+ ->andWhere('usergroup.accepted = true');
+ }
}
{{ form_rest(searchForm) }}
</form>
</div>
-
+
</div>
<table class="bordered">