Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Training: Improve getNextTrainings and fix deleting trainings #1158

Merged
merged 1 commit into from
Jan 16, 2025
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
10 changes: 1 addition & 9 deletions application/modules/training/boxes/Nexttraining.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

use Modules\Training\Mappers\Training as TrainingMapper;
use Modules\Training\Mappers\Entrants as EntrantsMapper;
use Modules\Training\Models\Training as TrainingModel;
use Modules\User\Mappers\User as UserMapper;

class Nexttraining extends \Ilch\Box
Expand All @@ -31,15 +30,8 @@ public function render()
}
}

// Get trainings, calculate next date if it's a recurrent event and sort them by date.
$trainings = $trainingMapper->getNextTrainings($config->get('training_boxNexttrainingLimit') ?? 5, $groupIds);
foreach ($trainings as $training) {
$trainingMapper->calculateNextTrainingDate($training);
}
usort($trainings, fn(TrainingModel $a, TrainingModel $b) => strcmp($a->getDate(), $b->getDate()));

$this->getView()->set('trainingMapper', $trainingMapper)
->set('entrantsMapper', $entrantsMapper)
->set('trainings', $trainings);
->set('trainings', $trainingMapper->getNextTrainings($config->get('training_boxNexttrainingLimit') ?? 5, $groupIds));
}
}
6 changes: 3 additions & 3 deletions application/modules/training/controllers/admin/Index.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ public function indexAction()
$trainingMapper = new TrainingMapper();
$this->getLayout()->getAdminHmenu()
->add($this->getTranslator()->trans('menuTraining'), ['action' => 'index']);
if ($this->getRequest()->getPost('check_training') && $this->getRequest()->getPost('action') === 'delete') {
foreach ($this->getRequest()->getPost('check_training') as $trainingId) {
if ($this->getRequest()->getPost('check_trainings') && $this->getRequest()->getPost('action') === 'delete') {
foreach ($this->getRequest()->getPost('check_trainings') as $trainingId) {
$trainingMapper->delete($trainingId);
}
$this->redirect()
->withMessage('deleteSuccess')
->to(['action' => 'index']);
}

$this->getView()->set('training', $trainingMapper->getEntriesBy());
$this->getView()->set('trainings', $trainingMapper->getEntriesBy());
}

public function treatAction()
Expand Down
70 changes: 39 additions & 31 deletions application/modules/training/mappers/Training.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,37 +176,52 @@ public function getTrainingsListWithLimt(?int $limit = null, $groupIds = '3', st
*
* @param int|null $limit
* @param string|array|null $groupIds A string like '1,2,3' or an array like [1,2,3]
* @param string $order ASC|DESC
* @return TrainingModel[]|null
* @since Version 1.10.0
*/
public function getNextTrainings(?int $limit = null, $groupIds = '3', string $order = 'ASC'): ?array
public function getNextTrainings(?int $limit = null, $groupIds = '3'): ?array
{
$pagination = new Pagination();

if ($limit) {
$pagination = new Pagination();
$pagination->setRowsPerPage($limit);
}

$currentDate = new \Ilch\Date();
$currentDate->format("Y-m-d H:i:s");
$select = $this->db()->select();

// Get all recurrent trainings with a repeat until date not in the past.
$where = [
't.period_type !=' => '',
't.repeat_until >' => $currentDate,
'ra.read_access' => $groupIds
];
$recurrentTrainings = $this->getEntriesBy($where) ?? [];

// Calculate next training dates for the recurrent trainings.
foreach ($recurrentTrainings as $training) {
$this->calculateNextTrainingDate($training);
}

// Get the next trainings. Taking the limit into account.
$where = [
$select->orX([
$select->andX([
't.period_type !=' => '',
't.repeat_until >' => $currentDate,
]
),
$select->andX([
't.period_type =' => '',
't.date >=' => $currentDate,
]
),
]),
't.period_type =' => '',
't.date >=' => $currentDate,
'ra.read_access' => $groupIds
];

return $this->getEntriesBy($where, ['t.date' => $order], $pagination ?? null);
$trainings = array_merge($recurrentTrainings, $this->getEntriesBy($where, ['t.date' => 'ASC'], $pagination ?? null) ?? []);

// Sort all trainings by date.
usort($trainings, fn(TrainingModel $a, TrainingModel $b) => strcmp($a->getDate(), $b->getDate()));

// If there is a limit then only return the number of trainings according to the limit as there
// might be more results than needed.
if ($limit) {
return array_slice($trainings, 0, $limit);
}

return $trainings;
}

/**
Expand Down Expand Up @@ -248,31 +263,26 @@ public function countdown(\Ilch\Date $countdown_date, int $countdown_time = 60)
}

/**
* Calculate the next training date.
* Calculate the next training date. Updates the passed parameter.
*
* @param TrainingModel $training
* @return TrainingModel
* @return void
* @throws \DateMalformedPeriodStringException
* @since Version 1.10.0
*/
public function calculateNextTrainingDate(TrainingModel $training): TrainingModel
public function calculateNextTrainingDate(TrainingModel $training)
{
// Early return if this is not a recurrent training.
if ($training->getPeriodType() === '') {
return $training;
return;
}

$givenDate = new \Ilch\Date();
$begin = new \Ilch\Date($training->getDate());

// Early return if the date is still in the future.
if ($begin > $givenDate) {
return $training;
}

// Early return if the repeat until date is in the past.
if ($givenDate > new \Ilch\Date($training->getRepeatUntil())) {
return $training;
// Early return if the date is still in the future or if the repeat until date is in the past.
if ($begin > $givenDate || ($givenDate > new \Ilch\Date($training->getRepeatUntil()))) {
return;
}

$interval = null;
Expand Down Expand Up @@ -337,8 +347,6 @@ public function calculateNextTrainingDate(TrainingModel $training): TrainingMode
$training->setEnd($date->format('Y-m-d H:i:s'));
break;
}

return $training;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion application/modules/training/models/Training.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Training extends \Ilch\Model
protected int $periodDay = 0;

/**
* period day of the training.
* period type of the training.
*
* @var string
*/
Expand Down
10 changes: 5 additions & 5 deletions application/modules/training/views/admin/index/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

/** @var \Ilch\View $this */

/** @var \Modules\Training\Models\Training[]|null $training */
$training = $this->get('training');
/** @var \Modules\Training\Models\Training[]|null $trainings */
$trainings = $this->get('trainings');

$periodDays = [
'1' => $this->getTranslator()->trans('Monday'),
Expand All @@ -24,7 +24,7 @@
];
?>
<h1><?=$this->getTrans('manage') ?></h1>
<?php if ($training) : ?>
<?php if ($trainings) : ?>
<form method="POST" action="">
<?=$this->getTokenField() ?>
<div class="table-responsive">
Expand All @@ -41,7 +41,7 @@
</colgroup>
<thead>
<tr>
<th><?=$this->getCheckAllCheckbox('check_training') ?></th>
<th><?=$this->getCheckAllCheckbox('check_trainings') ?></th>
<th></th>
<th></th>
<th><?=$this->getTrans('start') ?></th>
Expand All @@ -52,7 +52,7 @@
</tr>
</thead>
<tbody>
<?php foreach ($training as $model) :
<?php foreach ($trainings as $model) :
$datecreate = '';
if ($model->getDate()) {
$date = new \Ilch\Date($model->getDate());
Expand Down