Minor: Format code

pull/6061/head
Angel Fernando Quiroz Campos 7 months ago
parent 66d70728a6
commit b2e808aacd
No known key found for this signature in database
GPG Key ID: B284841AE3E562CD
  1. 1
      main/auth/external_login/facebook.inc.php
  2. 38
      main/auth/external_login/functions.inc.php
  3. 4
      main/exercise/export/aiken/aiken_import.inc.php
  4. 2
      main/inc/lib/Compilatio.php
  5. 2
      main/inc/lib/api.lib.php
  6. 3
      main/inc/lib/formvalidator/Element/HtmlEditor.php
  7. 7
      main/inc/lib/glossary.lib.php
  8. 2
      main/lp/LpAiHelper.php
  9. 4
      main/lp/learnpath.class.php
  10. 1
      main/session/resume_session.php
  11. 130
      plugin/ai_helper/AiHelperPlugin.php
  12. 12
      plugin/ai_helper/src/deepseek/DeepSeek.php
  13. 2
      plugin/ai_helper/src/deepseek/DeepSeekUrl.php
  14. 3
      plugin/ai_helper/tool/answers.php
  15. 1
      plugin/ai_helper/tool/learnpath.php
  16. 46
      plugin/azure_active_directory/src/AzureActiveDirectory.php
  17. 6
      plugin/azure_active_directory/src/Entity/AzureSyncState.php

@ -171,7 +171,6 @@ function facebookConnect()
/**
* Get facebook login url for the platform.
*
* @return string
* @throws FacebookSDKException
*/
function facebookGetLoginUrl(): string

@ -166,25 +166,25 @@ function external_add_user($u)
* new_user array.
*
* @param array $new_user associative array with the value to upgrade
* WARNING user_id key is MANDATORY
* Possible keys are :
* - firstname
* - lastname
* - username
* - auth_source
* - email
* - status
* - official_code
* - phone
* - picture_uri
* - expiration_date
* - active
* - creator_id
* - hr_dept_id
* - extra : array of custom fields
* - language
* - courses : string of all courses code separated by '|'
* - admin : boolean
* WARNING user_id key is MANDATORY
* Possible keys are :
* - firstname
* - lastname
* - username
* - auth_source
* - email
* - status
* - official_code
* - phone
* - picture_uri
* - expiration_date
* - active
* - creator_id
* - hr_dept_id
* - extra : array of custom fields
* - language
* - courses : string of all courses code separated by '|'
* - admin : boolean
*
* @author ndiechburg <noel@cblue.be>
* */

