<commit_before><?php

namespace Ilios\CliBundle\Command;

use Ilios\CliBundle\Form\InstallFirstUserType;
use Ilios\CoreBundle\Entity\Manager\ManagerInterface;

use Ilios\CoreBundle\Entity\SchoolInterface;
use Matthias\SymfonyConsoleForm\Console\Helper\FormHelper;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * Creates a first user account with Course Director privileges.
 *
 * Class InstallFirstUserCommand
 * @package Ilios\CoreBundle\Command
 */
class InstallFirstUserCommand extends Command
{
    /**
     * @var string
     */
    const USERNAME = 'first_user';

    /**
     * @var string
     */
    const PASSWORD = '<PASSWORD>';

    /**
     * @var string
     */
    const FIRST_NAME = 'First';

    /**
     * @var string
     */
    const LAST_NAME = 'User';

    /**
     * @var ManagerInterface
     */
    protected $userManager;

    /**
     * @var ManagerInterface
     */
    protected $schoolManager;

    /**
     * @var ManagerInterface
     */
    protected $userRoleManager;

    /**
     * @var  ManagerInterface
     */
    protected $authenticationManager;

    /**
     * @var UserPasswordEncoderInterface
     */
    protected $passwordEncoder;

    /**
     * Constructor.
     * @param ManagerInterface $userManager
     * @param ManagerInterface $schoolManager
     * @param ManagerInterface $userRoleManager
     * @param ManagerInterface $authenticationManager
     * @param UserPasswordEncoderInterface $passwordEncoder
     */
    public function __construct(
        ManagerInterface $userManager,
        ManagerInterface $schoolManager,
        ManagerInterface $userRoleManager,
        ManagerInterface $authenticationManager,
        UserPasswordEncoderInterface $passwordEncoder
    ) {
        $this->userManager = $userManager;
        $this->schoolManager = $schoolManager;
        $this->userRoleManager = $userRoleManager;
        $this->authenticationManager = $authenticationManager;
        $this->passwordEncoder = $passwordEncoder;
        parent::__construct();
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('ilios:setup:first-user')
            ->setDescription('Creates a first user account with "Course Director" privileges.')
            ->addOption(
                'school',
                null,
                InputOption::VALUE_REQUIRED,
                'A valid school id.'
            )
            ->addOption(
                'email',
                null,
                InputOption::VALUE_REQUIRED,
                'A valid email address.'
            );
    }

    /**
     * {@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.'
            );
        }

        $schoolEntities = $this->schoolManager->findBy([]);

        // 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($schoolEntities)) {
            throw new \Exception('No schools found. Please load schools into this Ilios instance first.');
        }

        // transform school data into a format that can be processed by the form.
        $schools = [];
        /* @var SchoolInterface $entity */
        foreach ($schoolEntities as $entity) {
            $schools[$entity->getId()] = $entity->getTitle();
        }

        /** @var FormHelper $formHelper */
        $formHelper = $this->getHelper('form');
        $formData = $formHelper->interactUsingForm(
            new InstallFirstUserType($schools),
            $input,
            $output
        );

        $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($formData['email']);
        $user->setAddedViaIlios(true);
        $user->setEnabled(true);
        $user->setUserSyncIgnore(false);

        $user->addRole($this->userRoleManager->findOneBy(['title' => 'Developer']));
        $user->setSchool($this->schoolManager->findOneBy(['id' => $formData['school']]));
        $this->userManager->update($user);

        $authentication = $this->authenticationManager->create();

        $authentication->setUser($user);
        $user->setAuthentication($authentication); // circular reference needed here. 123 BLEAH! [ST 2015/08/31]

        $encodedPassword = $this->passwordEncoder->encodePassword($user, self::PASSWORD);
<commit_msg>replaced hinky form helper with legit question helpers.<commit_after><?php

namespace Ilios\CliBundle\Command;

use Ilios\CoreBundle\Entity\Manager\ManagerInterface;

use Ilios\CoreBundle\Entity\SchoolInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

/**
 * Creates a first user account with Course Director privileges.
 *
 * Class InstallFirstUserCommand
 * @package Ilios\CoreBundle\Command
 */
class InstallFirstUserCommand extends Command
{
    /**
     * @var string
     */
    const USERNAME = 'first_user';

    /**
     * @var string
     */
    const PASSWORD = '<PASSWORD>';

    /**
     * @var string
     */
    const FIRST_NAME = 'First';

    /**
     * @var string
     */
    const LAST_NAME = 'User';

    /**
     * @var ManagerInterface
     */
    protected $userManager;

    /**
     * @var ManagerInterface
     */
    protected $schoolManager;

    /**
     * @var ManagerInterface
     */
    protected $userRoleManager;

    /**
     * @var  ManagerInterface
     */
    protected $authenticationManager;

    /**
     * @var UserPasswordEncoderInterface
     */
    protected $passwordEncoder;

    /**
     * Constructor.
     * @param ManagerInterface $userManager
     * @param ManagerInterface $schoolManager
     * @param ManagerInterface $userRoleManager
     * @param ManagerInterface $authenticationManager
     * @param UserPasswordEncoderInterface $passwordEncoder
     */
    public function __construct(
        ManagerInterface $userManager,
        ManagerInterface $schoolManager,
        ManagerInterface $userRoleManager,
        ManagerInterface $authenticationManager,
        UserPasswordEncoderInterface $passwordEncoder
    ) {
        $this->userManager = $userManager;
        $this->schoolManager = $schoolManager;
        $this->userRoleManager = $userRoleManager;
        $this->authenticationManager = $authenticationManager;
        $this->passwordEncoder = $passwordEncoder;
        parent::__construct();
    }

    /**
     * {@inheritdoc}
     */
    protected function configure()
    {
        $this
            ->setName('ilios:setup:first-user')
            ->setDescription('Creates a first user account with "Course Director" privileges.')
            ->addOption(
                'school',
                null,
                InputOption::VALUE_REQUIRED,
                'A valid school id.'
            )
            ->addOption(
                'email',
                null,
                InputOption::VALUE_REQUIRED,
                'A valid email address.'
            );
    }

    /**
     * {@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->setSchool($school);
        $this->userManager->update($user);

        $authentication = $this->authenticationManager->create();

        $authentication->setUser($user);
        $user->setAuthentication($authentication);

        $encodedPassword = $this->passwordEncoder->encodePassword($user, self::PASSWORD);

{'fraction_non_alphanumeric': 0.12088510020857894, 'fraction_numerical': 0.000997551464586923, 'mean_word_length': 2.293906810035842, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 96, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6268251', 'n_tokens_mistral': 2947, 'n_tokens_neox': 2847, 'n_words': 632}