]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Added groups management
authorNicolas Lœuillet <nicolas@loeuillet.org>
Thu, 3 Nov 2016 11:11:48 +0000 (12:11 +0100)
committerThomas Citharel <tcit@tcit.fr>
Fri, 23 Jun 2017 07:22:54 +0000 (09:22 +0200)
22 files changed:
app/config/routing.yml
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/layout.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/layout.html.twig
src/Wallabag/GroupBundle/Controller/ManageController.php [new file with mode: 0644]
src/Wallabag/GroupBundle/Form/GroupType.php [new file with mode: 0644]
src/Wallabag/GroupBundle/Form/NewGroupType.php [new file with mode: 0644]
src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig [new file with mode: 0644]
src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig [new file with mode: 0644]
src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig [new file with mode: 0644]
tests/Wallabag/GroupBundle/Controller/ManageControllerTest.php [new file with mode: 0644]

index 9c916f7dd6233274d778a19e57b06a00211bf213..74c21429c5bfcddd475a9a76cdba3d1d869d8a1b 100644 (file)
@@ -7,6 +7,11 @@ wallabag_import:
     type: annotation
     prefix: /import
 
+wallabag_group:
+    resource: "@WallabagGroupBundle/Controller/"
+    type: annotation
+    prefix: /groups
+
 wallabag_user:
     resource: "@WallabagUserBundle/Controller/"
     type: annotation
@@ -41,10 +46,6 @@ homepage:
 fos_user:
     resource: "@FOSUserBundle/Resources/config/routing/all.xml"
 
-fos_user_group:
-    resource: "@FOSUserBundle/Resources/config/routing/group.xml"
-    prefix: /group
-
 fos_oauth_server_token:
     resource: "@FOSOAuthServerBundle/Resources/config/routing/token.xml"
 
index ea7fb086361d42af982148290eb628a89eaa74dd..8d023efa3a157a439cd8b808c7bebad5eeb8b555 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Tilbage til de ulæste artikler'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Tilføj ny artikel'
         search: 'Søg'
@@ -496,6 +497,25 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'Back'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     # page_title: Users management
     # new_user: Create a new user
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index fcda6ae6d97ff8f21f07483f9a196da270cc057e..44f11ab4cadbc94502d0eba328fed64f9384648c 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Zurück zu ungelesenen Artikeln'
         users_management: 'Benutzerverwaltung'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Neuen Artikel hinzufügen'
         search: 'Suche'
@@ -496,6 +497,25 @@ developer:
             paragraph_8: 'Wenn du alle API-Endpunkte sehen willst, werfe einen Blick auf die <a href="%link%">API-Dokumentation</a>.'
         back: 'Zurück'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     page_title: Benutzerverwaltung
     new_user: Erstelle einen neuen Benutzer
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 54427e2318bf1dc5ef816c64913cacfc4cf729cc..0d8cde7ab9ad97fa6b77f798d6cee9fdd18ff3c0 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Back to unread articles'
         users_management: 'Users management'
         site_credentials: 'Site credentials'
+        groups_management: 'Groups management'
     top:
         add_new_entry: 'Add a new entry'
         search: 'Search'
@@ -496,6 +497,25 @@ developer:
             paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
         back: 'Back'
 
+group:
+    page_title: Groups management
+    new_group: Create a new group
+    edit_group: Edit an existing group
+    description: "Here you can manage all groups (create, edit and delete)"
+    list:
+        actions: Actions
+        edit_action: Edit
+        yes: Yes
+        no: No
+        create_new_one: Create a new group
+    form:
+        name_label: 'Name'
+        roles_label: 'Roles'
+        save: Save
+        delete: Delete
+        delete_confirm: Are you sure?
+        back_to_list: Back to list
+
 user:
     page_title: Users management
     new_user: Create a new user
@@ -602,3 +622,8 @@ flashes:
             added: 'Site credential for "%host%" added'
             updated: 'Site credential for "%host%" updated'
             deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            added: 'Group "%name%" added'
