/** * @param string $title * @param int $newAcademicYear * @throws \Exception */ private function checkForDuplicateRollover($title, $newAcademicYear) { $duplicateCourses = $this->courseManager->findBy(['title' => $title, 'year' => $newAcademicYear]); if (!empty($duplicateCourses)) { throw new \Exception("Another course with the same title and academic year already exists." . " If the year is correct, consider setting a new course title with '--new-course-title' option."); } }
/** * {@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>"); } }