refonte role

This commit is contained in:
Charles 2025-08-12 10:01:00 +02:00
parent 716bfb8ce1
commit 9dc79eaa7d
10 changed files with 466 additions and 186 deletions

View File

@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250808085504 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE user_organizaton_app (id SERIAL NOT NULL, users_id INT NOT NULL, organization_id INT DEFAULT NULL, role_id INT DEFAULT NULL, created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL, is_active BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_2C952FC767B3B43D ON user_organizaton_app (users_id)');
$this->addSql('CREATE INDEX IDX_2C952FC732C8A3DE ON user_organizaton_app (organization_id)');
$this->addSql('CREATE INDEX IDX_2C952FC7D60322AC ON user_organizaton_app (role_id)');
$this->addSql('COMMENT ON COLUMN user_organizaton_app.created_at IS \'(DC2Type:datetime_immutable)\'');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT FK_2C952FC767B3B43D FOREIGN KEY (users_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT FK_2C952FC732C8A3DE FOREIGN KEY (organization_id) REFERENCES organizations (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT FK_2C952FC7D60322AC FOREIGN KEY (role_id) REFERENCES roles (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE users_organizations_apps DROP CONSTRAINT fk_f01f6897964985f0');
$this->addSql('ALTER TABLE users_organizations_apps DROP CONSTRAINT fk_f01f6897a2d76671');
$this->addSql('ALTER TABLE apps_organizations DROP CONSTRAINT fk_ffe659d586288a55');
$this->addSql('ALTER TABLE apps_organizations DROP CONSTRAINT fk_ffe659d5a2d76671');
$this->addSql('DROP TABLE users_organizations_apps');
$this->addSql('DROP TABLE apps_organizations');
$this->addSql('ALTER TABLE users_organizations DROP CONSTRAINT fk_4b991472d60322ac');
$this->addSql('DROP INDEX idx_4b991472d60322ac');
$this->addSql('ALTER TABLE users_organizations DROP role_id');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('CREATE TABLE users_organizations_apps (users_organizations_id INT NOT NULL, apps_id INT NOT NULL, PRIMARY KEY(users_organizations_id, apps_id))');
$this->addSql('CREATE INDEX idx_f01f6897964985f0 ON users_organizations_apps (users_organizations_id)');
$this->addSql('CREATE INDEX idx_f01f6897a2d76671 ON users_organizations_apps (apps_id)');
$this->addSql('CREATE TABLE apps_organizations (apps_id INT NOT NULL, organizations_id INT NOT NULL, PRIMARY KEY(apps_id, organizations_id))');
$this->addSql('CREATE INDEX idx_ffe659d586288a55 ON apps_organizations (organizations_id)');
$this->addSql('CREATE INDEX idx_ffe659d5a2d76671 ON apps_organizations (apps_id)');
$this->addSql('ALTER TABLE users_organizations_apps ADD CONSTRAINT fk_f01f6897964985f0 FOREIGN KEY (users_organizations_id) REFERENCES users_organizations (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE users_organizations_apps ADD CONSTRAINT fk_f01f6897a2d76671 FOREIGN KEY (apps_id) REFERENCES apps (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE apps_organizations ADD CONSTRAINT fk_ffe659d586288a55 FOREIGN KEY (organizations_id) REFERENCES organizations (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE apps_organizations ADD CONSTRAINT fk_ffe659d5a2d76671 FOREIGN KEY (apps_id) REFERENCES apps (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT FK_2C952FC767B3B43D');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT FK_2C952FC732C8A3DE');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT FK_2C952FC7D60322AC');
$this->addSql('DROP TABLE user_organizaton_app');
$this->addSql('ALTER TABLE users_organizations ADD role_id INT NOT NULL');
$this->addSql('ALTER TABLE users_organizations ADD CONSTRAINT fk_4b991472d60322ac FOREIGN KEY (role_id) REFERENCES roles (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX idx_4b991472d60322ac ON users_organizations (role_id)');
}
}

View File

@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250808091021 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT fk_2c952fc732c8a3de');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT fk_2c952fc767b3b43d');
$this->addSql('DROP INDEX idx_2c952fc732c8a3de');
$this->addSql('DROP INDEX idx_2c952fc767b3b43d');
$this->addSql('ALTER TABLE user_organizaton_app DROP organization_id');
$this->addSql('ALTER TABLE user_organizaton_app RENAME COLUMN users_id TO user_organization_id');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT FK_2C952FC72014CF51 FOREIGN KEY (user_organization_id) REFERENCES users_organizations (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_2C952FC72014CF51 ON user_organizaton_app (user_organization_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT FK_2C952FC72014CF51');
$this->addSql('DROP INDEX IDX_2C952FC72014CF51');
$this->addSql('ALTER TABLE user_organizaton_app ADD organization_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE user_organizaton_app RENAME COLUMN user_organization_id TO users_id');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT fk_2c952fc732c8a3de FOREIGN KEY (organization_id) REFERENCES organizations (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT fk_2c952fc767b3b43d FOREIGN KEY (users_id) REFERENCES "user" (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX idx_2c952fc732c8a3de ON user_organizaton_app (organization_id)');
$this->addSql('CREATE INDEX idx_2c952fc767b3b43d ON user_organizaton_app (users_id)');
}
}

View File

@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250811121053 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE user_organizaton_app ADD application_id INT NOT NULL');
$this->addSql('ALTER TABLE user_organizaton_app ADD CONSTRAINT FK_2C952FC73E030ACD FOREIGN KEY (application_id) REFERENCES apps (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
$this->addSql('CREATE INDEX IDX_2C952FC73E030ACD ON user_organizaton_app (application_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE user_organizaton_app DROP CONSTRAINT FK_2C952FC73E030ACD');
$this->addSql('DROP INDEX IDX_2C952FC73E030ACD');
$this->addSql('ALTER TABLE user_organizaton_app DROP application_id');
}
}

View File

@ -33,18 +33,18 @@ class Apps
#[ORM\Column(options: ['default' => true])] #[ORM\Column(options: ['default' => true])]
private ?bool $isActive = null; private ?bool $isActive = null;
/**
* @var Collection<int, organizations>
*/
#[ORM\ManyToMany(targetEntity: organizations::class, inversedBy: 'apps')]
private Collection $organization;
#[ORM\Column(length: 255, nullable: true)] #[ORM\Column(length: 255, nullable: true)]
private ?string $descriptionSmall = null; private ?string $descriptionSmall = null;
/**
* @var Collection<int, UserOrganizatonApp>
*/
#[ORM\OneToMany(targetEntity: UserOrganizatonApp::class, mappedBy: 'application')]
private Collection $userOrganizatonApps;
public function __construct() public function __construct()
{ {
$this->organization = new ArrayCollection(); $this->userOrganizatonApps = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@ -124,29 +124,6 @@ class Apps
return $this; return $this;
} }
/**
* @return Collection<int, organizations>
*/
public function getOrganization(): Collection
{
return $this->organization;
}
public function addOrganization(organizations $organization): static
{
if (!$this->organization->contains($organization)) {
$this->organization->add($organization);
}
return $this;
}
public function removeOrganization(organizations $organization): static
{
$this->organization->removeElement($organization);
return $this;
}
public function getDescriptionSmall(): ?string public function getDescriptionSmall(): ?string
{ {
@ -159,4 +136,34 @@ class Apps
return $this; return $this;
} }
/**
* @return Collection<int, UserOrganizatonApp>
*/
public function getUserOrganizatonApps(): Collection
{
return $this->userOrganizatonApps;
}
public function addUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if (!$this->userOrganizatonApps->contains($userOrganizatonApp)) {
$this->userOrganizatonApps->add($userOrganizatonApp);
$userOrganizatonApp->setApplication($this);
}
return $this;
}
public function removeUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if ($this->userOrganizatonApps->removeElement($userOrganizatonApp)) {
// set the owning side to null (unless already changed)
if ($userOrganizatonApp->getApplication() === $this) {
$userOrganizatonApp->setApplication(null);
}
}
return $this;
}
} }