+            updated: 'Group "%name%" updated'
+            deleted: 'Group "%name%" deleted'
index 96998f53579b8c38882918bdc729680148134684..e632e7e198adfdbc4925c82808bba7958efc0970 100644 (file)
@@ -33,6 +33,8 @@ menu:
         back_to_unread: 'Volver a los artículos sin leer'
         users_management: 'Configuración de usuarios'
         # site_credentials: 'Site credentials'
+        # users_management: 'Users management'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Añadir un nuevo artículo'
         search: 'Buscar'
@@ -496,6 +498,25 @@ developer:
             paragraph_8: 'Si quiere ver todos los métodos del API, puede verlos en <a href="%link%">nuestra documentación del API</a>.'
         back: 'Volver'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     page_title: Gestión de usuarios
     new_user: Crear un usuario
@@ -601,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 16c4f3a04e9bebc338cfdce3eaa430b59f787583..61fe8a17b6e31cfd0a3684b569c3ba53e35be04b 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'بازگشت به خوانده‌نشده‌ها'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'افزودن مقالهٔ تازه'
         search: 'جستجو'
@@ -496,6 +497,25 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'بازگشت'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     # page_title: Users management
     # new_user: Create a new user
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 6eac4c36d2e9f3fea5197c1606c20cbe8e753cc5..be8751ff971a4affd6de63e7c152f3d938c5be4d 100644 (file)
@@ -16,6 +16,7 @@ security:
 
 menu:
     left:
+<<<<<<< 5da541f5bdeec8ad968ba75a30ca2d19ea64d1f2
         unread: "Non lus"
         starred: "Favoris"
         archive: "Lus"
@@ -33,6 +34,23 @@ menu:
         back_to_unread: "Retour aux articles non lus"
         users_management: "Gestion des utilisateurs"
         site_credentials: 'Accès aux sites'
+        unread: 'Non lus'
+        starred: 'Favoris'
+        archive: 'Lus'
+        all_articles: 'Tous les articles'
+        config: 'Configuration'
+        tags: 'Tags'
+        internal_settings: 'Configuration interne'
+        import: 'Importer'
+        howto: 'Aide'
+        developer: 'Développeur'
+        logout: 'Déconnexion'
+        about: 'À propos'
+        search: 'Recherche'
+        save_link: 'Sauvegarder un nouvel article'
+        back_to_unread: 'Retour aux articles non lus'
+        users_management: 'Gestion des utilisateurs'
+        groups_management: 'Gestion des groupes'
     top:
         add_new_entry: "Sauvegarder un nouvel article"
         search: "Rechercher"
@@ -496,6 +514,25 @@ developer:
             paragraph_8: "Si vous voulez toutes les méthodes de l’API, jetez un oeil <a href=\"%link%\">à la documentation de l’API</a>."
         back: "Retour"
 
+group:
+    page_title: Gestion des groupes
+    new_group: Créer un nouveau group
+    edit_group: Éditer un nouveau groupe
+    description: Ici vous pouvez gérer vos groupes (création, mise à jour et suppression)
+    list:
+        actions: Actions
+        edit_action: Éditer
+        yes: Oui
+        no: Non
+        create_new_one: Créer un nouveau groupe
+    form:
+        name_label: 'Nom'
+        roles_label: 'Rôles'
+        save: Sauvegarder
+        delete: Supprimer
+        delete_confirm: Êtes-vous sur ?
+        back_to_list: Revenir à la liste
+
 user:
     page_title: "Gestion des utilisateurs"
     new_user: "Créer un nouvel utilisateur"
@@ -601,3 +638,12 @@ flashes:
             added: 'Accès au site "%host%" ajouté'
             updated: 'Accès au site "%host%" mis à jour'
             deleted: 'Accès au site "%host%" supprimé'
+
+            added: "Utilisateur \"%username%\" ajouté"
+            updated: "Utilisateur \"%username%\" mis à jour"
+            deleted: "Utilisateur \"%username%\" supprimé"
+    group:
+        notice:
+            added: "Groupe \"%name%\" ajouté"
+            updated: "Groupe \"%name%\" mis à jour"
+            deleted: "Groupe \"%name%\" supprimé"
index 8dff4c6d746e8c2024d383156bcf89d8afa5853f..a909d2c1cdaa55e04af0ffedbdd981b2a87f2bc1 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Torna ai contenuti non letti'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Aggiungi un nuovo contenuto'
         search: 'Cerca'
