Skip to content

Conversation

@crydotsnake
Copy link
Member

@crydotsnake crydotsnake commented Mar 4, 2024

Q A
Branch? 2.2
Bug fix? no.
New feature? yes.
BC breaks? no.
Deprecations? no
Related tickets fixes #15890
License MIT

Description:

As described in: #15890

This pull request introduces a new CLI command:

bin/console sylius:admin-users:list

By default all available admin users are listed, and each data of a user is showed in a table:

SCR-20240304-nxdu

If you want to see only one admin user, you can use the --username option:

bin/console sylius:admin-user:list --username simon

Any feedback or improvement ideas are much appreciated!

Summary by CodeRabbit

  • New Features
    • Added a console command sylius:admin-user:list (alias sylius:admin-users:list) to display admin users.
    • Supports an optional --username flag to show a single user or list all users.
    • Outputs a formatted table with ID, E‑mail, username, first/last name, locale, and enabled/disabled status.
    • Registered as a CLI service and returns clear success/failure feedback.

@crydotsnake crydotsnake requested a review from a team as a code owner March 4, 2024 14:46
@probot-autolabeler probot-autolabeler bot added the Admin AdminBundle related issues and PRs. label Mar 4, 2024
@github-actions
Copy link

github-actions bot commented Mar 4, 2024

❌ Preview Environment deleted from Bunnyshell

Available commands:

  • 🚀 /bns:deploy to redeploy the environment

@crydotsnake
Copy link
Member Author

crydotsnake commented Mar 4, 2024

By default, all available admin users will be display. But you can also show only one admin user with the --username argument:

cfd5505

SCR-20240304-pqrf

@crydotsnake crydotsnake changed the title FEATURE: [AdminBundle] #15890 Introduce sylius:admin-users:list command FEATURE: [AdminBundle] #15890 Introduce sylius:admin-user:list command Mar 4, 2024
Copy link
Contributor

@Rafikooo Rafikooo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @crydotsnake for another contribution,
It would be awesome if you could try to test this feature, you can refer to how we tested other, similar CLI command here: https://github.com/Sylius/Sylius/pull/14571/files#diff-0cc123576bf137514df3bef27330b372df9d5016c6e3a27cbe1c29338934e1d5R26

@crydotsnake
Copy link
Member Author

crydotsnake commented Mar 4, 2024

Thank you @crydotsnake for another contribution,

It would be awesome if you could try to test this feature, you can refer to how we tested other, similar CLI command here: https://github.com/Sylius/Sylius/pull/14571/files#diff-0cc123576bf137514df3bef27330b372df9d5016c6e3a27cbe1c29338934e1d5R26

Yes. Good point 🤦🏼‍♂️ will take a look at it. A test for #15889 would be good aswell..

@Rafikooo
Copy link
Contributor

Hello @crydotsnake, are you still interested in completing this task? We want to incorporate this feature, however, Sylius 1.13-RC version has been released, so this pull request should now be directed to the 2.0 branch 💃

@crydotsnake
Copy link
Member Author

Hello @crydotsnake, are you still interested in completing this task? We want to incorporate this feature, however, Sylius 1.13-RC version has been released, so this pull request should now be directed to the 2.0 branch 💃

Hello @Rafikooo !

Yes, i'm. But i had no time to work on the tests so far 😓.

@crydotsnake crydotsnake changed the base branch from 1.13 to 2.1 July 17, 2025 11:04
@crydotsnake crydotsnake requested a review from a team as a code owner July 17, 2025 11:04
@crydotsnake
Copy link
Member Author

crydotsnake commented Jul 17, 2025

Thank you @crydotsnake for another contribution, It would be awesome if you could try to test this feature, you can refer to how we tested other, similar CLI command here: https://github.com/Sylius/Sylius/pull/14571/files#diff-0cc123576bf137514df3bef27330b372df9d5016c6e3a27cbe1c29338934e1d5R26

Does a list command really need a test? I mean, what could i test? 😅

@crydotsnake
Copy link
Member Author

Thank you @crydotsnake for another contribution, It would be awesome if you could try to test this feature, you can refer to how we tested other, similar CLI command here: https://github.com/Sylius/Sylius/pull/14571/files#diff-0cc123576bf137514df3bef27330b372df9d5016c6e3a27cbe1c29338934e1d5R26

