示例#1
0
 /**
  * Recursively copies nested sequence blocks for rollover.
  *
  * @param CurriculumInventorySequenceBlockInterface $block The block to copy.
  * @param CurriculumInventoryReportInterface $newReport The new report to roll over into.
  * @param CurriculumInventoryAcademicLevelInterface[] $newLevels A map of new academic levels, indexed by level.
  * @param CurriculumInventorySequenceBlockInterface|null $newParent The new parent block for this copy.
  */
 protected function rolloverSequenceBlock(CurriculumInventorySequenceBlockInterface $block, CurriculumInventoryReportInterface $newReport, array $newLevels, CurriculumInventorySequenceBlockInterface $newParent = null)
 {
     /* @var CurriculumInventorySequenceBlockInterface $newBlock */
     $newBlock = $this->sequenceBlockManager->create();
     $newBlock->setReport($newReport);
     $newBlock->setAcademicLevel($newLevels[$block->getAcademicLevel()->getLevel()]);
     $newBlock->setDescription($block->getDescription());
     $newBlock->setEndDate($block->getEndDate());
     $newBlock->setStartDate($block->getStartDate());
     $newBlock->setChildSequenceOrder($block->getChildSequenceOrder());
     $newBlock->setDuration($block->getDuration());
     $newBlock->setTitle($block->getTitle());
     $newBlock->setOrderInSequence($block->getOrderInSequence());
     $newBlock->setMinimum($block->getMinimum());
     $newBlock->setMaximum($block->getMaximum());
     $newBlock->setTrack($block->hasTrack());
     $newBlock->setRequired($block->getRequired());
     if ($newParent) {
         $newBlock->setParent($newParent);
         $newParent->addChild($newBlock);
     }
     $newReport->addSequenceBlock($newBlock);
     $this->sequenceBlockManager->update($newBlock, false, false);
     foreach ($block->getChildren() as $child) {
         $this->rolloverSequenceBlock($child, $newReport, $newLevels, $newBlock);
     }
 }