View File

@ -51,11 +51,18 @@ class Organizations
#[ORM\OneToMany(targetEntity: Actions::class, mappedBy: 'Organization')] #[ORM\OneToMany(targetEntity: Actions::class, mappedBy: 'Organization')]
private Collection $actions; private Collection $actions;
/**
* @var Collection<int, UserOrganizatonApp>
*/
#[ORM\OneToMany(targetEntity: UserOrganizatonApp::class, mappedBy: 'organization')]
private Collection $userOrganizatonApps;
public function __construct() public function __construct()
{ {
$this->apps = new ArrayCollection(); $this->apps = new ArrayCollection();
$this->actions = new ArrayCollection(); $this->actions = new ArrayCollection();
$this->createdAt = new \DateTimeImmutable(); $this->createdAt = new \DateTimeImmutable();
$this->userOrganizatonApps = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@ -215,4 +222,34 @@ class Organizations
return $this; return $this;
} }
/**
* @return Collection<int, UserOrganizatonApp>
*/
public function getUserOrganizatonApps(): Collection
{
return $this->userOrganizatonApps;
}
public function addUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if (!$this->userOrganizatonApps->contains($userOrganizatonApp)) {
$this->userOrganizatonApps->add($userOrganizatonApp);
$userOrganizatonApp->setOrganization($this);
}
return $this;
}
public function removeUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if ($this->userOrganizatonApps->removeElement($userOrganizatonApp)) {
// set the owning side to null (unless already changed)
if ($userOrganizatonApp->getOrganization() === $this) {
$userOrganizatonApp->setOrganization(null);
}
}
return $this;
}
} }