Does a list command really need a test? I mean, what could i test? 😅

@Rafikooo

@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from cfd5505 to 4bb44d7 Compare September 7, 2025 13:16
@coderabbitai
Copy link

coderabbitai bot commented Sep 7, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds a new Symfony console command sylius:admin-user:list (alias sylius:admin-users:list) that lists all admin users or a single user via --username, using the admin user repository and SymfonyStyle tables; returns appropriate SUCCESS/FAILURE exit codes.

Changes

Cohort / File(s) Summary
CLI command implementation
src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php
New ListAdminUsersCommand (AsCommand) injected with UserRepositoryInterface; adds --username option, initializes SymfonyStyle, fetches either one user or all users, renders table(s) with columns: ID, E-Mail, Username, First name, Last name, Locale code, Enabled; returns SUCCESS or FAILURE.
Service registration
src/Sylius/Bundle/AdminBundle/Resources/config/services.xml
Registers Sylius\Bundle\AdminBundle\Console\Command\ListAdminUsersCommand service with constructor argument sylius.repository.admin_user and console.command tag.

Sequence Diagram(s)

sequenceDiagram
    actor Dev as Developer (CLI)
    participant SC as Symfony Console
    participant CMD as ListAdminUsersCommand
    participant REPO as UserRepositoryInterface
    participant IO as SymfonyStyle

    Dev->>SC: sylius:admin-user:list [--username <name>]
    SC->>CMD: initialize()
    CMD->>IO: construct SymfonyStyle
    SC->>CMD: execute()

    alt username provided
        CMD->>REPO: findOneByUsername(name)
        REPO-->>CMD: AdminUser|null
        alt found
            CMD->>IO: render single-user table
            CMD-->>SC: Command::SUCCESS
        else not found
            CMD->>IO: error("Admin user not found")
            CMD-->>SC: Command::FAILURE
        end
    else no username
        CMD->>REPO: findAll()
        REPO-->>CMD: AdminUser[]
        CMD->>IO: render all-users table
        CMD-->>SC: Command::SUCCESS
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
Provide CLI command to list available admin users with key details [#15890]

I thump the keys with fluffy might,
A list of admins springs to light—
IDs, names, and emails too,
In tidy rows for every view.
With whisker-twitch and table grace,
I grep the burrow, user by face. 🐇💻

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

♻️ Duplicate comments (1)
src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php (1)

71-93: Render one table for all users and handle the empty case.

Currently a separate table is printed per user and there’s duplication with listSingleAdminUser. Prefer one table; warn if none. (Also addresses an earlier comment about reuse.)

     private function listAllAdminUsers(): void
     {
-        $adminUsers = $this->userRepositoryInterface->findAll();
-        /** @var AdminUser $adminUser */
-        foreach ($adminUsers as $adminUser) {
-            $this->io->table(
-                [
-                    'ID', 'E-Mail', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled',
-                ],
-                [
-                    [
-                        $adminUser->getId(),
-                        $adminUser->getEmail(),
-                        $adminUser->getUsername(),
-                        $adminUser->getFirstname() ?? 'No Firstname Set',
-                        $adminUser->getLastName() ?? 'No Lastname Set',
-                        $adminUser->getLocaleCode(),
-                        $adminUser->isEnabled() ? 'Enabled' : 'Disabled',
-                    ],
-                ],
-            );
-        }
+        $adminUsers = $this->adminUserRepository->findAll();
+        if ($adminUsers === []){
+            $this->io->warning('No admin users found.');
+            return;
+        }
+
+        $rows = array_map(
+            static function (AdminUserInterface $adminUser): array {
+                return [
+                    $adminUser->getId(),
+                    $adminUser->getEmail(),
+                    $adminUser->getUsername(),
+                    $adminUser->getFirstName() ?? 'No first name set',
+                    $adminUser->getLastName() ?? 'No last name set',
+                    $adminUser->getLocaleCode(),
+                    $adminUser->isEnabled() ? 'Enabled' : 'Disabled',
+                ];
+            },
+            $adminUsers,
+        );
+
+        $this->io->table(
+            ['ID', 'Email', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled'],
+            $rows,
+        );
     }
🧹 Nitpick comments (6)
src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php (6)

32-32: Restrict visibility of $io.

Make it private; the class is final and nothing extends it.

-    protected SymfonyStyle $io;
+    private SymfonyStyle $io;

46-50: Drop redundant PHPDoc on execute().

Types are already declared; remove the boilerplate per coding guidelines.

-    /**
-     * @param InputInterface $input
-     * @param OutputInterface $output
-     * @return int
-     */

78-78: Consistent header label.

Prefer “Email” over “E-Mail”.

-                    'ID', 'E-Mail', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled',
+                    'ID', 'Email', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled',
-                'ID', 'E-Mail', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled',
+                'ID', 'Email', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled',

Also applies to: 100-100


74-74: Prefer interface types in annotations or remove them.

Docblocks reference the concrete AdminUser; either switch to AdminUserInterface or drop the annotations (they’re not needed).

-        /** @var AdminUser $adminUser */
+        /** @var AdminUserInterface $adminUser */
-        /** @var AdminUser $adminUser */
+        /** @var AdminUserInterface $adminUser */

Also applies to: 97-97


95-114: Optional DRY: extract a row builder and reuse headers.

Reduce duplication between listAllAdminUsers and listSingleAdminUser by extracting a toRow(AdminUserInterface) and a TABLE_HEADERS constant.

Example:

private const TABLE_HEADERS = ['ID', 'Email', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled'];

private function toRow(AdminUserInterface $u): array
{
    return [
        $u->getId(),
        $u->getEmail(),
        $u->getUsername(),
        $u->getFirstName() ?? 'No first name set',
        $u->getLastName() ?? 'No last name set',
        $u->getLocaleCode(),
        $u->isEnabled() ? 'Enabled' : 'Disabled',
    ];
}

private function listSingleAdminUser(AdminUserInterface $adminUser): void
{
    $this->io->table(self::TABLE_HEADERS, [$this->toRow($adminUser)]);
}

51-69: Please add tests for the command.

Cover happy path (all users), filter by existing username, and “not found” failure (exit code 1). Use CommandTester.

Sample:

public function test_it_lists_all_admin_users(): void
{
    // arrange fixtures (2 admin users)
    // act
    $tester = new CommandTester(self::getContainer()->get(ListAdminUsersCommand::class));
    $exit = $tester->execute([]);
    // assert
    self::assertSame(Command::SUCCESS, $exit);
    $display = $tester->getDisplay();
    self::assertStringContainsString('Admin users', $display);
    self::assertStringContainsString('Enabled', $display);
}

public function test_it_lists_one_user_when_username_is_provided(): void { /* ... */ }

public function test_it_fails_when_username_not_found(): void { /* ... */ }

I can scaffold these in a dedicated test class if helpful.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 62c1327 and 4bb44d7.

📒 Files selected for processing (1)
  • src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{php,yaml,yml,xml,twig}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation in PHP, YAML, XML, and Twig files

Files:

  • src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php
**/*.php

📄 CodeRabbit inference engine (AGENTS.md)

**/*.php: Use modern PHP 8.2+ syntax and features
Declare strict_types=1 in all PHP files
Follow the Sylius Coding Standard
Do not use deprecated features from PHP, Symfony, or Sylius
Use final for all classes, except entities and repositories
Use readonly for immutable services and value objects
Add type declarations for all properties, arguments, and return values
Use camelCase for variables and method names
Use SCREAMING_SNAKE_CASE for constants
Use fast returns instead of unnecessary nesting
Use trailing commas in multi-line arrays and argument lists
Order array keys alphabetically where applicable
Use PHPDoc only when necessary (e.g., @var Collection)
Group class elements in order: constants, properties, constructor, public, protected, private methods
Group getter and setter methods for the same properties together
Suffix interfaces with Interface and traits with Trait
Use use statements for all non-global classes
Sort use imports alphabetically and group by type (classes, functions, constants)

Files:

  • src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php
🧬 Code graph analysis (1)
src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php (1)
src/Sylius/Bundle/CoreBundle/Fixture/Factory/AdminUserExampleFactory.php (4)
  • AdminUserExampleFactory (28-112)
  • __construct (38-49)
  • configureOptions (82-97)
  • create (51-80)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (17)
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: Packages / PHP 8.4, Symfony ^7.2
  • GitHub Check: Packages / PHP 8.2, Symfony ^6.4
  • GitHub Check: Packages / PHP 8.3, Symfony ^7.2, ORM ^3.3
  • GitHub Check: End-to-end tests (MariaDB) / Non-JS, PHP 8.4, Symfony ^7.2, MariaDB 11.4.7, State Machine Adapter symfony_workflow
  • GitHub Check: End-to-end tests (MariaDB) / Non-JS, PHP 8.2, Symfony ^6.4, MariaDB 10.11.13, State Machine Adapter winzou_state_machine
  • GitHub Check: End-to-end tests (PostgreSQL) / Non-JS, PHP 8.2, Symfony ^6.4, PostgreSQL 15.13
  • GitHub Check: End-to-end tests (PostgreSQL) / Non-JS, PHP 8.4, Symfony ^7.2, PostgreSQL 17.5
  • GitHub Check: Frontend / NodeJS 24.x
🔇 Additional comments (1)
src/Sylius/Bundle/AdminBundle/Console/Command/ListAdminUsersCommand.php (1)

84-85: Confirm Username API compatibility in your target Sylius version.

If AdminUserInterface no longer guarantees getUsername() (migrated to getUserIdentifier()), update accordingly.

#!/bin/bash
# Verify AdminUserInterface still declares getUsername() in this repo
rg -nP -C2 'interface\s+AdminUserInterface\b' --type=php
rg -nP '\bfunction\s+getUsername\s*\(' --type=php
rg -nP '\bfunction\s+getUserIdentifier\s*\(' --type=php

Also applies to: 106-106

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/Sylius/Bundle/AdminBundle/Resources/config/services.xml (1)

56-59: Align service ID/visibility with existing console commands

Other commands here use a named service ID and are marked public. For consistency, consider switching to a named ID, add the class attribute, and set public="true". Indentation can also follow the file’s convention.

-        <service id="Sylius\Bundle\AdminBundle\Console\Command\ListAdminUsersCommand">
-            <argument type="service" id="sylius.repository.admin_user" />
-            <tag name="console.command" />
-        </service>
+        <service id="sylius_admin.console.command.list_admin_users"
+                 class="Sylius\Bundle\AdminBundle\Console\Command\ListAdminUsersCommand"
+                 public="true">
+            <argument type="service" id="sylius.repository.admin_user" />
+            <tag name="console.command" />
+        </service>

Note: If #[AsCommand] is present, the explicit tag is optional; keeping it is fine for parity with neighbors.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4bb44d7 and f7663a4.

📒 Files selected for processing (1)
  • src/Sylius/Bundle/AdminBundle/Resources/config/services.xml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{php,yaml,yml,xml,twig}

📄 CodeRabbit inference engine (AGENTS.md)

Use 4 spaces for indentation in PHP, YAML, XML, and Twig files

Files:

  • src/Sylius/Bundle/AdminBundle/Resources/config/services.xml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Panther, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.4, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / JS with Chromedriver, PHP 8.3, Symfony ^7.2 (test_cached), MySQL 8.4, Twig ^3.3
  • GitHub Check: End-to-end tests (MySQL) / Non-JS, PHP 8.2, Symfony ^6.4 (test_cached), MySQL 8.0, Twig ^3.3
  • GitHub Check: End-to-end tests (PostgreSQL) / Non-JS, PHP 8.2, Symfony ^6.4, PostgreSQL 15.13
  • GitHub Check: End-to-end tests (PostgreSQL) / Non-JS, PHP 8.4, Symfony ^7.2, PostgreSQL 17.5
  • GitHub Check: End-to-end tests (MariaDB) / Non-JS, PHP 8.4, Symfony ^7.2, MariaDB 11.4.7, State Machine Adapter symfony_workflow
  • GitHub Check: End-to-end tests (MariaDB) / Non-JS, PHP 8.2, Symfony ^6.4, MariaDB 10.11.13, State Machine Adapter winzou_state_machine

@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from 99ce5bc to 4259170 Compare September 7, 2025 14:05
@Rafikooo Rafikooo changed the base branch from 2.1 to 2.2 September 16, 2025 08:26
@Rafikooo Rafikooo self-assigned this Sep 16, 2025
@Rafikooo
Copy link
Contributor

Rafikooo commented Sep 26, 2025

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

@crydotsnake
Copy link
Member Author

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

Sure!
But what do you mean with format? Is that possible with the table helper:
https://symfony.com/doc/current/components/console/helpers/table.html

@Rafikooo
Copy link
Contributor

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

Sure! But what do you mean with format? Is that possible with the table helper: symfony.com/doc/current/components/console/helpers/table.html

Yup, it looks like something we're looking for 🚀

@crydotsnake
Copy link
Member Author

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

Sure! But what do you mean with format? Is that possible with the table helper: symfony.com/doc/current/components/console/helpers/table.html

Yup, it looks like something we're looking for 🚀

Because i already use the table helper. Thats why i dont quite understand what you mean with "format the table" 🤔

@Rafikooo
Copy link
Contributor

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

Sure! But what do you mean with format? Is that possible with the table helper: symfony.com/doc/current/components/console/helpers/table.html

Yup, it looks like something we're looking for 🚀

Because i already use the table helper. Thats why i dont quite understand what you mean with "format the table" 🤔

image

I mean the content isn't aligned 🙂

@crydotsnake
Copy link
Member Author

I have a small feature request. Could we format the table so that each column automatically adjusts to the widest field value? I think this would make it more readable and would also allow removing the repeated table headers 💃

Sure! But what do you mean with format? Is that possible with the table helper: symfony.com/doc/current/components/console/helpers/table.html

Yup, it looks like something we're looking for 🚀

Because i already use the table helper. Thats why i dont quite understand what you mean with "format the table" 🤔

image I mean the content isn't aligned 🙂
image

This is the new output.

@Rafikooo
Copy link
Contributor

Last feature request: it might be useful to add a field for the privileges that admins have 🎉

@crydotsnake
Copy link
Member Author

crydotsnake commented Sep 30, 2025

Last feature request: it might be useful to add a field for the privileges that admins have 🎉

@Rafikooo I like the idea too !🧙🏽‍♂️ 🪄

image

I added the Roles column at the end because also in the sylius_admin_user table its pretty much after Enabled etc..

@crydotsnake crydotsnake requested a review from Rafikooo October 18, 2025 12:29
@crydotsnake
Copy link
Member Author

Looks good i would say 👀

image

@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from ca6ec35 to 1dba01f Compare October 18, 2025 12:34
@crydotsnake
Copy link
Member Author

squashing done :) !

@crydotsnake
Copy link
Member Author

If this one is merged, i will rebase #15889 and include also a unit test for that! 🙂

@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from 1dba01f to f357663 Compare October 19, 2025 03:12
@crydotsnake crydotsnake added the Feature New feature proposals. label Oct 23, 2025
@crydotsnake crydotsnake changed the title FEATURE: [AdminBundle] #15890 Introduce sylius:admin-user:list command FEATURE: [2.2] [AdminBundle] #15890 Introduce sylius:admin-user:list command Oct 23, 2025
@crydotsnake crydotsnake self-assigned this Oct 24, 2025
@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch 2 times, most recently from 0ff6c52 to a48d63e Compare October 25, 2025 15:19
@crydotsnake crydotsnake requested a review from Rafikooo October 25, 2025 15:21
@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch 2 times, most recently from 2c78190 to 91bd08c Compare October 31, 2025 19:12
@crydotsnake crydotsnake requested a review from diimpp November 1, 2025 12:38
@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from 91bd08c to b8a4ee0 Compare November 24, 2025 19:39
@crydotsnake
Copy link
Member Author

FYI: I rebased the branch 🙂

@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from b8a4ee0 to 8a2d9a8 Compare December 5, 2025 07:34
)]
final class ListAdminUsersCommand extends Command
{
protected SymfonyStyle $io;
Copy link
Member

@diimpp diimpp Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since class is final and closed to extension.

Suggested change
protected SymfonyStyle $io;
private SymfonyStyle $io;

Comment on lines +63 to +75
$searchTerm = $input->getOption('search');
if ($searchTerm === null || $searchTerm === '') {
$this->renderUsersTable($output, $this->adminUserRepository->findAll());

return Command::SUCCESS;
}

$users = $this->searchUsers($searchTerm);
if (empty($users)) {
$this->io->warning(sprintf('No users found matching "%s"', $searchTerm));

return Command::SUCCESS;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, that code was refactored few times, I think logic branching for all and filtered users is not necessary anymore

Suggested change
$searchTerm = $input->getOption('search');
if ($searchTerm === null || $searchTerm === '') {
$this->renderUsersTable($output, $this->adminUserRepository->findAll());
return Command::SUCCESS;
}
$users = $this->searchUsers($searchTerm);
if (empty($users)) {
$this->io->warning(sprintf('No users found matching "%s"', $searchTerm));
return Command::SUCCESS;
}
$adminUsers = $this->findAdminUsers($input->getOption('search'));
if (empty($adminUsers)) {
$this->io->warning('No admin users found.');
return Command::SUCCESS;
}

and

    /**
     * @return array<AdminUserInterface>
     */
    private function findAdminUsers(?string $criteria): array
    {
        if (empty($criteria)) {
            return $this->adminUserRepository->findAll();
        }

        return $this->adminUserManager->createQueryBuilder()
            ->from(AdminUserInterface::class, 'o')
            ->select('o')
            ->where('LOWER(o.email) LIKE :criteria
                OR LOWER(o.username) LIKE :criteria
                OR LOWER(o.firstName) LIKE :criteria
                OR LOWER(o.lastName) LIKE :criteria')
            ->setParameter('criteria', '%' . mb_strtolower($searchTerm) . '%')
            ->orderBy('o.createdAt', 'DESC')
            ->getQuery()
            ->getResult();
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. Why should the filter logic removed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not suggesting removing the filtering logic, but rather refactoring the code. It has been modified several times, and as a result, the overall clarity and structure have been affected.

$criteria = '%' . mb_strtolower($searchTerm) . '%';

return $this->adminManager->createQueryBuilder()
->from(AdminUserInterface::class, 'u')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's sylius default to use o as alias for all queries.

Suggested change
->from(AdminUserInterface::class, 'u')
->from(AdminUserInterface::class, 'o')

{
$table = new Table($output);
$table->setHeaders([
'ID', 'E-Mail', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled', 'Roles',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'ID', 'E-Mail', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled', 'Roles',
'ID', 'Email', 'Username', 'First name', 'Last name', 'Locale code', 'Enabled', 'Roles',
image

/** @param UserRepositoryInterface<AdminUserInterface> $adminUserRepository */
public function __construct(
private readonly UserRepositoryInterface $adminUserRepository,
private readonly EntityManagerInterface $adminManager,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private readonly EntityManagerInterface $adminManager,
private readonly EntityManagerInterface $adminUserManager,

…command

FEATURE: Implement option to also select single admin user by username

TASK: add ListAdminUsersCommand back too services.xml after rebase

TASK: apply review suggestions & use ternary operator for getFirstName() & getLastName()

TASK: Integrate Table Helper and format table

TASK: add roles column with priviliges to table

TASK: apply cs fixes

TASK: adjust namings of variables and switch from AdminUser to AdminUserInterface

TASK: make logic more compact and use one function for generate table

TASK: move configure() function at the top

TASK: make phpstan happy

TASK: add unit test for ListAdminUsersCommand class

TASK: adjust unit test

TASK: adjust services.xml

TASK: adjust ListAdminUsersCommand by adding ability to search by email, username, first and lastname

TASK: check users array with empty function instead of with null

TASK: apply review suggestions

BUGFIX: make sure table only renders once

TASK: inject EntityManagerInterface and write custom query method to search for users
@crydotsnake crydotsnake force-pushed the feature/15890/list-admin-users-command branch from 8a2d9a8 to b2ba496 Compare December 10, 2025 10:01
@Rafikooo Rafikooo merged commit 4c004d4 into Sylius:2.2 Dec 11, 2025
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Admin AdminBundle related issues and PRs. Feature New feature proposals.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[CLI FEATURE] Command for list available admin users

4 participants