Skip to content

Commit

Permalink
Got basic AIProvider form working
Browse files Browse the repository at this point in the history
  • Loading branch information
mhughes2k committed Mar 22, 2024
1 parent 2617ff3 commit 1bdbabc
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 13 deletions.
19 changes: 19 additions & 0 deletions ai/classes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ class api {
const ACTION_REMOVE_PROVIDER = "remove";
const ACTION_EDIT_PROVIDER = "edit";
const ACTION_MANAGE_PROVIDERS = "manage";

const ACTION_SAVE_PROVIDER = "save";
/**
* Return a list of AIProviders that are available for specified context.
* @param $context
Expand Down Expand Up @@ -52,4 +54,21 @@ public static function get_providers($contextid = null, $allowchat = null, $allo
$providers = aiprovider::get_records($filters);
return array_values($providers);
}
public static function create_provider($data) {
return self::create_or_update_provider($data, true);
}
public static function update_provider($data) {
return self::create_or_update_provider($data, false);
}
protected static function create_or_update_provider($data, bool $create) {
//TODO Capability check.
$provider = new aiprovider($data->id ?? 0, $data);

if ($create) {
$provider->create();
} else {
$provider->update();
}
return $provider;
}
}
85 changes: 73 additions & 12 deletions ai/classes/form/openaiapiprovider.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<?php

namespace core_ai\form;

use core_ai\api;
class openaiapiprovider extends \core\form\persistent{
/** @var string $persistentclass */
protected static $persistentclass = 'core_ai\\aiprovider';

protected static $fieldstoremove = [
'type',
'submitbutton',
'action'
];

public function __construct($action = null, $customdata = null, $method = 'post', $target = '', $attributes = null,
$editable = true, array $ajaxformdata = null){
if (array_key_exists('type', $customdata)) {
Expand Down Expand Up @@ -51,18 +57,73 @@ public function definition() {
$mform->disabledIf('embeddingmodel', 'allowembeddings', 'notchecked');

$mform->addElement('header','constraints', get_string('constraints', 'ai'));
$mform->addElement('checkbox', 'systemwide', get_string('allowsystemwide', 'ai'));
$displaylist = \core_course_category::make_categories_list('moodle/course:changecategory');
// if (!isset($displaylist[$course->category])) {
// //always keep current
// $displaylist[$course->category] = core_course_category::get($course->category, MUST_EXIST, true)
// ->get_formatted_name();
// }
$mform->addElement('autocomplete', 'contextid', get_string('coursecategory'), $displaylist);
// $mform->addRule('contextid', null, 'required', null, 'client');
$mform->addHelpButton('contextid', 'coursecategory');
$mform->disabledIf('contextid', 'systemwide', 'checked');

$displaylist = [
"" => get_string('anywhere', 'ai'),
"-1" => get_string('anyusercourse', 'ai')
];
$displaylist =
$displaylist +
\core_course_category::make_categories_list('moodle/ai:selectcategory')
;

$mform->addElement('autocomplete', 'categoryid', get_string('scopecoursecategory','ai'), $displaylist);
$mform->addHelpButton('categoryid', 'scopecoursecategory', 'ai');
$mform->setDefault('categoryid', null); // a null category is technical "whole" site

$coursedisplaylist = \get_courses("all", "shortname");
$coursedisplaylist = array_map(function($course) {
return $course->shortname;
}, $coursedisplaylist);
$coursedisplaylist = ["" => "No Restriction"] + $coursedisplaylist;
$mform->addElement('autocomplete', 'courseid', get_string('course'), $coursedisplaylist);
$mform->addHelpButton('courseid', 'scopecourse', 'ai');
$mform->setDefault('courseid', null); // a null category is technical "whole" site
// $mform->disabledIf('courseid', 'categoryid', 'neq', "");

$mform->addElement('hidden', 'contextid', );
$mform->setType('contextid', PARAM_RAW);

$mform->addElement('hidden', 'onlyenrolledcourses', );
$mform->setType('onlyenrolledcourses', PARAM_RAW);

$mform->addElement('hidden', 'enabled', true);
$mform->setType('enabled', PARAM_ALPHA);

$mform->addElement('hidden', 'type', $this->_customdata['type']);
$mform->setType('type', PARAM_ALPHANUM);

$mform->addElement('hidden', 'action', api::ACTION_EDIT_PROVIDER);
$mform->setType('action', PARAM_ALPHA);

$mform->addElement('hidden', 'id', $provider->get('id'));
$mform->setType('id', PARAM_INT);
$this->add_action_buttons(true, get_string('savechanges', 'ai'));
}

protected function filter_data_for_persistent($data) {
if (!empty($data->categoryid)) {
$data->onlyenrolledcourses = false;
if ($data->categoryid >0) {
$data->contextid = \core_course_category::get($data->categoryid)->get_context()->id;
} else{
$data->contextid = $data->categoryid;
if ($data->contextid == -1) {
$data->onlyenrolledcourses = true;
}
}
} else if (!empty($data->courseid)) {
$data->contextid = \core\context\course::instance($data->courseid)->id;
}
return (object) array_diff_key((array) $data, array_flip((array) static::$foreignfields));
}
function extra_validation($data, $files, array &$errors) {
parent::extra_validation($data, $files, $errors);
if(!empty($data->categoryid) && !empty($data->courseid)) {
// $data->category is not allowed to be set.
$errors['courseid'] = "Course constraint cannot be set whilst a category one is set";
}
var_dump($errors);
return $errors;
}
}
16 changes: 15 additions & 1 deletion ai/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,22 @@
redirect(new moodle_url('/admin/tool/oauth2/issuers.php'));
} else if ($action == api::ACTION_EDIT_PROVIDER) {
// Handle edit.
if ($data = $mform->get_data()) {
if ($mform->is_cancelled()) {
echo 'cancelled';
}
if ($mform->is_submitted()) {
echo 'submitted';
}
echo 'validated '. (int)$mform->is_validated();

if ($data = $mform->get_data()) {
var_dump($data);
if (!empty($data->id)) {
core_ai\api::update_provider($data);
} else {
core_ai\api::create_provider($data);
}
exit();
} else {
echo $OUTPUT->header();
$mform->display();
Expand Down
15 changes: 15 additions & 0 deletions lang/en/ai.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
$string['pluginname'] = 'AI Providers';
$string['aiprovider'] = 'AI Provider';
$string['addprovider'] = 'Add AI Provider';
$string['anyusercourse'] = 'Any course user is enrolled in';
$string['anywhere'] = 'Anywhere in site';
$string['enabled'] = 'Enabled';
$string['disabled'] = 'Disabled';
$string['removeprovider'] = 'Remove AI Provider';
Expand Down Expand Up @@ -68,5 +70,18 @@
$string['embeddingmodel'] = 'Embedding Model';
$string['embeddingmodel_help'] = 'Embedding Model';

$string['scopecoursecategory'] = 'Category';
$string['scopecoursecategory_help'] = 'Limit AI scope to courses and sub-categories.
This can be limited to work only against the user\'s enrolled courses.
Users must hold the `moodle/ai:selectcategory` capability on a category to choose it.';
$string['scopecourse'] = 'Course(s)';
$string['scopecourse_help'] = 'Limit AI scope to specific courses.
Not available if a category scope constraint has been chosen.
Users must hold the `moodle/ai:selectcourse` capability on a course to choose it.';

$string['constraints'] = 'Constraints';
$string['savechanges'] = 'Save changes';
7 changes: 7 additions & 0 deletions lib/db/access.php
Original file line number Diff line number Diff line change
Expand Up @@ -2772,4 +2772,11 @@
'manager' => CAP_ALLOW,
]
],
'moodle/ai:selectcategory' => [
'captype' => 'read',
'contextlevel' => CONTEXT_COURSECAT,
'archetypes' => [
'manager' => CAP_ALLOW,
]
]
);

0 comments on commit 1bdbabc

Please sign in to comment.