Skip to content

Commit

Permalink
Add support for per-category member count limits
Browse files Browse the repository at this point in the history
  • Loading branch information
jtojnar committed Apr 10, 2019
1 parent be52a96 commit e9d743c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 9 deletions.
47 changes: 39 additions & 8 deletions app/forms/TeamFormFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public function create(array $countries, CategoryData $categories, array $parame
$renderer = new Bs4FormRenderer();
$form->setRenderer($renderer);

$minMembers = $parameters['minMembers'];
$defaultMinMembers = $parameters['minMembers'];
$defaultMaxMembers = $parameters['maxMembers'];

$form->addProtection();
$form->addGroup('messages.team.info.label');
Expand All @@ -51,20 +52,50 @@ public function create(array $countries, CategoryData $categories, array $parame
}
}

$category->addRule(function(CategoryEntry $entry) use ($categories, $defaultMaxMembers) {
$category = $entry->getValue();
$maxMembers = $categories->getCategoryData()[$category]['maxMembers'] ?? $defaultMaxMembers;
$replicator = $entry->form['persons'];

return $maxMembers > iterator_count($replicator->getContainers());
}, 'messages.team.error.too_many_members_simple'); // TODO: add params like in add/remove buttons

$category->addRule(function(CategoryEntry $entry) use ($categories, $defaultMinMembers) {
$category = $entry->getValue();
$minMembers = $categories->getCategoryData()[$category]['minMembers'] ?? $defaultMinMembers;
$replicator = $entry->form['persons'];

return $minMembers < iterator_count($replicator->getContainers());
}, 'messages.team.error.too_few_members_simple');

$fields = $parameters['fields']['team'];
$form->addCustomFields($fields, $form);

$form->addTextArea('message', 'messages.team.message.label');

$form->setCurrentGroup();
$form->addSubmit('save', 'messages.team.action.register');
$form->addSubmit('add', 'messages.team.action.add')->setValidationScope([])->onClick[] = function(SubmitButton $button): void {
$button->parent['persons']->createOne();
$form->addSubmit('add', 'messages.team.action.add')->setValidationScope([])->onClick[] = function(SubmitButton $button) use ($categories, $defaultMaxMembers): void {
$category = $button->form['category']->getValue();
$maxMembers = $categories->getCategoryData()[$category]['maxMembers'] ?? $defaultMaxMembers;
$replicator = $button->parent['persons'];
if ($maxMembers > iterator_count($replicator->getContainers())) {
$replicator->createOne();
} else {
$button->form->addError(Html::el()->setText($this->translator->translate('messages.team.error.too_many_members', $maxMembers, ['category' => $category])));
}
};
$form->addSubmit('remove', 'messages.team.action.remove')->setValidationScope([])->onClick[] = function(SubmitButton $button): void {
$lastPerson = last($button->parent['persons']->getContainers());
if ($lastPerson) {
$button->parent['persons']->remove($lastPerson, true);
$form->addSubmit('remove', 'messages.team.action.remove')->setValidationScope([])->onClick[] = function(SubmitButton $button) use ($categories, $defaultMinMembers): void {
$category = $button->form['category']->getValue();
$minMembers = $categories->getCategoryData()[$category]['minMembers'] ?? $defaultMinMembers;
$replicator = $button->parent['persons'];
if ($minMembers < iterator_count($replicator->getContainers())) {
$lastPerson = last($button->parent['persons']->getContainers());
if ($lastPerson) {
$replicator->remove($lastPerson, true);
}
} else {
$button->form->addError(Html::el()->setText($this->translator->translate('messages.team.error.too_few_members', $minMembers, ['category' => $category])));
}
};

Expand All @@ -90,7 +121,7 @@ public function create(array $countries, CategoryData $categories, array $parame
$container['email']->setRequired()->addRule(Form::EMAIL);
$group->setOption('description', 'messages.team.person.isContact');
}
}, $minMembers, true);
}, $defaultMinMembers, true);