@@ -496,6 +497,25 @@ developer:
             paragraph_8: 'Se vuoi visualizzare tutti gli API endpoints, dai una occhiata alla <a href="%link%">documentazione delle API</a>.'
         back: 'Indietro'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     # page_title: Users management
     # new_user: Create a new user
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 1cf70233b7f0fd957a54d74cf08b66d5542b1611..a3c935caaeabb6178f88e2aafeb8936aa07ff5eb 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Tornar als articles pas legits'
         users_management: 'Gestion dels utilizaires'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Enregistrar un novèl article'
         search: 'Cercar'
@@ -496,6 +497,26 @@ developer:
             paragraph_8: "Se volètz totas las adreças d'accès de l'API, donatz un còp d’uèlh <a href=\"%link%\">a la documentacion de l'API</a>."
         back: 'Retorn'
 
+
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     page_title: 'Gestion dels utilizaires'
     new_user: 'Crear un novèl utilizaire'
@@ -602,3 +623,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index d3af4fd551a87f015a2f842e4500c991aff600ec..d252d4485ba8f2fcafb4aa83490f3b16b9dea103 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Powrót do nieprzeczytanych artykułów'
         users_management: 'Zarządzanie użytkownikami'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Dodaj nowy wpis'
         search: 'Szukaj'
@@ -496,6 +497,25 @@ developer:
             paragraph_8: 'Jeżeli chcesz wyświetlić wszystkie punkty końcowe API, zobacz <a href="%link%">Dokumentacja naszego API</a>.'
         back: 'Cofnij'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     page_title: Zarządzanie użytkownikami
     new_user: Stwórz nowego użytkownika
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 4ab5f144c590fddfd335cbb2bc61c01cc3c3258c..ccb3debb943377bf940d06a40053e4331b9bb28d 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Voltar para os artigos não lidos'
         users_management: 'Gestão de Usuários'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Adicionar uma nova entrada'
         search: 'Pesquisa'
@@ -601,3 +602,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 3952eae8054af7f01f5641ce27e6ef398c00bdd0..29ae81cd6dc14c22cfd04d54dce2adbdfb12da37 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Înapoi la articolele necitite'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Introdu un nou articol'
         search: 'Căutare'
@@ -496,6 +497,25 @@ developer:
     #         paragraph_8: 'If you want to see all the API endpoints, you can have a look <a href="%link%">to our API documentation</a>.'
     #     back: 'Back'
 
+group:
+    # page_title: Groups management
+    # new_group: Create a new group
+    # edit_group: Edit an existing group
+    # description: "Here you can manage all groups (create, edit and delete)"
+    # list:
+    #     actions: Actions
+    #     edit_action: Edit
+    #     yes: Yes
+    #     no: No
+    #     create_new_one: Create a new group
+    # form:
+    #     name_label: 'Name'
+    #     roles_label: 'Roles'
+    #     save: Save
+    #     delete: Delete
+    #     delete_confirm: Are you sure?
+    #     back_to_list: Back to list
+
 user:
     # page_title: Users management
     # new_user: Create a new user
@@ -602,3 +622,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 74f76c7266ed8ea3bcb603994fb9349bcf50f168..4ac867a0f356c514b05e3346e203254a12949b7e 100644 (file)
@@ -33,6 +33,7 @@ menu:
         back_to_unread: 'Okunmayan makalelere geri dön'
         # users_management: 'Users management'
         # site_credentials: 'Site credentials'
+        # groups_management: 'Groups management'
     top:
         add_new_entry: 'Yeni bir makale ekle'
         search: 'Ara'
@@ -580,3 +581,8 @@ flashes:
             # added: 'Site credential for "%host%" added'
             # updated: 'Site credential for "%host%" updated'
             # deleted: 'Site credential for "%host%" deleted'