View File

@ -263,6 +263,4 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface
return $this; return $this;
} }
} }

View File

@ -0,0 +1,103 @@
<?php
namespace App\Entity;
use App\Repository\UserOrganizatonAppRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: UserOrganizatonAppRepository::class)]
class UserOrganizatonApp
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column]
private ?\DateTimeImmutable $createdAt = null;
#[ORM\ManyToOne]
private ?Roles $role = null;
#[ORM\Column]
private ?bool $isActive;
#[ORM\ManyToOne(inversedBy: 'userOrganizatonApps')]
#[ORM\JoinColumn(nullable: false)]
private ?UsersOrganizations $userOrganization = null;
#[ORM\ManyToOne(inversedBy: 'userOrganizatonApps')]
#[ORM\JoinColumn(nullable: false)]
private ?Apps $application = null;
public function __construct()
{
$this->createdAt = new \DateTimeImmutable(); // Set createdAt to current time
$this->isActive = true; // Default value for isActive
}
public function getId(): ?int
{
return $this->id;
}
public function getCreatedAt(): ?\DateTimeImmutable
{
return $this->createdAt;
}
public function setCreatedAt(\DateTimeImmutable $createdAt): static
{
$this->createdAt = $createdAt;
return $this;
}
public function getRole(): ?Roles
{
return $this->role;
}
public function setRole(?Roles $role): static
{
$this->role = $role;
return $this;
}
public function isActive(): ?bool
{
return $this->isActive;
}
public function setIsActive(bool $isActive): static
{
$this->isActive = $isActive;
return $this;
}
public function getUserOrganization(): ?UsersOrganizations
{
return $this->userOrganization;
}
public function setUserOrganization(?UsersOrganizations $userOrganization): static
{
$this->userOrganization = $userOrganization;
return $this;
}
public function getApplication(): ?Apps
{
return $this->application;
}
public function setApplication(?Apps $application): static
{
$this->application = $application;
return $this;
}
}

View File

