Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions assets/js/profile/preference.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const member = document.getElementById('member').value
const preferences = document.querySelectorAll( '.preference')

preferences.forEach(
async preference => {
preference.addEventListener('change', async (event) => {
let value = null
if (event.target.type === 'checkbox') {
value = event.target.checked
} else {
value = event.target.value
}

const form = new FormData();
form.append('member', member);
form.append('preference', preference.id.replace('preferences_', ''));
form.append('value', value);

await fetch("/members/update/preference", { method: 'POST', body: form })
.then(() => { /* Nothing to do here */ })

console.log(form)
})
}
)
1 change: 1 addition & 0 deletions assets/tailwindcss/tailwind.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

--radius-4: 4px;
--radius-5: 5px;
--radius-6: 6px;
--radius-8: 8px;
--radius-full: 100%;

Expand Down
33 changes: 20 additions & 13 deletions src/Command/MigrateDatabaseCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Exception;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
Expand Down Expand Up @@ -164,13 +165,15 @@ public function __construct(
$this->connection = $this->entityManager->getConnection();
}

public function __invoke(InputInterface $input, OutputInterface $output): int
public function __invoke(InputInterface $input, OutputInterface $output, #[Argument] int $offset): int
{
$this->io = new SymfonyStyle($input, $output);
$this->io->success('Migrating old profiles.');

$this->connection->executeStatement('SET FOREIGN_KEY_CHECKS=0;');
$this->connection->executeStatement('TRUNCATE `address`; TRUNCATE `member_translations`; TRUNCATE `member_language_level`; TRUNCATE `friend`; TRUNCATE `member`;');
if (0 === $offset) {
$this->connection->executeStatement('SET FOREIGN_KEY_CHECKS=0;');
$this->connection->executeStatement('TRUNCATE `address`; TRUNCATE `member_translations`; TRUNCATE `member_language_level`; TRUNCATE `friend`; TRUNCATE `member`;');
}

$sql = "SELECT COUNT(m.id) FROM members m WHERE m.status IN ('" . implode("', '", self::MIGRATED_STATUSES) . "')";

Expand All @@ -190,24 +193,24 @@ public function __invoke(InputInterface $input, OutputInterface $output): int
}

$this->errorMembers = [];
$batchSize = 2000;
$batchSize = 20000;

$this->progressBar = new ProgressBar($output, $countOfMembers);
$this->progressBar = new ProgressBar($output, $batchSize);
$this->progressBar->setFormat(
"<fg=white;bg=green>\n %info:-60s% \n</>\n%current%/%max% [%bar%] %percent:3s%%\n%elapsed:-10% %%estimated:-10s% %memory:20s%\nLast error: %error%"
"<fg=white;bg=green>\n %info:-60s% \n</>\n%current%/%max% [%bar%] %percent:3s%%\n%elapsed:-10s% %estimated:-10s% %memory:20s%\nLast error: %error%"
);
$this->progressBar->setMessage("Migrating {$countOfMembers} members to new member table including translations.", 'info');
$this->progressBar->setMessage("Migrating {$countOfMembers} members starting at {$offset} to new member table including translations.", 'info');
$this->progressBar->setMessage('none', 'error');
$this->progressBar->minSecondsBetweenRedraws(10.0);
$this->progressBar->start();

// Make sure the tables member and member_translations are empty

try {
for ($current = 0; $current < $countOfMembers; $current += $batchSize) {
$this->migrateMembersData($current, $batchSize);
}
$this->reportErrors();
// for ($current = 0; $current < $countOfMembers; $current += $batchSize) {
$this->migrateMembersData($offset, $batchSize);
// }
$this->reportErrors($offset);
} finally {
$this->connection->executeStatement('SET FOREIGN_KEY_CHECKS=1;');
}
Expand Down Expand Up @@ -243,6 +246,7 @@ private function migrateMembersData(int $current, int $batchSize): void
$this->progressBar->advance();
unset($member);
}
unset($members);
}

private function migrateMemberData(array $member): void
Expand Down Expand Up @@ -345,6 +349,8 @@ private function migrateMemberAddress(mixed $member): void
} catch (Exception $e) {
$this->progressBar->setMessage($member['Username'], 'error');
$this->addErrorAddress($member, $e->getMessage());
} finally {
$this->entityManager->detach($city);
}
}

Expand Down Expand Up @@ -402,6 +408,7 @@ private function migrateMemberTranslations(array $member): void
}
}
}
unset($processedTranslations, $memberTranslations);

$values = substr($queryString, 2);

Expand Down Expand Up @@ -669,10 +676,10 @@ private function migrateLanguageLevel(string $level): string
}
}