+    group:
+        notice:
+            # added: 'Group "%name%" added'
+            # updated: 'Group "%name%" updated'
+            # deleted: 'Group "%name%" deleted'
index 17fa13bb5f247afd3013812780c8e3e5935f5d7d..545dab90cc67bb55af4d0255fdee7c9814b9562e 100644 (file)
@@ -44,6 +44,7 @@
         <li class="menu config"><a href="{{ path('config') }}">{{ 'menu.left.config'|trans }}</a></li>
         {% if is_granted('ROLE_SUPER_ADMIN') %}
             <li class="menu users"><a href="{{ path('user_index') }}">{{ 'menu.left.users_management'|trans }}</a></li>
+            <li class="menu groups"><a href="{{ path('group_index') }}">{{ 'menu.left.groups_management'|trans }}</a></li>
             <li class="menu internal"><a href="{{ path('craue_config_settings_modify') }}">{{ 'menu.left.internal_settings'|trans }}</a></li>
         {% endif %}
         <li class="menu import"><a href="{{ path('import') }}">{{ 'menu.left.import'|trans }}</a></li>
index 60907e11a253f77520f2aa7c37f82fa6fddc62fd..575c77f2e01c4c56223fddcf1dd52ed1c317cce0 100644 (file)
@@ -75,6 +75,9 @@
                 <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>