return $form;
}
Expand Down
4 changes: 4 additions & 0 deletions app/lang/messages.cs.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ team.list.entry.status.registered: "Přihláška registrována"
team.list.filter.status.registered: "Registrováno"
team.list.export.csv: "Exportovat (CSV)"
team.person.name.first.label: "Jméno:"
team.error.too_few_members: "one: Týmy v kategorii %category% musí mít nejméně %count% člena.|few: Týmy v kategorii %category% musí mít nejméně %count% členy.|other: Týmy v kategorii %category% musí mít nejméně %count% členů."
team.error.too_few_members_simple: "Týmy v této kategorii musí mít více členů."
team.error.too_many_members: "one: Týmy v kategorii %category% smí mít nejvýše %count% člena.|few: Týmy v kategorii %category% smí mít nejvýše %count% členy.|other: Týmy v kategorii %category% smí mít nejvýše %count% členů."
team.error.too_many_members_simple: "Týmy v této kategorii musí mít méně členů."
team.error.gender_mismatch: "Zvolená kategorie neodpovídá pohlaví členů týmu!"
team.person.gender.label: "Pohlaví:"
team.list: "Pro zobrazení čísla čipu SportIdent najeďte na člena týmu."
Expand Down
4 changes: 4 additions & 0 deletions app/lang/messages.en.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ team.list.entry.status.registered: "Entry registered"
team.list.filter.status.registered: "Registered"
team.list.export.csv: "Export (CSV)"
team.person.name.first.label: "First name:"
team.error.too_few_members: "one: Your team needs to have at least %count% member to register in category %category%.|other: Your team needs to have at least %count% members to register in category %category%."
team.error.too_few_members_simple: "Your team needs to have more members to register in this category."
team.error.too_many_members: "one: Your team can have at most %count% member to register in category %category%.|other: Your team can have at most %count% members to register in category %category%."
team.error.too_many_members_simple: "Your team needs less members to register in this category."
team.error.gender_mismatch: "Gender category does not match gender of team members!"
team.person.gender.label: "Gender:"
team.list: "Hover name of a team member to display SportIdent card number."
Expand Down
4 changes: 4 additions & 0 deletions app/model/CategoryData.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ public function getCategoryTree(): array {
'label' => $categoryKey,
'fee' => $fee,
'constraints' => $this->parseConstraints($category),
'minMembers' => $category['minMembers'] ?? null,
'maxMembers' => $category['maxMembers'] ?? null,
];

if (isset($this->categoryData[$categoryKey])) {
Expand Down Expand Up @@ -181,6 +183,8 @@ public function getCategoryTree(): array {
'label' => $categoryKey,
'fee' => $fee,
'constraints' => $this->parseConstraints($category),
'minMembers' => $category['minMembers'] ?? null,
'maxMembers' => $category['maxMembers'] ?? null,
];
}, array_keys($categories));

Expand Down
15 changes: 14 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ closing: 2017-11-01T01:00:00
# whether to urge people to use e-mail after registration period (defaults to false)
allowLateRegistrationsByEmail: true
# constraints on number of team members
# constraints on number of team members (can be overridden in each category individually)
minMembers: 2
maxMembers: 3
Expand Down Expand Up @@ -95,6 +95,19 @@ Prices will be displayed in choosen currency on the invoice and in the administr

This section defines the categories entrants can choose from. The `categories` section can be either nested or flat. Each category defines a set of constraints that need to be satisfied in order for the team to be able to register in the category.

Categories can also narrow down the minimum and maximum number of team members:

```neon
parameters:
entries:
minMembers: 1
maxMembers: 5
categories:
'MM':
minMembers: 2
maxMembers: 2
```

###### Category constraints
Each constraint is a simple expression consisting of either a predicate

Expand Down

0 comments on commit e9d743c

Please sign in to comment.