private function reportErrors(): void
private function reportErrors(int $offset): void
{
if (!empty($this->errorMembers)) {
$file = fopen('migrateMembers.errors.txt', 'w');
$file = fopen("migrateMembers.errors-{$offset}.txt", 'w');
$countOfErrorMembers = 0;
foreach ($this->errorMembers as $errors) {
$countOfErrorMembers += \count($errors);
Expand Down
71 changes: 51 additions & 20 deletions src/Controller/PreferenceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,27 @@
namespace App\Controller;

use App\Entity\Member;
use App\Entity\Preference;
use App\Form\PreferencesType;
use App\Model\PreferenceModel;
use App\Utilities\ChangeProfilePictureGlobals;
use App\Utilities\ProfileSubmenu;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class PreferenceController extends AbstractController
{
public function __construct(
private readonly PreferenceModel $preferenceModel,
private readonly EntityManagerInterface $entityManager,
) {
}

#[Route(path: '/mypreferences', name: 'mypreferences_redirect')]
public function redirectMyPreferences(): RedirectResponse
{
Expand All @@ -27,9 +35,7 @@ public function preferences(
Request $request,
Member $member,
ProfileSubmenu $profileSubmenu,
PreferenceModel $preferenceModel,
ChangeProfilePictureGlobals $globals,
EntityManagerInterface $entityManager,
): Response {
/** Member must be the logged in member to be able to access this page.
* @var Member $loggedInMember
Expand All @@ -39,8 +45,8 @@ public function preferences(
return $this->redirectToRoute('preferences', ['username' => $loggedInMember->getUsername()]);
}

$preferences = $preferenceModel->getPreferences();
$memberPreferences = $preferenceModel->getMemberPreferences($loggedInMember, $preferences);
$preferences = $this->preferenceModel->getPreferences();
$memberPreferences = $this->preferenceModel->getMemberPreferences($loggedInMember, $preferences);
$data = [];
foreach ($memberPreferences as $memberPreference) {
$preference = $memberPreference->getPreference();
Expand All @@ -50,30 +56,55 @@ public function preferences(
$preferenceForm = $this->createForm(PreferencesType::class, $data, [
'preferences' => $preferences,
]);
$preferenceForm->handleRequest($request);

if ($preferenceForm->isSubmitted() && $preferenceForm->isValid()) {
$data = $preferenceForm->getData();

foreach ($memberPreferences as $memberPreference) {
$preference = $memberPreference->getPreference();

$memberPreference->setValue($data[$preference->getCodename()]);
$entityManager->persist($memberPreference);
}
$entityManager->flush();

return $this->redirectToRoute('members_profile', ['username' => $loggedInMember->getUsername()]);
}

return $this->render('preference/preference.html.twig', [
'member' => $loggedInMember,
'form' => $preferenceForm->createView(),
'form' => $preferenceForm,
'preferences' => $preferences,
'globals_js_json' => $globals->getGlobalsJsAsJson($loggedInMember, $member),
'submenu' => $profileSubmenu->getSubmenu($loggedInMember, $member, [
'active' => 'preferences',
]),
]);
}

#[Route(path: '/members/update/preference', name: 'profile_update_preference', methods: ['POST'], priority: 20)]
public function updatePreference(Request $request): Response
{
$form = $this->createFormBuilder(options: ['csrf_protection' => false])
->add('member', TextType::class)
->add('preference', TextType::class)
->add('value', TextType::class)
->getForm();

$form->submit($request->request->all());
if ($form->isSubmitted() && $form->isValid()) {
$loggedInMember = $this->getUser();
$data = $form->getData();
$memberRepository = $this->entityManager->getRepository(Member::class);
$member = $memberRepository->findOneBy(['username' => $data['member']]);

// Check if user exists and if logged in member is either same or privileged
if ($member === $loggedInMember) {
$preference = $this->entityManager
->getRepository(Preference::class)
->findOneBy(['codename' => $data['preference']])
;
$memberPreference = $member->getMemberPreference($preference);

$value = $data['value'];
if ('false' === $data['value'] || 'true' === $data['value']) {
$values = $preference->getPossibleValues();
$value = 'false' === $data['value'] ? $values[0] : $values[1];
}

$memberPreference->setValue($value);

$this->entityManager->persist($memberPreference);
$this->entityManager->flush();
}
}

return new Response();
}
}
5 changes: 3 additions & 2 deletions src/Controller/TripController.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ class TripController extends AbstractController
use TranslatedFlashTrait;
use TranslatorTrait;

public function __construct(private TripModel $tripModel)
{
public function __construct(
private readonly TripModel $tripModel,
) {
}

#[Route(path: '/trips/{page}', name: 'trips', requirements: ['page' => '\d+'])]
Expand Down
9 changes: 2 additions & 7 deletions src/Entity/Preference.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,14 +157,9 @@ public function getDefaultValue()
return $this->defaultValue;
}

/**
* Get possiblevalues.
*
* @return string
*/
public function getPossibleValues()
public function getPossibleValues(): array
{
return $this->possibleValues;
return explode(';', $this->possibleValues);
}

/**
Expand Down
48 changes: 27 additions & 21 deletions src/Form/PreferencesType.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,34 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
foreach ($preferences as $preference) {
$choices = $this->getChoices($preference);
if (2 === \count($choices)) {
// Create radio buttons
$fieldOptions = [
'expanded' => true,
];
$builder
->add($preference->getCodename(), SwitchType::class, [
'label' => strtolower($preference->getCodename()),
'help' => strtolower($preference->getCodedescription()),
'help_html' => true,
'choices' => $choices,
'default' => $preference->getDefaultValue(),
])
;
} else {
$fieldOptions = [
'expanded' => false,
];
$builder
->add($preference->getCodename(), ChoiceType::class, [
'attr' => [
'class' => 'preference',
],
'label' => strtolower($preference->getCodename()),
'help' => strtolower($preference->getCodedescription()),
'expanded' => false,
'help_html' => true,
'choices' => $choices,
'multiple' => false,
'required' => true,
'constraints' => [
new NotBlank(),
],
])
;
}
$builder
->add($preference->getCodename(), ChoiceType::class, array_merge($fieldOptions, [
'label' => strtolower($preference->getCodename()),
'help' => strtolower($preference->getCodedescription()),
'help_html' => true,
'choices' => $choices,
'multiple' => false,
'required' => true,
'constraints' => [
new NotBlank(),
],
]))
;
}
}

Expand All @@ -57,7 +63,7 @@ public function configureOptions(OptionsResolver $resolver): void

private function getChoices(Preference $preference): array
{
$possibleValues = explode(';', $preference->getPossibleValues());
$possibleValues = $preference->getPossibleValues();
$values = [];
foreach ($possibleValues as $value) {
$values[strtolower($preference->getCodename() . $value)] = $value;
Expand Down
Loading
Loading