Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
af98d0d1d4 |
@@ -30,6 +30,6 @@ Szkielet komponentu Joomla 6 do gromadzenia pytań testowych.
|
||||
|
||||
## Instalacja
|
||||
|
||||
W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.42.9).
|
||||
W Joomla wybierz **System → Install → Install from Folder** i wskaż ten katalog. Manifestem instalacyjnym jest `com_testquestions.xml` (wersja 1.43.0).
|
||||
|
||||
Po instalacji komponent jest dostępny w panelu administratora jako **Pytania testowe**.
|
||||
|
||||
@@ -69,6 +69,10 @@ COM_TESTQUESTIONS_AI_SETTINGS_MENU="Konfiguracja AI"
|
||||
COM_TESTQUESTIONS_AI_SETTINGS_SAVED="Ustawienia AI zapisano."
|
||||
COM_TESTQUESTIONS_AI_SAVE_FAILED="Nie udało się zapisać ustawień AI."
|
||||
COM_TESTQUESTIONS_AI_PROVIDER_INVALID="Wybierz prawidłowego dostawcę AI."
|
||||
COM_TESTQUESTIONS_AI_EVALUATE_ALL="AI — oceń wszystkie niezaliczone pytania otwarte (%s)"
|
||||
COM_TESTQUESTIONS_AI_BULK_DONE="AI oceniło %s pytań."
|
||||
COM_TESTQUESTIONS_AI_BULK_PARTIAL="AI oceniło %s pytań; nie udało się ocenić %s. Błąd: %s"
|
||||
COM_TESTQUESTIONS_AI_NO_OPEN_QUESTIONS="Brak niezaliczonych pytań otwartych do oceny AI."
|
||||
COM_TESTQUESTIONS_AI_EVALUATE="AI"
|
||||
COM_TESTQUESTIONS_AI_RESULT="Ocena AI"
|
||||
COM_TESTQUESTIONS_AI_NOT_CONFIGURED="Skonfiguruj dostawcę i klucz API w ustawieniach komponentu."
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
-- No database changes required for version 1.43.0.
|
||||
@@ -63,6 +63,47 @@ class ResultController extends BaseController
|
||||
);
|
||||
}
|
||||
|
||||
public function aiAll(): void
|
||||
{
|
||||
if (!Session::checkToken()) {
|
||||
throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403);
|
||||
}
|
||||
|
||||
$input = Factory::getApplication()->getInput();
|
||||
$id = $input->post->getInt('id');
|
||||
$message = '';
|
||||
$type = 'message';
|
||||
|
||||
try {
|
||||
$summary = $this->getModel('Result')->evaluateAllWithAi($id);
|
||||
if ($summary['failed'] > 0) {
|
||||
$message = Text::sprintf(
|
||||
'COM_TESTQUESTIONS_AI_BULK_PARTIAL',
|
||||
$summary['evaluated'],
|
||||
$summary['failed'],
|
||||
$summary['first_error']
|
||||
);
|
||||
$type = 'warning';
|
||||
} else {
|
||||
$message = Text::sprintf('COM_TESTQUESTIONS_AI_BULK_DONE', $summary['evaluated']);
|
||||
}
|
||||
} catch (\Throwable $error) {
|
||||
$errorMessage = $error->getMessage();
|
||||
$message = $errorMessage === 'AI_NO_OPEN_QUESTIONS'
|
||||
? Text::_('COM_TESTQUESTIONS_AI_NO_OPEN_QUESTIONS')
|
||||
: ($errorMessage === 'AI_NOT_CONFIGURED'
|
||||
? Text::_('COM_TESTQUESTIONS_AI_NOT_CONFIGURED')
|
||||
: Text::sprintf('COM_TESTQUESTIONS_AI_ERROR', $errorMessage));
|
||||
$type = 'error';
|
||||
}
|
||||
|
||||
$this->setRedirect(
|
||||
Route::_('index.php?option=com_testquestions&view=result&id=' . $id, false),
|
||||
$message,
|
||||
$type
|
||||
);
|
||||
}
|
||||
|
||||
private function saveAssessment(): void
|
||||
{
|
||||
if (!Session::checkToken()) {
|
||||
|
||||
@@ -153,4 +153,51 @@ class ResultModel extends BaseDatabaseModel
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
|
||||
public function evaluateAllWithAi(int $id): array
|
||||
{
|
||||
$item = $this->getItem($id);
|
||||
|
||||
if (!$item) {
|
||||
throw new \RuntimeException('Nie znaleziono zapisanego testu.');
|
||||
}
|
||||
|
||||
$questionIds = [];
|
||||
foreach ($item->answers as $questionId => $answer) {
|
||||
$question = $item->questions[(int) $questionId] ?? null;
|
||||
if ($question && $question->question_type === 'open' && empty($answer['correct'])) {
|
||||
$questionIds[] = (int) $questionId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$questionIds) {
|
||||
throw new \RuntimeException('AI_NO_OPEN_QUESTIONS');
|
||||
}
|
||||
|
||||
$evaluated = 0;
|
||||
$failed = 0;
|
||||
$firstError = '';
|
||||
|
||||
foreach ($questionIds as $questionId) {
|
||||
try {
|
||||
$this->evaluateWithAi($id, $questionId);
|
||||
$evaluated++;
|
||||
} catch (\Throwable $error) {
|
||||
$failed++;
|
||||
$firstError = $firstError ?: $error->getMessage();
|
||||
|
||||
if (in_array($error->getMessage(), ['AI_NOT_CONFIGURED'], true)
|
||||
|| str_starts_with($error->getMessage(), 'AI_KEY_EMPTY|')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'evaluated' => $evaluated,
|
||||
'failed' => $failed,
|
||||
'first_error' => $firstError,
|
||||
'total' => count($questionIds),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,18 @@
|
||||
<dd class="col-sm-9"><?php echo floor((int) $this->item->execution_time / 60); ?>:<?php echo str_pad((string) ((int) $this->item->execution_time % 60), 2, '0', STR_PAD_LEFT); ?></dd>
|
||||
</dl>
|
||||
<form action="<?php echo Route::_('index.php?option=com_testquestions&view=result&id=' . (int) $this->item->id); ?>" method="post" name="adminForm" id="adminForm">
|
||||
<?php $pendingAiCount = 0; ?>
|
||||
<?php foreach ($this->item->answers as $questionId => $answer) : ?>
|
||||
<?php $candidate = $this->item->questions[(int) $questionId] ?? null; ?>
|
||||
<?php if ($candidate && $candidate->question_type === 'open' && empty($answer['correct'])) { $pendingAiCount++; } ?>
|
||||
<?php endforeach; ?>
|
||||
<?php if ($pendingAiCount > 0) : ?>
|
||||
<div class="mb-3">
|
||||
<button type="submit" class="btn btn-primary" formaction="<?php echo Route::_('index.php?option=com_testquestions&task=result.aiAll&id=' . (int) $this->item->id); ?>" onclick="this.form.task.value='result.aiAll';">
|
||||
<?php echo \Joomla\CMS\Language\Text::sprintf('COM_TESTQUESTIONS_AI_EVALUATE_ALL', $pendingAiCount); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<h2><?php echo \Joomla\CMS\Language\Text::_('COM_TESTQUESTIONS_RESULT_ANSWERS'); ?></h2>
|
||||
<?php foreach ($this->item->answers as $questionId => $answer) : ?>
|
||||
<?php $question = $this->item->questions[(int) $questionId] ?? null; if (!$question) continue; ?>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<creationDate>2026-10-14</creationDate>
|
||||
<author>Komponent</author>
|
||||
<license>GNU General Public License version 2 or later</license>
|
||||
<version>1.42.9</version>
|
||||
<version>1.43.0</version>
|
||||
<description>COM_TESTQUESTIONS_DESCRIPTION</description>
|
||||
<element>com_testquestions</element>
|
||||
<namespace path="src">Komponent\Component\Testquestions</namespace>
|
||||
|
||||
Reference in New Issue
Block a user