@ -17,33 +17,29 @@ class UsersOrganizations
#[ORM\ManyToOne] #[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
private ?user $users = null; private ?User $users = null;
#[ORM\ManyToOne] #[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)] #[ORM\JoinColumn(nullable: false)]
private ?Organizations $organization = null; private ?Organizations $organization = null;
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false)]
private ?Roles $role = null;
#[ORM\Column(options: ['default' => true])] #[ORM\Column(options: ['default' => true])]
private ?bool $isActive = null; private ?bool $isActive = null;
/**
* @var Collection<int, Apps>
*/
#[ORM\ManyToMany(targetEntity: Apps::class)]
private Collection $apps;
#[ORM\Column(nullable:true, options: ['default' => 'CURRENT_TIMESTAMP'])] #[ORM\Column(nullable:true, options: ['default' => 'CURRENT_TIMESTAMP'])]
private ?\DateTimeImmutable $createdAt = null; private ?\DateTimeImmutable $createdAt = null;
/**
* @var Collection<int, UserOrganizatonApp>
*/
#[ORM\OneToMany(targetEntity: UserOrganizatonApp::class, mappedBy: 'userOrganization')]
private Collection $userOrganizatonApps;
public function __construct() public function __construct()
{ {
$this->apps = new ArrayCollection();
$this->isActive = true; // Default value for isActive $this->isActive = true; // Default value for isActive
$this->createdAt = new \DateTimeImmutable(); // Set createdAt to current $this->createdAt = new \DateTimeImmutable(); // Set createdAt to current
$this->userOrganizatonApps = new ArrayCollection();
} }
public function getId(): ?int public function getId(): ?int
@ -75,18 +71,6 @@ class UsersOrganizations
return $this; return $this;
} }
public function getRole(): ?roles
{
return $this->role;
}
public function setRole(?roles $role): static
{
$this->role = $role;
return $this;
}
public function isActive(): ?bool public function isActive(): ?bool
{ {
return $this->isActive; return $this->isActive;
@ -99,38 +83,37 @@ class UsersOrganizations
return $this; return $this;
} }
/**
* @return Collection<int, apps>
*/
public function getApps(): Collection
{
return $this->apps;
}
public function addApp(apps $app): static
{
if (!$this->apps->contains($app)) {
$this->apps->add($app);
}
return $this;
}
public function removeApp(apps $app): static
{
$this->apps->removeElement($app);
return $this;
}
public function getCreatedAt(): ?\DateTimeImmutable public function getCreatedAt(): ?\DateTimeImmutable
{ {
return $this->createdAt; return $this->createdAt;
} }
public function setCreatedAt(?\DateTimeImmutable $createdAt): static /**
* @return Collection<int, UserOrganizatonApp>
*/
public function getUserOrganizatonApps(): Collection
{ {
$this->createdAt = $createdAt; return $this->userOrganizatonApps;
}
public function addUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if (!$this->userOrganizatonApps->contains($userOrganizatonApp)) {
$this->userOrganizatonApps->add($userOrganizatonApp);
$userOrganizatonApp->setUserOrganization($this);
}
return $this;
}
public function removeUserOrganizatonApp(UserOrganizatonApp $userOrganizatonApp): static
{
if ($this->userOrganizatonApps->removeElement($userOrganizatonApp)) {
// set the owning side to null (unless already changed)
if ($userOrganizatonApp->getUserOrganization() === $this) {
$userOrganizatonApp->setUserOrganization(null);
}
}
return $this; return $this;
} }

View File

