*/ class EmployeeRepository extends ServiceEntityRepository implements PasswordUpgraderInterface { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Employee::class); } public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void { if (!$user instanceof Employee) { throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $user::class)); } $user->setPassword($newHashedPassword); $this->getEntityManager()->persist($user); $this->getEntityManager()->flush(); } /** * Lädt ein öffentlich sichtbares (aktives) Profil anhand Firmen- und * Mitarbeiter-Slug. Nicht mandantengefiltert – diese Seiten sind öffentlich. */ public function findPublic(string $companySlug, string $slug): ?Employee { return $this->createQueryBuilder('e') ->join('e.company', 'c') ->andWhere('c.slug = :companySlug') ->andWhere('e.slug = :slug') ->andWhere('e.status = :status') ->setParameter('companySlug', $companySlug) ->setParameter('slug', $slug) ->setParameter('status', 'active') ->getQuery() ->getOneOrNullResult(); } /** Aktives Profil über den stabilen NFC/QR-Kurz-Code (für /t/{code}). */ public function findByShortCode(string $shortCode): ?Employee { return $this->findOneBy(['shortCode' => $shortCode, 'status' => 'active']); } /** @return Employee[] Mitarbeiter ohne Kurz-Code (für Backfill). */ public function findWithoutShortCode(): array { return $this->createQueryBuilder('e') ->andWhere('e.shortCode IS NULL') ->getQuery() ->getResult(); } }