diff --git a/src/Wallabag/GroupBundle/Controller/ManageController.php b/src/Wallabag/GroupBundle/Controller/ManageController.php
new file mode 100644 (file)
index 0000000..7015a46
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+namespace Wallabag\GroupBundle\Controller;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Bundle\FrameworkBundle\Controller\Controller;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
+use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
+use Wallabag\GroupBundle\Entity\Group;
+
+/**
+ * Group controller.
+ */
+class ManageController extends Controller
+{
+    /**
+     * Lists all Group entities.
+     *
+     * @Route("/", name="group_index")
+     * @Method("GET")
+     */
+    public function indexAction()
+    {
+        $em = $this->getDoctrine()->getManager();
+
+        $groups = $em->getRepository('WallabagGroupBundle:Group')->findAll();
+
+        return $this->render('WallabagGroupBundle:Manage:index.html.twig', array(
+            'groups' => $groups,
+        ));
+    }
+
+    /**
+     * Creates a new Group entity.
+     *
+     * @Route("/new", name="group_new")
+     * @Method({"GET", "POST"})
+     */
+    public function newAction(Request $request)
+    {
+        $group = new Group('');
+
+        $form = $this->createForm('Wallabag\GroupBundle\Form\NewGroupType', $group);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($group);
+            $em->flush();
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.group.notice.added', ['%name%' => $group->getName()])
+            );
+
+            return $this->redirectToRoute('group_edit', array('id' => $group->getId()));
+        }
+
+        return $this->render('WallabagGroupBundle:Manage:new.html.twig', array(
+            'group' => $group,
+            'form' => $form->createView(),
+        ));
+    }
+
+    /**
+     * Displays a form to edit an existing Group entity.
+     *
+     * @Route("/{id}/edit", name="group_edit")
+     * @Method({"GET", "POST"})
+     */
+    public function editAction(Request $request, Group $group)
+    {
+        $deleteForm = $this->createDeleteForm($group);
+        $editForm = $this->createForm('Wallabag\GroupBundle\Form\GroupType', $group);
+        $editForm->handleRequest($request);
+
+        if ($editForm->isSubmitted() && $editForm->isValid()) {
+            $em = $this->getDoctrine()->getManager();
+            $em->persist($group);
+            $em->flush();
+
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.group.notice.updated', ['%name%' => $group->getName()])
+            );
+
+            return $this->redirectToRoute('group_edit', array('id' => $group->getId()));
+        }
+
+        return $this->render('WallabagGroupBundle:Manage:edit.html.twig', array(
+            'group' => $group,
+            'edit_form' => $editForm->createView(),
+            'delete_form' => $deleteForm->createView(),
+        ));
+    }
+
+    /**
+     * Deletes a Group entity.
+     *
+     * @Route("/{id}", name="group_delete")
+     * @Method("DELETE")
+     */
+    public function deleteAction(Request $request, Group $group)
+    {
+        $form = $this->createDeleteForm($group);
+        $form->handleRequest($request);
+
+        if ($form->isSubmitted() && $form->isValid()) {
+            $this->get('session')->getFlashBag()->add(
+                'notice',
+                $this->get('translator')->trans('flashes.group.notice.deleted', ['%name%' => $group->getName()])
+            );
+
+            $em = $this->getDoctrine()->getManager();
+            $em->remove($group);
+            $em->flush();
+        }
+
+        return $this->redirectToRoute('group_index');
+    }
+
+    /**
+     * Creates a form to delete a Group entity.
+     *
+     * @param Group $group The Group entity
+     *
+     * @return \Symfony\Component\Form\Form The form
+     */
+    private function createDeleteForm(Group $group)
+    {
+        return $this->createFormBuilder()
+            ->setAction($this->generateUrl('group_delete', array('id' => $group->getId())))
+            ->setMethod('DELETE')
+            ->getForm()
+        ;
+    }
+}
diff --git a/src/Wallabag/GroupBundle/Form/GroupType.php b/src/Wallabag/GroupBundle/Form/GroupType.php
new file mode 100644 (file)
index 0000000..c2ad764
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+
+namespace Wallabag\GroupBundle\Form;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+
+class GroupType extends AbstractType
+{
+    /**
+     * @param FormBuilderInterface $builder
+     * @param array                $options
+     */
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('name', TextType::class, [
+                'required' => false,
+                'label' => 'group.form.name_label',
+            ])
+            ->add('save', SubmitType::class, [
+                'label' => 'group.form.save',
+            ])
+        ;
+    }
+
+    /**
+     * @param OptionsResolver $resolver
+     */
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults(array(
+            'data_class' => 'Wallabag\GroupBundle\Entity\Group',
+        ));
+    }
+}
diff --git a/src/Wallabag/GroupBundle/Form/NewGroupType.php b/src/Wallabag/GroupBundle/Form/NewGroupType.php
new file mode 100644 (file)
index 0000000..29b20fe
--- /dev/null
@@ -0,0 +1,37 @@
+<?php
+
+namespace Wallabag\GroupBundle\Form;
+
+use Symfony\Component\Form\AbstractType;
+use Symfony\Component\Form\Extension\Core\Type\SubmitType;
+use Symfony\Component\Form\Extension\Core\Type\TextType;
+use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+
+class NewGroupType extends AbstractType
+{
+    public function buildForm(FormBuilderInterface $builder, array $options)
+    {
+        $builder
+            ->add('name', TextType::class, [
+                'required' => true,
+                'label' => 'group.form.name_label',
+            ])
+            ->add('save', SubmitType::class, [
+                'label' => 'group.form.save',
+            ])
+        ;
+    }
+
+    public function configureOptions(OptionsResolver $resolver)
+    {
+        $resolver->setDefaults([
+            'data_class' => 'Wallabag\GroupBundle\Entity\Group',
+        ]);
+    }
+
+    public function getBlockPrefix()
+    {
+        return 'new_group';
+    }
+}
diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/edit.html.twig
new file mode 100644 (file)
index 0000000..7de68c3
--- /dev/null
@@ -0,0 +1,44 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'group.edit_group'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(edit_form) }}
+                                {{ form_errors(edit_form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(edit_form.name) }}
+                                        {{ form_errors(edit_form.name) }}
+                                        {{ form_widget(edit_form.name) }}
+                                    </div>
+                                </div>
+
+                                <br/>
+
+                                {{ form_widget(edit_form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_widget(edit_form._token) }}
+                            </form>
+                            <p>
+                                {{ form_start(delete_form) }}
+                                    <button onclick="return confirm('{{ 'group.form.delete_confirm'|trans|escape('js') }}')" type="submit" class="btn waves-effect waves-light red">{{ 'group.form.delete'|trans }}</button>
+                                {{ form_end(delete_form) }}
+                            </p>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('group_index') }}">{{ 'group.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/index.html.twig
new file mode 100644 (file)
index 0000000..ce2a455
--- /dev/null
@@ -0,0 +1,44 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <p class="help">{{ 'group.description'|trans|raw }}</p>
+
+                        <table class="bordered">
+                            <thead>
+                                <tr>
+                                    <th>{{ 'group.form.name_label'|trans }}</th>
+                                    <th>{{ 'group.form.roles_label'|trans }}</th>
+                                    <th>{{ 'group.list.actions'|trans }}</th>
+                                </tr>
+                            </thead>
+                            <tbody>
+                            {% 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>
+                                    </td>
+                                </tr>
+                            {% endfor %}
+                            </tbody>
+                        </table>
+                        <br />
+                        <p>
+                            <a href="{{ path('group_new') }}" class="waves-effect waves-light btn">{{ 'group.list.create_new_one'|trans }}</a>
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig b/src/Wallabag/GroupBundle/Resources/views/Manage/new.html.twig
new file mode 100644 (file)
index 0000000..3f1c2ad
--- /dev/null
@@ -0,0 +1,37 @@
+{% extends "WallabagCoreBundle::layout.html.twig" %}
+
+{% block title %}{{ 'group.page_title'|trans }}{% endblock %}
+
+{% block content %}
+
+    <div class="row">
+        <div class="col s12">
+            <div class="card-panel">
+                <div class="row">
+                    <div class="input-field col s12">
+                        <h4>{{ 'group.new_group'|trans }}</h4>
+
+                        <div id="set6" class="col s12">
+                            {{ form_start(form) }}
+                                {{ form_errors(form) }}
+
+                                <div class="row">
+                                    <div class="input-field col s12">
+                                        {{ form_label(form.name) }}
+                                        {{ form_errors(form.name) }}
+                                        {{ form_widget(form.name) }}
+                                    </div>
+                                </div>
+
+                                {{ form_widget(form.save, {'attr': {'class': 'btn waves-effect waves-light'}}) }}
+                                {{ form_rest(form) }}
+                            </form>
+                            <p><a class="waves-effect waves-light btn blue-grey" href="{{ path('group_index') }}">{{ 'group.form.back_to_list'|trans }}</a></p>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+
+{% endblock %}
diff --git a/tests/Wallabag/GroupBundle/Controller/ManageControllerTest.php b/tests/Wallabag/GroupBundle/Controller/ManageControllerTest.php
new file mode 100644 (file)
index 0000000..fc1852e
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+namespace Wallabag\GroupBundle\Tests\Controller;
+
+use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
+
+class ManageControllerTest extends WallabagCoreTestCase
+{
+    public function testLogin()
+    {
+        $client = $this->getClient();
+
+        $client->request('GET', '/groups/');
+
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+        $this->assertContains('login', $client->getResponse()->headers->get('location'));
+    }
+
+    public function testCompleteScenario()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        // Create a new group in the database
+        $crawler = $client->request('GET', '/groups/');
+        $this->assertEquals(200, $client->getResponse()->getStatusCode(), 'Unexpected HTTP status code for GET /groups/');
+        $crawler = $client->click($crawler->selectLink('group.list.create_new_one')->link());
+
+        // Fill in the form and submit it
+        $form = $crawler->selectButton('group.form.save')->form(array(
+            'new_group[name]' => 'test_group',
+        ));
+
+        $client->submit($form);
+        $client->followRedirect();
+        $crawler = $client->request('GET', '/groups/');
+
+        // Check data in the show view
+        $this->assertGreaterThan(0, $crawler->filter('td:contains("test_group")')->count(), 'Missing element td:contains("test_group")');
+
+        // Edit the group
+        $crawler = $client->click($crawler->selectLink('group.list.edit_action')->last()->link());
+
+        $form = $crawler->selectButton('group.form.save')->form(array(
+            'group[name]' => 'test_group',
+        ));
+
+        $client->submit($form);
+        $crawler = $client->followRedirect();
+
+        // Check the element contains an attribute with value equals "test_group"
+        $this->assertGreaterThan(0, $crawler->filter('[value="test_group"]')->count(), 'Missing element [value="test_group"]');
+
+        $crawler = $client->request('GET', '/groups/');
+        $crawler = $client->click($crawler->selectLink('group.list.edit_action')->last()->link());
+
+        // Delete the group
+        $client->submit($crawler->selectButton('group.form.delete')->form());
+        $crawler = $client->followRedirect();
+
+        // Check the user has been delete on the list
+        $this->assertNotRegExp('/test_group/', $client->getResponse()->getContent());
+    }
+}