@ -0,0 +1,43 @@
<?php
namespace App\Repository;
use App\Entity\UserOrganizatonApp;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<UserOrganizatonApp>
*/
class UserOrganizatonAppRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, UserOrganizatonApp::class);
}
// /**
// * @return UserOrganizatonApp[] Returns an array of UserOrganizatonApp objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('u.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?UserOrganizatonApp
// {
// return $this->createQueryBuilder('u')
// ->andWhere('u.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@ -19,153 +19,116 @@ class UsersOrganizationsRepository extends ServiceEntityRepository
parent::__construct($registry, UsersOrganizations::class); parent::__construct($registry, UsersOrganizations::class);
} }
/**
* Find all distinct active organizations for a given user ID.
*
* @param int $userId
* @return UsersOrganizations[]
*/
public function findAllDistinctOrganizationsByUserId(int $userId): array
{
return $this->createQueryBuilder('uo')
->select('DISTINCT uo')
->leftJoin('uo.organization', 'o')
->leftJoin('uo.role', 'r')
->addSelect('o', 'r')
->where('uo.users = :userId', 'uo.isActive = :isActive')
->setParameter('userId', $userId)
->setParameter('isActive', true)
->getQuery()
->getResult();
}
/** /**
* Find all organizations where a user (by email) has a specific role. * Find organizations where a user has a specific role (e.g., ADMIN)
* *
* @param string $userEmail * @param string $userEmail
* @param string $roleName * @param string $roleName
* @return Organizations[] * @return array Array of UsersOrganizations entities (with organizations preloaded)
*/ */
public function findOrganizationsByUserEmailAndRoleName(string $userEmail, string $roleName): array public function findUserOrganizationsByRole(string $userEmail, string $roleName): array
{ {
$results = $this->createQueryBuilder('uo') return $this->createQueryBuilder('uo')
->select('uo, o')
->innerJoin('uo.users', 'u') ->innerJoin('uo.users', 'u')
->innerJoin('uo.organization', 'o') ->innerJoin('uo.organization', 'o')
->innerJoin('uo.role', 'r') ->innerJoin('uo.userOrganizatonApps', 'uoa')
->innerJoin('uoa.role', 'r')
->where('u.email = :email') ->where('u.email = :email')
->andWhere('r.name = :roleName') ->andWhere('r.name = :roleName')
->andWhere('uo.isActive = :isActive') ->andWhere('uo.isActive = :isActive')
->andWhere('o.isActive = :orgIsActive') // Check if organization is active ->andWhere('u.isActive = :userIsActive')
->andWhere('o.isActive = :orgIsActive')
->andWhere('uoa.isActive = :uoaIsActive')
->setParameter('email', $userEmail) ->setParameter('email', $userEmail)
->setParameter('roleName', $roleName) ->setParameter('roleName', $roleName)
->setParameter('isActive', true) ->setParameter('isActive', true)
->setParameter('orgIsActive', true) // Parameter for organization active status ->setParameter('userIsActive', true)
->setParameter('orgIsActive', true)
->setParameter('uoaIsActive', true)
->getQuery() ->getQuery()
->getResult(); ->getResult();
return array_map(fn($uo) => $uo->getOrganization(), $results);
} }
/** /**
* Helper: Get all active UsersOrganizations links, optionally filtered by organizations. * Get all active user-organization relationships.
* Optionally filter by specific organizations.
* *
* @param Organizations[]|null $organizations * @param array|null $organizations Array of Organization entities to filter by
* @return UsersOrganizations[] * @return array Array of UsersOrganizations entities
*/ */
public function getAllActiveUserOrganizationLinks(array $organizations = null): array public function getAllActiveUserOrganizationLinks(array $organizations = null): array
{ {
$qb = $this->createQueryBuilder('uo') $queryBuilder = $this->createQueryBuilder('uo')
->innerJoin('uo.organization', 'o')
->innerJoin('uo.users', 'u')
->where('uo.isActive = :isActive')
->setParameter('isActive', true);
if (!empty($organizations)) {
$qb->andWhere('o IN (:organizations)')
->setParameter('organizations', $organizations);
}
return $qb->getQuery()->getResult();
}
/**
* Get the last 10 new active users for a specific organization.
* Users are ordered by creation date (most recent first).
*
* @param Organizations $organization
* @return array
*/
public function getLastNewActiveUsersByOrganization(Organizations $organization): array
{
$results = $this->createQueryBuilder('uo')
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive', 'uo.createdAt')
->innerJoin('uo.users', 'u') ->innerJoin('uo.users', 'u')
->innerJoin('uo.organization', 'o') ->innerJoin('uo.organization', 'o')
->where('uo.isActive = :isActive') ->where('uo.isActive = :isActive')
->andWhere('u.isActive = :userIsActive') ->andWhere('u.isActive = :userIsActive')
->andWhere('u.isDeleted = :userIsDeleted')
->andWhere('o.isActive = :orgIsActive') ->andWhere('o.isActive = :orgIsActive')
->andWhere('uo.organization = :organization') ->andWhere('o.isDeleted = :orgIsDeleted')
->setParameter('isActive', true) ->setParameter('isActive', true)
->setParameter('userIsActive', true) ->setParameter('userIsActive', true)
->setParameter('userIsDeleted', false)
->setParameter('orgIsActive', true) ->setParameter('orgIsActive', true)
->setParameter('organization', $organization) ->setParameter('orgIsDeleted', false)
->orderBy('uo.createdAt', 'DESC') ->orderBy('o.name', 'ASC')
->setMaxResults(10) ->addOrderBy('u.surname', 'ASC');
->getQuery()
->getResult();
// Remove duplicates by user ID (in case user has multiple roles) // Filter by specific organizations if provided
$uniqueUsers = []; if ($organizations !== null && !empty($organizations)) {
foreach ($results as $result) { $queryBuilder->andWhere('uo.organization IN (:organizations)')
$userId = $result['id']; ->setParameter('organizations', $organizations);
if (!isset($uniqueUsers[$userId])) {
$uniqueUsers[$userId] = $result;
}
} }
return array_values($uniqueUsers); return $queryBuilder->getQuery()->getResult();
} }
/** /**
* Get all active admin users for a specific organization. * Get all active users who are not in any organization.
* Returns users who have the 'ADMIN' role in the given organization.
* *
* @param Organizations $organization * @return array Array of User entities
* @return array
*/ */
public function getAdminUsersByOrganization(Organizations $organization): array public function getUsersWithoutOrganizations(): array
{ {
$results = $this->createQueryBuilder('uo') return $this->getEntityManager()->getRepository(User::class)
->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive') ->createQueryBuilder('u')
->innerJoin('uo.users', 'u') ->leftJoin('App\Entity\UsersOrganizations', 'uo', 'WITH', 'uo.users = u AND uo.isActive = true')
->innerJoin('uo.organization', 'o') ->where('u.isActive = :userIsActive')
->innerJoin('uo.role', 'r') ->andWhere('u.isDeleted = :userIsDeleted')
->where('uo.isActive = :isActive') ->andWhere('uo.id IS NULL')
->andWhere('u.isActive = :userIsActive')
->andWhere('o.isActive = :orgIsActive')
->andWhere('uo.organization = :organization')
->andWhere('r.name = :roleName')
->setParameter('isActive', true)
->setParameter('userIsActive', true) ->setParameter('userIsActive', true)
->setParameter('orgIsActive', true) ->setParameter('userIsDeleted', false)
->setParameter('organization', $organization)
->setParameter('roleName', 'ADMIN')
->orderBy('u.surname', 'ASC') ->orderBy('u.surname', 'ASC')
->getQuery() ->getQuery()
->getResult(); ->getResult();
// Remove duplicates by user ID (in case user has multiple admin-related roles)
$uniqueUsers = [];
foreach ($results as $result) {
$userId = $result['id'];
if (!isset($uniqueUsers[$userId])) {
$uniqueUsers[$userId] = $result;
}
}
return array_values($uniqueUsers);
} }
// /**
// * Get the last 10 new active users for a specific organization.
// * Users are ordered by creation date (most recent first).
// *
// * @param Organizations $organization
// * @return array
// */
// public function getLastNewActiveUsersByOrganization(Organizations $organization): array
// {
// return $this->createQueryBuilder('uo')
// ->select('u.id', 'u.surname', 'u.name', 'u.email', 'u.pictureUrl', 'u.isActive', 'uo.createdAt')
// ->innerJoin('uo.users', 'u')
// ->innerJoin('uo.organization', 'o')
// ->where('uo.isActive = :isActive')
// ->andWhere('u.isActive = :userIsActive')
// ->andWhere('o.isActive = :orgIsActive')
// ->andWhere('uo.organization = :organization')
// ->setParameter('isActive', true)
// ->setParameter('userIsActive', true)
// ->setParameter('orgIsActive', true)
// ->setParameter('organization', $organization)
// ->orderBy('uo.createdAt', 'DESC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult();
// }
} }