示例#2
0
 /**
  * @param SessionInterface     $newSession
  * @param SessionInterface     $origSession
  * @param $daysOffset
  */
 protected function rolloverIlmSession(SessionInterface $newSession, SessionInterface $origSession, $daysOffset)
 {
     /* @var IlmSessionInterface $origIlmSession */
     if ($origIlmSession = $origSession->getIlmSession()) {
         /* @var IlmSessionInterface $newIlmSession */
         $newIlmSession = $this->ilmSessionManager->create();
         $newIlmSession->setHours($origIlmSession->getHours());
         $newSession->setIlmSession($newIlmSession);
         $newDueDate = $this->getAdjustedDate($origIlmSession->getDueDate(), $daysOffset);
         $newIlmSession->setDueDate($newDueDate);
         $this->ilmSessionManager->update($newIlmSession, false, false);
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $output->writeln('<info>Starting former student synchronization process.</info>');
     $filter = $input->getArgument('filter');
     $formerStudents = $this->directory->findByLdapFilter($filter);
     if (!$formerStudents) {
         $output->writeln("<error>{$filter} returned no results.</error>");
         return;
     }
     $output->writeln('<info>Found ' . count($formerStudents) . ' former students in the directory.</info>');
     $formerStudentsCampusIds = array_map(function (array $arr) {
         return $arr['campusId'];
     }, $formerStudents);
     $notFormerStudents = $this->userManager->findUsersWhoAreNotFormerStudents($formerStudentsCampusIds);
     $usersToUpdate = $notFormerStudents->filter(function (UserInterface $user) {
         return !$user->isUserSyncIgnore();
     });
     if (!$usersToUpdate->count() > 0) {
         $output->writeln("<info>There are no students to update.</info>");
         return;
     }
     $output->writeln('<info>There are ' . $usersToUpdate->count() . ' students in Ilios who will be marked as a Former Student.</info>');
     $rows = $usersToUpdate->map(function (UserInterface $user) {
         return [$user->getCampusId(), $user->getFirstName(), $user->getLastName(), $user->getEmail()];
     })->toArray();
     $table = new Table($output);
     $table->setHeaders(array('Campus ID', 'First', 'Last', 'Email'))->setRows($rows);
     $table->render();
     $helper = $this->getHelper('question');
     $output->writeln('');
     $question = new ConfirmationQuestion('<question>Do you wish to mark these users as Former Students? </question>' . "\n", true);
     if ($helper->ask($input, $output, $question)) {
         /* @var UserRoleInterface $formerStudentRole */
         $formerStudentRole = $this->userRoleManager->findOneBy(array('title' => 'Former Student'));
         /* @var UserInterface $user */
         foreach ($usersToUpdate as $user) {
             $formerStudentRole->addUser($user);
             $user->addRole($formerStudentRole);
             $this->userManager->update($user, false);
         }
         $this->userRoleManager->update($formerStudentRole);
         $output->writeln('<info>Former students updated successfully!</info>');
     } else {
         $output->writeln('<comment>Update canceled,</comment>');
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $filter = $input->getArgument('filter');
     $schoolId = $input->getArgument('schoolId');
     $school = $this->schoolManager->findOneBy(['id' => $schoolId]);
     if (!$school) {
         throw new \Exception("School with id {$schoolId} could not be found.");
     }
     $output->writeln("<info>Searching for new students to add to " . $school->getTitle() . ".</info>");
     $students = $this->directory->findByLdapFilter($filter);
     if (!$students) {
         $output->writeln("<error>{$filter} returned no results.</error>");
         return;
     }
     $output->writeln('<info>Found ' . count($students) . ' students in the directory.</info>');
     $campusIds = $this->userManager->getAllCampusIds();
     $newStudents = array_filter($students, function (array $arr) use($campusIds) {
         return !in_array($arr['campusId'], $campusIds);
     });
     if (!count($newStudents) > 0) {
         $output->writeln("<info>There are no new students to add.</info>");
         return;
     }
     $output->writeln('<info>There are ' . count($newStudents) . ' new students to be added to ' . $school->getTitle() . '.</info>');
     $rows = array_map(function (array $arr) {
         return [$arr['campusId'], $arr['firstName'], $arr['lastName'], $arr['email']];
     }, $newStudents);
     $table = new Table($output);
     $table->setHeaders(array('Campus ID', 'First', 'Last', 'Email'))->setRows($rows);
     $table->render();
     $helper = $this->getHelper('question');
     $output->writeln('');
     $question = new ConfirmationQuestion('<question>Do you wish to add these students to ' . $school->getTitle() . '? </question>' . "\n", true);
     if ($helper->ask($input, $output, $question)) {
         $studentRole = $this->userRoleManager->findOneBy(array('title' => 'Student'));
         foreach ($newStudents as $userRecord) {
             if (empty($userRecord['email'])) {
                 $output->writeln('<error>Unable to add student ' . var_export($userRecord, true) . ' they have no email address.</error>');
                 continue;
             }
             if (empty($userRecord['campusId'])) {
                 $output->writeln('<error>Unable to add student ' . var_export($userRecord, true) . ' they have no campus ID.</error>');
                 continue;
             }
             if (empty($userRecord['username'])) {
                 $output->writeln('<error>Unable to add student ' . var_export($userRecord, true) . ' they have no username.</error>');
                 continue;
             }
             $user = $this->userManager->create();
             $user->setFirstName($userRecord['firstName']);
             $user->setLastName($userRecord['lastName']);
             $user->setEmail($userRecord['email']);
             $user->setCampusId($userRecord['campusId']);
             $user->setAddedViaIlios(true);
             $user->setEnabled(true);
             $user->setSchool($school);
             $user->setUserSyncIgnore(false);
             $user->addRole($studentRole);
             $this->userManager->update($user);
             $authentication = $this->authenticationManager->create();
             $authentication->setUser($user);
             $authentication->setUsername($userRecord['username']);
             $this->authenticationManager->update($authentication, false);
             $studentRole->addUser($user);
             $this->userRoleManager->update($studentRole);
             $output->writeln('<info>Success! New student #' . $user->getId() . ' ' . $user->getFirstAndLastName() . ' created.</info>');
         }
     } else {
         $output->writeln('<comment>Update canceled.</comment>');
     }
 }
 /**
  * Reorder the entire sequence if on of the blocks changes position.
  * @param int $oldValue
  * @param CurriculumInventorySequenceBlockInterface $block
  * @param ManagerInterface $manager
  * @throws \OutOfRangeException
  */
 protected function reorderBlocksInSequenceOnOrderChange($oldValue, CurriculumInventorySequenceBlockInterface $block, ManagerInterface $manager)
 {
     $parent = $block->getParent();
     if (!$parent) {
         return;
     }
     if ($parent->getChildSequenceOrder() !== CurriculumInventorySequenceBlockInterface::ORDERED) {
         return;
     }
     $newValue = $block->getOrderInSequence();
     $blocks = $parent->getChildrenAsSortedList();
     $blocks = array_filter($blocks, function ($sibling) use($block) {
         return $sibling->getId() !== $block->getId();
     });
     $blocks = array_values($blocks);
     $minRange = 1;
     $maxRange = count($blocks) + 1;
     if ($newValue < $minRange || $newValue > $maxRange) {
         throw new \OutOfRangeException("The given order-in-sequence value {$newValue} falls outside the range {$minRange} - {$maxRange}.");
     }
     if ($oldValue === $newValue) {
         return;
     }
     array_splice($blocks, $block->getOrderInSequence() - 1, 0, [$block]);
     for ($i = 0, $n = count($blocks); $i < $n; $i++) {
         /* @var CurriculumInventorySequenceBlockInterface $current */
         $current = $blocks[$i];
         $j = $i + 1;
         if ($current->getId() !== $block && $current->getOrderInSequence() !== $j) {
             $current->setOrderInSequence($j);
             $manager->update($current, false, false);
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     // prevent this command to run on a non-empty user store.
     $existingUser = $this->userManager->findOneBy([]);
     if (!empty($existingUser)) {
         throw new \Exception('Sorry, at least one user record already exists. Cannot create a "first" user account.');
     }
     $schools = $this->schoolManager->findBy([], ['title' => 'ASC']);
     // check if any school data is present before invoking the form helper
     // to prevent the form from breaking on missing school data further downstream.
     if (empty($schools)) {
         throw new \Exception('No schools found. Please load schools into this Ilios instance first.');
     }
     $schoolId = $input->getOption('school');
     if (!$schoolId) {
         $schoolTitles = [];
         /* @var SchoolInterface $school */
         foreach ($schools as $school) {
             $schoolTitles[$school->getTitle()] = $school->getId();
         }
         $helper = $this->getHelper('question');
         $question = new ChoiceQuestion("What is this user's primary school?", array_keys($schoolTitles));
         $question->setErrorMessage('School %s is invalid.');
         $schoolTitle = $helper->ask($input, $output, $question);
         $schoolId = $schoolTitles[$schoolTitle];
     }
     $school = $this->schoolManager->findOneBy(['id' => $schoolId]);
     if (!$school) {
         throw new \Exception("School with id {$schoolId} could not be found.");
     }
     $email = $input->getOption('email');
     if (!$email) {
         $question = new Question("What is the user's Email Address? ");
         $question->setValidator(function ($answer) {
             if (!filter_var($answer, FILTER_VALIDATE_EMAIL)) {
                 throw new \RuntimeException("Email is not valid");
             }
             return $answer;
         });
         $email = $this->getHelper('question')->ask($input, $output, $question);
     }
     $user = $this->userManager->create();
     $user->setFirstName(self::FIRST_NAME);
     $user->setMiddleName(date('Y-m-d_h.i.s'));
     $user->setLastName(self::LAST_NAME);
     $user->setEmail($email);
     $user->setAddedViaIlios(true);
     $user->setEnabled(true);
     $user->setUserSyncIgnore(false);
     $user->addRole($this->userRoleManager->findOneBy(['title' => 'Developer']));
     $user->addRole($this->userRoleManager->findOneBy(['title' => 'Course Director']));
     $user->setSchool($school);
     $this->userManager->update($user);
     $authentication = $this->authenticationManager->create();
     $authentication->setUser($user);
     $user->setAuthentication($authentication);
     $encodedPassword = $this->passwordEncoder->encodePassword($user, self::PASSWORD);
     $authentication->setUsername(self::USERNAME);
     $authentication->setPasswordBcrypt($encodedPassword);
     $this->authenticationManager->update($authentication);
     $output->writeln('Success!');
     $output->writeln('A user account has been created.');
     $output->writeln(sprintf("You may now log in as '%s' with the password '%s'.", self::USERNAME, self::PASSWORD));
     $output->writeln('Please change this password as soon as possible.');
 }
 /**
  * {@inheritdoc}
  */
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $isDryRun = $input->getOption('dry-run');
     $alerts = $this->alertManager->findBy(['dispatched' => false, 'tableName' => 'offering']);
     if (!count($alerts)) {
         $output->writeln("<info>No undispatched offering alerts found.</info>");
         return;
     }
     $templateCache = [];
     $sent = 0;
     // email out change alerts
     /* @var AlertInterface $alert */
     foreach ($alerts as $alert) {
         $output->writeln("<info>Processing offering change alert {$alert->getId()}.</info>");
         $offering = $this->offeringManager->findOneBy(['id' => $alert->getTableRowId()]);
         if (!$offering) {
             $output->writeln("<warning>No offering with id {$alert->getTableRowId()}," . " unable to send change alert with id {$alert->getId()}.</warning>");
             continue;
         }
         // do not send alerts for deleted stuff.
         $deleted = !$offering->getSession() || !$offering->getSession()->getCourse() || !$offering->getSession()->getCourse()->getSchool();
         if ($deleted) {
             // @todo print another warning here? [ST 2015/09/30]
             continue;
         }
         $schools = $alert->getRecipients();
         if ($schools->isEmpty()) {
             $output->writeln("<error>No alert recipient for offering change alert {$alert->getId()}.</error>");
             continue;
         }
         // Technically, there could be multiple school as recipients to a given alert.
         // The db schema allows for it.
         // In practice, there is really only ever one school recipient.
         // So take the first one and run with it for determining recipients/rendering the email template.
         // [ST 2015/10/05]
         /* @var SchoolInterface $school */
         $school = $schools->first();
         $recipients = trim($school->getChangeAlertRecipients());
         if ('' === $recipients) {
             $output->writeln("<error>Recipient without email for offering change alert {$alert->getId()}.</error>");
             continue;
         }
         $recipients = array_map('trim', explode(',', $recipients));
         // get change alert history from audit logs
         $history = $this->auditLogManager->findBy(['objectId' => $alert->getId(), 'objectClass' => 'alert'], ['createdAt' => 'asc']);
         $history = array_filter($history, function (AuditLogInterface $auditLog) {
             $user = $auditLog->getUser();
             return isset($user);
         });
         $subject = $offering->getSession()->getCourse()->getExternalId() . ' - ' . $offering->getStartDate()->format('m/d/Y');
         if (!array_key_exists($school->getId(), $templateCache)) {
             $template = $this->getTemplatePath($school);
             $templateCache[$school->getId()] = $template;
         }
         $template = $templateCache[$school->getId()];
         $messageBody = $this->templatingEngine->render($template, ['alert' => $alert, 'history' => $history, 'offering' => $offering, 'timezone' => $this->timezone]);
         $message = \Swift_Message::newInstance()->setSubject($subject)->setTo($recipients)->setFrom($school->getIliosAdministratorEmail())->setContentType('text/plain')->setBody($messageBody)->setMaxLineLength(998);
         if ($isDryRun) {
             $output->writeln($message->getHeaders()->toString());
             $output->writeln($message->getBody());
         } else {
             $this->mailer->send($message);
         }
         $sent++;
     }
     if (!$isDryRun) {
         // Mark all alerts as dispatched, regardless as to whether an actual email
         // was sent or not.
         // This is consistent with the Ilios v2 implementation of this process.
         // @todo Reassess the validity of this step. [ST 2015/10/01]
         foreach ($alerts as $alert) {
             $alert->setDispatched(true);
             $this->alertManager->update($alert);
         }
         $dispatched = count($alerts);
         $output->writeln("<info>Sent {$sent} offering change alert notifications.</info>");
         $output->writeln("<info>Marked {$dispatched} offering change alerts as dispatched.</info>");
     }
 }