@ -70,7 +70,7 @@ function generateAikenForm()
if ($hasSingleApi) {
$apiName = $availableApis[$configuredApi] ?? $configuredApi;
$form->addHtml('<div style="margin-bottom: 10px; font-size: 14px; color: #555;">'
. sprintf(get_lang('UsingAIProviderX'), '<strong>'.htmlspecialchars($apiName).'</strong>').'</div>');
.sprintf(get_lang('UsingAIProviderX'), '<strong>'.htmlspecialchars($apiName).'</strong>').'</div>');
}
$form->addElement('text', 'quiz_name', get_lang('QuestionsTopic'));
@ -105,7 +105,7 @@ function generateAikenForm()
var quizName = $("[name=\'quiz_name\']").val();
var nroQ = parseInt($("[name=\'nro_questions\']").val());
var qType = $("[name=\'question_type\']").val();'
. (!$hasSingleApi ? 'var provider = $("[name=\'ai_provider\']").val();' : 'var provider = "' . $configuredApi . '";') .
.(!$hasSingleApi ? 'var provider = $("[name=\'ai_provider\']").val();' : 'var provider = "'.$configuredApi.'";').
'var valid = (quizName != \'\' && nroQ > 0);
if (valid) {
btnGenerate.attr("disabled", true);

@ -208,7 +208,7 @@ class Compilatio
if (isset($dataDocument['analyses'][$anasim]['state'])) {
$documentInfo['analysis_status'] = $dataDocument['analyses'][$anasim]['state'];
}
if (isset($dataDocument['light_reports'][$anasim]['scores']['global_score_percent'])) {
$documentInfo['report_percent'] = $dataDocument['light_reports'][$anasim]['scores']['global_score_percent'];
}

@ -4033,7 +4033,7 @@ function api_not_allowed(
// Check if a custom file (login.tpl) exists for custompages included overrides
if ((!isset($user_id) || api_is_anonymous()) && CustomPages::enabled()) {
$customLoginTemplate = Template::findTemplateFilePath('custompage/login.tpl');
if (file_exists(api_get_path(SYS_TEMPLATE_PATH) . $customLoginTemplate)) {
if (file_exists(api_get_path(SYS_TEMPLATE_PATH).$customLoginTemplate)) {
if (empty($_SESSION['request_uri'])) {
$_SESSION['request_uri'] = $_SERVER['REQUEST_URI'];
}

@ -112,9 +112,6 @@ class HtmlEditor extends HTML_QuickForm_textarea
return $result;
}
/**
* @return string|null
*/
public function getValue(): ?string
{
return RemoveOnAttributes::filter($this->_value);

@ -132,12 +132,11 @@ class GlossaryManager
* This functions stores the glossary in the database.
*
* @param array $values Array of title + description (name => $title, description => $comment)
* @param bool $showMessage
*
* @return bool|int Term id on success, false on failure
*
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*
* @return bool|int Term id on success, false on failure
*/
public static function save_glossary(array $values, bool $showMessage = true)
{
@ -170,7 +169,7 @@ class GlossaryManager
->setDescription($values['description'] ?? "")
->setDisplayOrder($max_glossary_item + 1)
->setSessionId($session_id);
;
Database::getManager()->persist($glossary);
Database::getManager()->flush();

@ -74,7 +74,7 @@ class LpAiHelper
var wordsCount = parseInt($("[name=\'words_count\']").val());
var addTests = $("#add-lp-quiz").is(":checked");
var nroQuestions = parseInt($("[name=\'nro_questions\']").val());
var provider = "' . $configuredApi . '";
var provider = "'.$configuredApi.'";
if (lpName && nroItems > 0 && wordsCount > 0) {
if (addTests && (nroQuestions <= 0 || nroQuestions > 5)) {

@ -4860,12 +4860,8 @@ class learnpath
/**
* Check if the learnpath category is visible for a user.
*
* @param CLpCategory|null $category
* @param User $user
* @param int $courseId
* @param int $sessionId
*
* @return bool
*/
public static function categoryIsVisibleForStudent(
?CLpCategory $category,

@ -370,6 +370,7 @@ if (!empty($userList)) {
$valueA = strtotime($a['registered_at']);
$valueB = strtotime($b['registered_at']);
}
return $sortOrder === SORT_ASC ? $valueA <=> $valueB : $valueB <=> $valueA;
});

@ -3,7 +3,8 @@
use Chamilo\PluginBundle\Entity\AiHelper\Requests;
use Doctrine\ORM\Tools\SchemaTool;
require_once __DIR__ . '/src/deepseek/DeepSeek.php';
require_once __DIR__.'/src/deepseek/DeepSeek.php';
/**
* Description of AiHelperPlugin.
*
@ -112,6 +113,7 @@ class AiHelperPlugin extends Plugin
if (isset($result['error'])) {
$errorMessage = $result['error']['message'] ?? 'Unknown error';
error_log("OpenAI Error: $errorMessage");
return [
'error' => true,
'message' => $errorMessage,
@ -132,11 +134,10 @@ class AiHelperPlugin extends Plugin
}
return $resultText ?: 'No response generated.';
} catch (Exception $e) {
return [
'error' => true,
'message' => 'An error occurred while connecting to OpenAI: ' . $e->getMessage(),
'message' => 'An error occurred while connecting to OpenAI: '.$e->getMessage(),
];
}
}
@ -179,8 +180,9 @@ class AiHelperPlugin extends Plugin
$response = curl_exec($ch);
if ($response === false) {
error_log('cURL error: ' . curl_error($ch));
error_log('cURL error: '.curl_error($ch));
curl_close($ch);
return ['error' => true, 'message' => 'Request to AI provider failed.'];
}
@ -211,12 +213,14 @@ class AiHelperPlugin extends Plugin
/**
* Generate questions based on the selected AI provider.
*
* @param int $nQ Number of questions
* @param string $lang Language for the questions
* @param string $topic Topic of the questions
* @param int $nQ Number of questions
* @param string $lang Language for the questions
* @param string $topic Topic of the questions
* @param string $questionType Type of questions (e.g., 'multiple_choice')
* @return string Questions generated in Aiken format
*
* @throws Exception If an error occurs
*
* @return string Questions generated in Aiken format
*/
public function generateQuestions(int $nQ, string $lang, string $topic, string $questionType = 'multiple_choice'): string
{
@ -232,61 +236,6 @@ class AiHelperPlugin extends Plugin
}
}
/**
* Generate questions using OpenAI.
*/
private function generateOpenAiQuestions(int $nQ, string $lang, string $topic, string $questionType): string
{
$prompt = sprintf(
'Generate %d "%s" questions in Aiken format in the %s language about "%s", making sure there is a \'ANSWER\' line for each question. \'ANSWER\' lines must only mention the letter of the correct answer, not the full answer text and not a parenthesis. The line starting with \'ANSWER\' must not be separated from the last possible answer by a blank line. Each answer starts with an uppercase letter, a dot, one space and the answer text without quotes. Include an \'ANSWER_EXPLANATION\' line after the \'ANSWER\' line for each question. The terms between single quotes above must not be translated. There must be a blank line between each question.',
$nQ,
$questionType,
$lang,
$topic
);
$result = $this->openAiGetCompletionText($prompt, 'quiz');
if (isset($result['error']) && true === $result['error']) {
throw new Exception($result['message']);
}
return $result;
}
/**
* Generate questions using DeepSeek.
*/
private function generateDeepSeekQuestions(int $nQ, string $lang, string $topic, string $questionType): string
{
$apiKey = $this->get('api_key');
$prompt = sprintf(
'Generate %d "%s" questions in Aiken format in the %s language about "%s", making sure there is a \'ANSWER\' line for each question. \'ANSWER\' lines must only mention the letter of the correct answer, not the full answer text and not a parenthesis. The line starting with \'ANSWER\' must not be separated from the last possible answer by a blank line. Each answer starts with an uppercase letter, a dot, one space and the answer text without quotes. Include an \'ANSWER_EXPLANATION\' line after the \'ANSWER\' line for each question. The terms between single quotes above must not be translated. There must be a blank line between each question.',
$nQ,
$questionType,
$lang,
$topic
);
$payload = [
'model' => 'deepseek-chat',
'messages' => [
[
'role' => 'system',
'content' => 'You are a helpful assistant that generates Aiken format questions.',
],
[
'role' => 'user',
'content' => $prompt,
],
],
'stream' => false,
];
$deepSeek = new DeepSeek($apiKey);
$response = $deepSeek->generateQuestions($payload);
return $response;
}
/**
* Validates tokens limit of a user per current month.
*/
@ -414,4 +363,59 @@ class AiHelperPlugin extends Plugin
]
);
}
/**
* Generate questions using OpenAI.
*/
private function generateOpenAiQuestions(int $nQ, string $lang, string $topic, string $questionType): string
{
$prompt = sprintf(
'Generate %d "%s" questions in Aiken format in the %s language about "%s", making sure there is a \'ANSWER\' line for each question. \'ANSWER\' lines must only mention the letter of the correct answer, not the full answer text and not a parenthesis. The line starting with \'ANSWER\' must not be separated from the last possible answer by a blank line. Each answer starts with an uppercase letter, a dot, one space and the answer text without quotes. Include an \'ANSWER_EXPLANATION\' line after the \'ANSWER\' line for each question. The terms between single quotes above must not be translated. There must be a blank line between each question.',
$nQ,
$questionType,
$lang,
$topic
);
$result = $this->openAiGetCompletionText($prompt, 'quiz');
if (isset($result['error']) && true === $result['error']) {
throw new Exception($result['message']);
}
return $result;
}
/**
* Generate questions using DeepSeek.
*/
private function generateDeepSeekQuestions(int $nQ, string $lang, string $topic, string $questionType): string
{
$apiKey = $this->get('api_key');
$prompt = sprintf(
'Generate %d "%s" questions in Aiken format in the %s language about "%s", making sure there is a \'ANSWER\' line for each question. \'ANSWER\' lines must only mention the letter of the correct answer, not the full answer text and not a parenthesis. The line starting with \'ANSWER\' must not be separated from the last possible answer by a blank line. Each answer starts with an uppercase letter, a dot, one space and the answer text without quotes. Include an \'ANSWER_EXPLANATION\' line after the \'ANSWER\' line for each question. The terms between single quotes above must not be translated. There must be a blank line between each question.',
$nQ,
$questionType,
$lang,
$topic
);
$payload = [
'model' => 'deepseek-chat',
'messages' => [
[
'role' => 'system',
'content' => 'You are a helpful assistant that generates Aiken format questions.',
],
[
'role' => 'user',
'content' => $prompt,
],
],
'stream' => false,
];
$deepSeek = new DeepSeek($apiKey);
$response = $deepSeek->generateQuestions($payload);
return $response;
}
}

@ -21,8 +21,10 @@ class DeepSeek
* Generate questions using the DeepSeek API.
*
* @param array $payload Data to send to the API
* @return string Decoded response from the API
*
* @throws Exception If an error occurs during the request
*
* @return string Decoded response from the API
*/
public function generateQuestions(array $payload): string
{
@ -51,11 +53,13 @@ class DeepSeek
/**
* Send a request to the DeepSeek API.
*
* @param string $url Endpoint to send the request to
* @param string $url Endpoint to send the request to
* @param string $method HTTP method (e.g., GET, POST)
* @param array $data Data to send as JSON
* @return string Raw response from the API
* @param array $data Data to send as JSON
*
* @throws Exception If a cURL error occurs
*
* @return string Raw response from the API
*/
private function sendRequest(string $url, string $method, array $data = []): string
{

@ -12,6 +12,6 @@ class DeepSeekUrl
*/
public static function completionsUrl(): string
{
return self::BASE_URL . '/completions';
return self::BASE_URL.'/completions';
}
}

@ -22,10 +22,9 @@ try {
'text' => trim($resultText),
]);
} catch (Exception $e) {
error_log("Error: " . $e->getMessage());
error_log("Error: ".$e->getMessage());
echo json_encode([
'success' => false,
'text' => $e->getMessage(),
]);
}

@ -22,7 +22,6 @@ if (!in_array($apiName, array_keys($apiList))) {
exit;
}
$courseLanguage = (string) $_REQUEST['language'];
$chaptersCount = (int) $_REQUEST['nro_items'];
$topic = (string) $_REQUEST['lp_name'];

@ -384,6 +384,29 @@ class AzureActiveDirectory extends Plugin
];
}
public function getSyncState(string $title): ?AzureSyncState
{
$stateRepo = Database::getManager()->getRepository(AzureSyncState::class);
return $stateRepo->findOneBy(['title' => $title]);
}
public function saveSyncState(string $title, $value)
{
$state = $this->getSyncState($title);
if (!$state) {
$state = new AzureSyncState();
$state->setTitle($title);
Database::getManager()->persist($state);
}
$state->setValue($value);
Database::getManager()->flush();
}
/**
* @throws Exception
*/
@ -425,27 +448,4 @@ class AzureActiveDirectory extends Plugin
$extra,
];
}
public function getSyncState(string $title): ?AzureSyncState
{
$stateRepo = Database::getManager()->getRepository(AzureSyncState::class);
return $stateRepo->findOneBy(['title' => $title]);
}
public function saveSyncState(string $title, $value)
{
$state = $this->getSyncState($title);
if (!$state) {
$state = new AzureSyncState();
$state->setTitle($title);
Database::getManager()->persist($state);
}
$state->setValue($value);
Database::getManager()->flush();
}
}

@ -21,8 +21,6 @@ class AzureSyncState
public const USERGROUPS_DATALINK = 'usergroups_datalink';
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id()
* @ORM\GeneratedValue()
@ -30,15 +28,11 @@ class AzureSyncState
private int $id = 0;
/**
* @var string
*
* @ORM\Column(name="title", type="string")
*/
private string $title;
/**
* @var string
*
* @ORM\Column(name="value", type="text")
*/
private string $value;

Loading…
Cancel
Save