userManager = $userManager; $this->memberRequest = $memberRequest; $this->membershipRequest = $membershipRequest; $this->circleRequest = $circleRequest; $this->federatedUserService = $federatedUserService; $this->circleService = $circleService; $this->membershipService = $membershipService; $this->configService = $configService; } /** * */ protected function configure() { parent::configure(); $this->setName('circles:memberships') ->setDescription('index and display memberships for local and federated users') ->addArgument('userId', InputArgument::OPTIONAL, 'userId to generate memberships', '') ->addOption('display-name', '', InputOption::VALUE_NONE, 'display the displayName') // ->addOption('reset', '', InputOption::VALUE_NONE, 'reset memberships') ->addOption('all', '', InputOption::VALUE_NONE, 'refresh memberships for all entities') ->addOption( 'type', '', InputOption::VALUE_REQUIRED, 'type of the user', Member::$TYPE[Member::TYPE_SINGLE] ); } /** * @param InputInterface $input * @param OutputInterface $output * * @return int * @throws CircleNotFoundException * @throws FederatedUserException * @throws FederatedUserNotFoundException * @throws MemberNotFoundException * @throws OwnerNotFoundException * @throws RemoteInstanceException * @throws RemoteNotFoundException * @throws RemoteResourceNotFoundException * @throws UnknownRemoteException * @throws UserTypeNotFoundException * @throws FederatedItemException * @throws InvalidIdException * @throws SingleCircleNotFoundException * @throws Exception */ protected function execute(InputInterface $input, OutputInterface $output): int { $this->input = $input; if ($input->getOption('all')) { $this->manageAllMemberships(); return 0; } $userId = $input->getArgument('userId'); if ($userId === '') { throw new Exception('Not enough arguments (missing: "userId").'); } $type = Member::parseTypeString($input->getOption('type')); $federatedUser = $this->federatedUserService->getFederatedUser($userId, $type); // if ($this->input->getOption('reset')) { // $this->membershipsService->resetMemberships($federatedUser->getSingleId()); // // return 0; // } $output->writeln('Id: ' . $federatedUser->getUserId() . ''); $output->writeln('Instance: ' . $federatedUser->getInstance() . ''); $output->writeln('Type: ' . Member::$TYPE[$federatedUser->getUserType()] . ''); $output->writeln('SingleId: ' . $federatedUser->getSingleId() . ''); $output->writeln(''); $output->writeln('Memberships:'); $count = $this->membershipService->manageMemberships($federatedUser->getSingleId()); if ($count === 0) { $output->writeln('(database not updated)'); } else { $output->writeln('(' . ((string)$count) . ' entries generated/updated in the database)'); } foreach ($federatedUser->getMemberships() as $membership) { $this->memberships[$membership->getCircleId()] = $membership; $output->writeln( '- ' . $membership->getCircleId() . ' (' . Member::$DEF_LEVEL[$membership->getLevel()] . ')' ); } $output->writeln(''); $tree = new TreeNode(null, new SimpleDataStore(['federatedUser' => $federatedUser])); $this->generateTree($federatedUser->getSingleId(), $tree); $this->drawTree( $tree, [$this, 'displayLeaf'], [ 'height' => 3, 'node-spacing' => 0, 'item-spacing' => 1, ] ); return 0; } /** * @param string $id * @param TreeNode $tree * @param array $knownIds */ private function generateTree(string $id, TreeNode $tree, array $knownIds = []) { if (in_array($id, $knownIds)) { return; } $knownIds[] = $id; $members = $this->memberRequest->getMembersBySingleId($id); foreach ($members as $member) { if ($member->getLevel() < Member::LEVEL_MEMBER || $member->getCircle()->isConfig(Circle::CFG_SINGLE)) { continue; } $item = new TreeNode( $tree, new SimpleDataStore( [ 'member' => $member, 'cycling' => in_array($member->getCircleId(), $knownIds) ] ) ); $this->generateTree($member->getCircleId(), $item, $knownIds); } } /** * @param SimpleDataStore $data * @param int $lineNumber * * @return string * @throws OwnerNotFoundException */ public function displayLeaf(SimpleDataStore $data, int $lineNumber): string { if ($lineNumber === 3) { return ($data->gBool('cycling')) ? '(loop detected)' : ''; } try { $line = ''; if ($data->hasKey('federatedUser')) { /** @var FederatedUser $federatedUser */ $federatedUser = $data->gObj('federatedUser', FederatedUser::class); if ($lineNumber === 2) { return ''; } $line .= '' . $federatedUser->getSingleId() . ''; if (!$this->configService->isLocalInstance($federatedUser->getInstance())) { $line .= '@' . $federatedUser->getInstance(); } return $line; } if ($data->hasKey('member')) { /** @var Member $member */ $member = $data->gObj('member', Member::class); $circle = $member->getCircle(); if ($lineNumber === 1) { $line .= '' . $circle->getSingleId() . ''; if (!$this->configService->isLocalInstance($circle->getInstance())) { $line .= '@' . $circle->getInstance(); } $line .= ' (' . ($this->input->getOption('display-name') ? $circle->getDisplayName() : $circle->getName()) . ')'; $line .= ' MemberId: ' . $member->getId(); $line .= ' Level: ' . Member::$DEF_LEVEL[$member->getLevel()]; $knownMembership = $this->memberships[$member->getCircleId()]; if ($member->getLevel() !== $knownMembership->getLevel()) { $line .= ' (' . Member::$DEF_LEVEL[$knownMembership->getLevel()] . ')'; } } if ($lineNumber === 2) { $owner = $circle->getOwner(); $line .= 'Owner: ' . $owner->getUserId() . '@' . $owner->getInstance() . ' '; if ($owner->hasBasedOn()) { $line .= '(' . Circle::$DEF_SOURCE[$owner->getBasedOn()->getSource()] . ') '; } $type = implode(', ', Circle::getCircleFlags($circle, Circle::FLAGS_LONG)); $line .= ($type === '') ? '' : 'Config: ' . $type; } return $line; } } catch (InvalidItemException|ItemNotFoundException|UnknownTypeException $e) { } return ''; } /** * @throws FederatedUserNotFoundException * @throws InitiatorNotFoundException * @throws OwnerNotFoundException * @throws RequestBuilderException */ private function manageAllMemberships() { // if ($this->input->getOption('reset')) { // $this->membershipsService->resetMemberships('', true); // // return; // } $this->federatedUserService->bypassCurrentUserCondition(true); $probe = new CircleProbe(); $probe->includeSystemCircles() ->includeSingleCircles() ->includePersonalCircles(); $circles = $this->circleService->getCircles($probe); $output = new ConsoleOutput(); $output = $output->section(); $table = new Table($output); $table->setHeaders(['Circle Id', 'Name', 'Source', 'Owner', 'Instance', 'Updated', 'Memberships']); $count = 0; $rows = []; foreach ($circles as $circle) { $owner = $circle->getOwner(); $updated = $this->membershipService->manageMemberships($circle->getSingleId()); $count += $updated; $federatedUser = $this->circleRequest->getFederatedUserBySingleId($circle->getSingleId()); $rows[] = [ $circle->getSingleId(), $circle->getDisplayName(), ($circle->getSource() > 0) ? Circle::$DEF_SOURCE[$circle->getSource()] : '', $owner->getUserId(), $this->configService->displayInstance($owner->getInstance()), $updated, sizeof($federatedUser->getMemberships()) ]; } $table->setRows($rows); $table->render(); $output->writeln(((string)$count) . ' memberships updated'); } }