first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
@@ -0,0 +1,95 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Payment subsystem callback implementation for enrol_fee.
*
* @package enrol_fee
* @category payment
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace enrol_fee\payment;
/**
* Payment subsystem callback implementation for enrol_fee.
*
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class service_provider implements \core_payment\local\callback\service_provider {
/**
* Callback function that returns the enrolment cost and the accountid
* for the course that $instanceid enrolment instance belongs to.
*
* @param string $paymentarea Payment area
* @param int $instanceid The enrolment instance id
* @return \core_payment\local\entities\payable
*/
public static function get_payable(string $paymentarea, int $instanceid): \core_payment\local\entities\payable {
global $DB;
$instance = $DB->get_record('enrol', ['enrol' => 'fee', 'id' => $instanceid], '*', MUST_EXIST);
return new \core_payment\local\entities\payable($instance->cost, $instance->currency, $instance->customint1);
}
/**
* Callback function that returns the URL of the page the user should be redirected to in the case of a successful payment.
*
* @param string $paymentarea Payment area
* @param int $instanceid The enrolment instance id
* @return \moodle_url
*/
public static function get_success_url(string $paymentarea, int $instanceid): \moodle_url {
global $DB;
$courseid = $DB->get_field('enrol', 'courseid', ['enrol' => 'fee', 'id' => $instanceid], MUST_EXIST);
return new \moodle_url('/course/view.php', ['id' => $courseid]);
}
/**
* Callback function that delivers what the user paid for to them.
*
* @param string $paymentarea
* @param int $instanceid The enrolment instance id
* @param int $paymentid payment id as inserted into the 'payments' table, if needed for reference
* @param int $userid The userid the order is going to deliver to
* @return bool Whether successful or not
*/
public static function deliver_order(string $paymentarea, int $instanceid, int $paymentid, int $userid): bool {
global $DB;
$instance = $DB->get_record('enrol', ['enrol' => 'fee', 'id' => $instanceid], '*', MUST_EXIST);
$plugin = enrol_get_plugin('fee');
if ($instance->enrolperiod) {
$timestart = time();
$timeend = $timestart + $instance->enrolperiod;
} else {
$timestart = 0;
$timeend = 0;
}
$plugin->enrol_user($instance, $userid, $instance->roleid, $timestart, $timeend);
return true;
}
}
+447
View File
@@ -0,0 +1,447 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Fee enrolment plugin.
*
* This plugin allows you to set up paid courses.
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Fee enrolment plugin implementation.
*
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class enrol_fee_plugin extends enrol_plugin {
/**
* Returns the list of currencies that the payment subsystem supports and therefore we can work with.
*
* @return array[currencycode => currencyname]
*/
public function get_possible_currencies(): array {
$codes = \core_payment\helper::get_supported_currencies();
$currencies = [];
foreach ($codes as $c) {
$currencies[$c] = new lang_string($c, 'core_currencies');
}
uasort($currencies, function($a, $b) {
return strcmp($a, $b);
});
return $currencies;
}
/**
* Returns optional enrolment information icons.
*
* This is used in course list for quick overview of enrolment options.
*
* We are not using single instance parameter because sometimes
* we might want to prevent icon repetition when multiple instances
* of one type exist. One instance may also produce several icons.
*
* @param array $instances all enrol instances of this type in one course
* @return array of pix_icon
*/
public function get_info_icons(array $instances) {
$found = false;
foreach ($instances as $instance) {
if ($instance->enrolstartdate != 0 && $instance->enrolstartdate > time()) {
continue;
}
if ($instance->enrolenddate != 0 && $instance->enrolenddate < time()) {
continue;
}
$found = true;
break;
}
if ($found) {
return array(new pix_icon('icon', get_string('pluginname', 'enrol_fee'), 'enrol_fee'));
}
return array();
}
public function roles_protected() {
// Users with role assign cap may tweak the roles later.
return false;
}
public function allow_unenrol(stdClass $instance) {
// Users with unenrol cap may unenrol other users manually - requires enrol/fee:unenrol.
return true;
}
public function allow_manage(stdClass $instance) {
// Users with manage cap may tweak period and status - requires enrol/fee:manage.
return true;
}
public function show_enrolme_link(stdClass $instance) {
return ($instance->status == ENROL_INSTANCE_ENABLED);
}
/**
* Returns true if the user can add a new instance in this course.
* @param int $courseid
* @return boolean
*/
public function can_add_instance($courseid) {
$context = context_course::instance($courseid, MUST_EXIST);
if (empty(\core_payment\helper::get_supported_currencies())) {
return false;
}
if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/fee:config', $context)) {
return false;
}
// Multiple instances supported - different cost for different roles.
return true;
}
/**
* We are a good plugin and don't invent our own UI/validation code path.
*
* @return boolean
*/
public function use_standard_editing_ui() {
return true;
}
/**
* Add new instance of enrol plugin.
* @param object $course
* @param array $fields instance fields
* @return int id of new instance, null if can not be created
*/
public function add_instance($course, array $fields = null) {
if ($fields && !empty($fields['cost'])) {
$fields['cost'] = unformat_float($fields['cost']);
}
return parent::add_instance($course, $fields);
}
/**
* Update instance of enrol plugin.
* @param stdClass $instance
* @param stdClass $data modified instance fields
* @return boolean
*/
public function update_instance($instance, $data) {
if ($data) {
$data->cost = unformat_float($data->cost);
}
return parent::update_instance($instance, $data);
}
/**
* Creates course enrol form, checks if form submitted
* and enrols user if necessary. It can also redirect.
*
* @param stdClass $instance
* @return string html text, usually a form in a text box
*/
public function enrol_page_hook(stdClass $instance) {
return $this->show_payment_info($instance);
}
/**
* Returns optional enrolment instance description text.
*
* This is used in detailed course information.
*
*
* @param object $instance
* @return string short html text
*/
public function get_description_text($instance) {
return $this->show_payment_info($instance);
}
/**
* Generates payment information to display on enrol/info page.
*
* @param stdClass $instance
* @return false|string
* @throws coding_exception
* @throws dml_exception
*/
private function show_payment_info(stdClass $instance) {
global $USER, $OUTPUT, $DB;
ob_start();
if ($DB->record_exists('user_enrolments', array('userid' => $USER->id, 'enrolid' => $instance->id))) {
return ob_get_clean();
}
if ($instance->enrolstartdate != 0 && $instance->enrolstartdate > time()) {
return ob_get_clean();
}
if ($instance->enrolenddate != 0 && $instance->enrolenddate < time()) {
return ob_get_clean();
}
$course = $DB->get_record('course', array('id' => $instance->courseid));
$context = context_course::instance($course->id);
if ( (float) $instance->cost <= 0 ) {
$cost = (float) $this->get_config('cost');
} else {
$cost = (float) $instance->cost;
}
if (abs($cost) < 0.01) { // No cost, other enrolment methods (instances) should be used.
echo '<p>'.get_string('nocost', 'enrol_fee').'</p>';
} else {
$data = [
'isguestuser' => isguestuser() || !isloggedin(),
'cost' => \core_payment\helper::get_cost_as_string($cost, $instance->currency),
'instanceid' => $instance->id,
'description' => get_string('purchasedescription', 'enrol_fee',
format_string($course->fullname, true, ['context' => $context])),
'successurl' => \enrol_fee\payment\service_provider::get_success_url('fee', $instance->id)->out(false),
];
echo $OUTPUT->render_from_template('enrol_fee/payment_region', $data);
}
return $OUTPUT->box(ob_get_clean());
}
/**
* Restore instance and map settings.
*
* @param restore_enrolments_structure_step $step
* @param stdClass $data
* @param stdClass $course
* @param int $oldid
*/
public function restore_instance(restore_enrolments_structure_step $step, stdClass $data, $course, $oldid) {
global $DB;
if ($step->get_task()->get_target() == backup::TARGET_NEW_COURSE) {
$merge = false;
} else {
$merge = array(
'courseid' => $data->courseid,
'enrol' => $this->get_name(),
'roleid' => $data->roleid,
'cost' => $data->cost,
'currency' => $data->currency,
);
}
if ($merge and $instances = $DB->get_records('enrol', $merge, 'id')) {
$instance = reset($instances);
$instanceid = $instance->id;
} else {
$instanceid = $this->add_instance($course, (array) $data);
}
$step->set_mapping('enrol', $oldid, $instanceid);
}
/**
* Restore user enrolment.
*
* @param restore_enrolments_structure_step $step
* @param stdClass $data
* @param stdClass $instance
* @param int $oldinstancestatus
* @param int $userid
*/
public function restore_user_enrolment(restore_enrolments_structure_step $step, $data, $instance, $userid, $oldinstancestatus) {
$this->enrol_user($instance, $userid, null, $data->timestart, $data->timeend, $data->status);
}
/**
* Return an array of valid options for the status.
*
* @return array
*/
protected function get_status_options() {
$options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
ENROL_INSTANCE_DISABLED => get_string('no'));
return $options;
}
/**
* Return an array of valid options for the roleid.
*
* @param stdClass $instance
* @param context $context
* @return array
*/
protected function get_roleid_options($instance, $context) {
if ($instance->id) {
$roles = get_default_enrol_roles($context, $instance->roleid);
} else {
$roles = get_default_enrol_roles($context, $this->get_config('roleid'));
}
return $roles;
}
/**
* Add elements to the edit instance form.
*
* @param stdClass $instance
* @param MoodleQuickForm $mform
* @param context $context
* @return bool
*/
public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
$mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
$mform->setType('name', PARAM_TEXT);
$options = $this->get_status_options();
$mform->addElement('select', 'status', get_string('status', 'enrol_fee'), $options);
$mform->setDefault('status', $this->get_config('status'));
$accounts = \core_payment\helper::get_payment_accounts_menu($context);
if ($accounts) {
$accounts = ((count($accounts) > 1) ? ['' => ''] : []) + $accounts;
$mform->addElement('select', 'customint1', get_string('paymentaccount', 'payment'), $accounts);
} else {
$mform->addElement('static', 'customint1_text', get_string('paymentaccount', 'payment'),
html_writer::span(get_string('noaccountsavilable', 'payment'), 'alert alert-danger'));
$mform->addElement('hidden', 'customint1');
$mform->setType('customint1', PARAM_INT);
}
$mform->addHelpButton('customint1', 'paymentaccount', 'enrol_fee');
$mform->addElement('text', 'cost', get_string('cost', 'enrol_fee'), array('size' => 4));
$mform->setType('cost', PARAM_RAW);
$mform->setDefault('cost', format_float($this->get_config('cost'), 2, true));
$supportedcurrencies = $this->get_possible_currencies();
$mform->addElement('select', 'currency', get_string('currency', 'enrol_fee'), $supportedcurrencies);
$mform->setDefault('currency', $this->get_config('currency'));
$roles = $this->get_roleid_options($instance, $context);
$mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_fee'), $roles);
$mform->setDefault('roleid', $this->get_config('roleid'));
$options = array('optional' => true, 'defaultunit' => 86400);
$mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_fee'), $options);
$mform->setDefault('enrolperiod', $this->get_config('enrolperiod'));
$mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_fee');
$options = array('optional' => true);
$mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_fee'), $options);
$mform->setDefault('enrolstartdate', 0);
$mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_fee');
$options = array('optional' => true);
$mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_fee'), $options);
$mform->setDefault('enrolenddate', 0);
$mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_fee');
if (enrol_accessing_via_instance($instance)) {
$warningtext = get_string('instanceeditselfwarningtext', 'core_enrol');
$mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warningtext);
}
}
/**
* Perform custom validation of the data used to edit the instance.
*
* @param array $data array of ("fieldname"=>value) of submitted data
* @param array $files array of uploaded files "element_name"=>tmp_file_path
* @param object $instance The instance loaded from the DB
* @param context $context The context of the instance we are editing
* @return array of "element_name"=>"error_description" if there are errors,
* or an empty array if everything is OK.
* @return void
*/
public function edit_instance_validation($data, $files, $instance, $context) {
$errors = array();
if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
$errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_fee');
}
$cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']);
if (!is_numeric($cost)) {
$errors['cost'] = get_string('costerror', 'enrol_fee');
}
$validstatus = array_keys($this->get_status_options());
$validcurrency = array_keys($this->get_possible_currencies());
$validroles = array_keys($this->get_roleid_options($instance, $context));
$tovalidate = array(
'name' => PARAM_TEXT,
'status' => $validstatus,
'currency' => $validcurrency,
'roleid' => $validroles,
'enrolperiod' => PARAM_INT,
'enrolstartdate' => PARAM_INT,
'enrolenddate' => PARAM_INT
);
$typeerrors = $this->validate_param_types($data, $tovalidate);
$errors = array_merge($errors, $typeerrors);
if ($data['status'] == ENROL_INSTANCE_ENABLED &&
(!$data['customint1']
|| !array_key_exists($data['customint1'], \core_payment\helper::get_payment_accounts_menu($context)))) {
$errors['status'] = 'Enrolments can not be enabled without specifying the payment account';
}
return $errors;
}
/**
* Execute synchronisation.
* @param progress_trace $trace
* @return int exit code, 0 means ok
*/
public function sync(progress_trace $trace) {
$this->process_expirations($trace);
return 0;
}
/**
* Is it possible to delete enrol instance via standard UI?
*
* @param stdClass $instance
* @return bool
*/
public function can_delete_instance($instance) {
$context = context_course::instance($instance->courseid);
return has_capability('enrol/fee:config', $context);
}
/**
* Is it possible to hide/show enrol instance via standard UI?
*
* @param stdClass $instance
* @return bool
*/
public function can_hide_show_instance($instance) {
$context = context_course::instance($instance->courseid);
return has_capability('enrol/fee:config', $context);
}
}
+269
View File
@@ -0,0 +1,269 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for enrol_fee.
*
* @package enrol_fee
* @category privacy
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace enrol_fee\privacy;
use core_privacy\local\request\approved_contextlist;
use core_privacy\local\request\approved_userlist;
use core_privacy\local\request\transform;
use core_privacy\local\request\userlist;
use core_privacy\local\request\writer;
use core_payment\helper as payment_helper;
/**
* Privacy Subsystem for enrol_fee implementing null_provider.
*
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements
\core_privacy\local\metadata\null_provider,
\core_payment\privacy\consumer_provider
{
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
public static function get_contextid_for_payment(string $paymentarea, int $itemid): ?int {
global $DB;
$sql = "SELECT ctx.id
FROM {enrol} e
JOIN {context} ctx ON (e.courseid = ctx.instanceid AND ctx.contextlevel = :contextcourse)
WHERE e.id = :enrolid AND e.enrol = :enrolname";
$params = [
'contextcourse' => CONTEXT_COURSE,
'enrolid' => $itemid,
'enrolname' => 'fee',
];
$contextid = $DB->get_field_sql($sql, $params);
return $contextid ?: null;
}
public static function get_users_in_context(userlist $userlist) {
$context = $userlist->get_context();
if ($context instanceof \context_course) {
$sql = "SELECT p.userid
FROM {payments} p
JOIN {enrol} e ON (p.component = :component AND p.itemid = e.id)
WHERE e.courseid = :courseid";
$params = [
'component' => 'enrol_fee',
'courseid' => $context->instanceid,
];
$userlist->add_from_sql('userid', $sql, $params);
} else if ($context instanceof \context_system) {
// If context is system, then the enrolment belongs to a deleted enrolment.
$sql = "SELECT p.userid
FROM {payments} p
LEFT JOIN {enrol} e ON p.itemid = e.id
WHERE p.component = :component AND e.id IS NULL";
$params = [
'component' => 'enrol_fee',
];
$userlist->add_from_sql('userid', $sql, $params);
}
}
/**
* Export all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts to export information for.
*/
public static function export_user_data(approved_contextlist $contextlist) {
global $DB;
$subcontext = [
get_string('pluginname', 'enrol_fee'),
];
foreach ($contextlist as $context) {
if (!$context instanceof \context_course) {
continue;
}
$feeplugins = $DB->get_records('enrol', ['courseid' => $context->instanceid, 'enrol' => 'fee']);
foreach ($feeplugins as $feeplugin) {
\core_payment\privacy\provider::export_payment_data_for_user_in_context(
$context,
$subcontext,
$contextlist->get_user()->id,
'enrol_fee',
'fee',
$feeplugin->id
);
}
}
if (in_array(SYSCONTEXTID, $contextlist->get_contextids())) {
// Orphaned payments.
$sql = "SELECT p.*
FROM {payments} p
LEFT JOIN {enrol} e ON p.itemid = e.id
WHERE p.userid = :userid AND p.component = :component AND e.id IS NULL";
$params = [
'component' => 'enrol_fee',
'userid' => $contextlist->get_user()->id,
];
$orphanedpayments = $DB->get_recordset_sql($sql, $params);
foreach ($orphanedpayments as $payment) {
\core_payment\privacy\provider::export_payment_data_for_user_in_context(
\context_system::instance(),
$subcontext,
$payment->userid,
$payment->component,
$payment->paymentarea,
$payment->itemid
);
}
$orphanedpayments->close();
}
}
/**
* Delete all data for all users in the specified context.
*
* @param \context $context The specific context to delete data for.
*/
public static function delete_data_for_all_users_in_context(\context $context) {
if ($context instanceof \context_course) {
$sql = "SELECT p.id
FROM {payments} p
JOIN {enrol} e ON (p.component = :component AND p.itemid = e.id)
WHERE e.courseid = :courseid";
$params = [
'component' => 'enrol_fee',
'courseid' => $context->instanceid,
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
} else if ($context instanceof \context_system) {
// If context is system, then the enrolment belongs to a deleted enrolment.
$sql = "SELECT p.id
FROM {payments} p
LEFT JOIN {enrol} e ON p.itemid = e.id
WHERE p.component = :component AND e.id IS NULL";
$params = [
'component' => 'enrol_fee',
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
}
}
/**
* Delete all user data for the specified user, in the specified contexts.
*
* @param approved_contextlist $contextlist The approved contexts and user information to delete information for.
*/
public static function delete_data_for_user(approved_contextlist $contextlist) {
global $DB;
if (empty($contextlist->count())) {
return;
}
$contexts = $contextlist->get_contexts();
$courseids = [];
foreach ($contexts as $context) {
if ($context instanceof \context_course) {
$courseids[] = $context->instanceid;
}
}
[$insql, $inparams] = $DB->get_in_or_equal($courseids, SQL_PARAMS_NAMED);
$sql = "SELECT p.id
FROM {payments} p
JOIN {enrol} e ON (p.component = :component AND p.itemid = e.id)
WHERE p.userid = :userid AND e.courseid $insql";
$params = $inparams + [
'component' => 'enrol_fee',
'userid' => $contextlist->get_user()->id,
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
if (in_array(SYSCONTEXTID, $contextlist->get_contextids())) {
// Orphaned payments.
$sql = "SELECT p.id
FROM {payments} p
LEFT JOIN {enrol} e ON p.itemid = e.id
WHERE p.component = :component AND p.userid = :userid AND e.id IS NULL";
$params = [
'component' => 'enrol_fee',
'userid' => $contextlist->get_user()->id,
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
}
}
/**
* Delete multiple users within a single context.
*
* @param approved_userlist $userlist The approved context and user information to delete information for.
*/
public static function delete_data_for_users(approved_userlist $userlist) {
global $DB;
$context = $userlist->get_context();
if ($context instanceof \context_course) {
[$usersql, $userparams] = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
$sql = "SELECT p.id
FROM {payments} p
JOIN {enrol} e ON (p.component = :component AND p.itemid = e.id)
WHERE e.courseid = :courseid AND p.userid $usersql";
$params = $userparams + [
'component' => 'enrol_fee',
'courseid' => $context->instanceid,
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
} else if ($context instanceof \context_system) {
// Orphaned payments.
[$usersql, $userparams] = $DB->get_in_or_equal($userlist->get_userids(), SQL_PARAMS_NAMED);
$sql = "SELECT p.id
FROM {payments} p
LEFT JOIN {enrol} e ON p.itemid = e.id
WHERE p.component = :component AND p.userid $usersql AND e.id IS NULL";
$params = $userparams + [
'component' => 'enrol_fee',
];
\core_payment\privacy\provider::delete_data_for_payment_sql($sql, $params);
}
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Capabilities for fee enrolment plugin.
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'enrol/fee:config' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW,
)
),
'enrol/fee:manage' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
)
),
'enrol/fee:unenrol' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'manager' => CAP_ALLOW,
)
),
'enrol/fee:unenrolself' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
)
),
);
+54
View File
@@ -0,0 +1,54 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'enrol_fee', language 'en'
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['assignrole'] = 'Assign role';
$string['cost'] = 'Enrolment fee';
$string['costerror'] = 'The enrolment fee must be a number.';
$string['currency'] = 'Currency';
$string['defaultrole'] = 'Default role assignment';
$string['defaultrole_desc'] = 'Select the role to assign to users after making a payment.';
$string['enrolenddate'] = 'End date';
$string['enrolenddate_help'] = 'If enabled, users can be enrolled until this date only.';
$string['enrolenddaterror'] = 'The enrolment end date cannot be earlier than the start date.';
$string['enrolperiod'] = 'Enrolment duration';
$string['enrolperiod_desc'] = 'Default length of time that the enrolment is valid. If set to zero, the enrolment duration will be unlimited by default.';
$string['enrolperiod_help'] = 'Length of time that the enrolment is valid, starting with the moment the user is enrolled. If disabled, the enrolment duration will be unlimited.';
$string['enrolstartdate'] = 'Start date';
$string['enrolstartdate_help'] = 'If enabled, users can only be enrolled from this date onwards.';
$string['expiredaction'] = 'Enrolment expiry action';
$string['expiredaction_help'] = 'Select the action to be performed when a user\'s enrolment expires. Please note that some user data and settings are deleted when a user is unenrolled.';
$string['fee:config'] = 'Configure enrolment on payment enrol instances';
$string['fee:manage'] = 'Manage enrolled users';
$string['fee:unenrol'] = 'Unenrol users from course';
$string['fee:unenrolself'] = 'Unenrol self from course';
$string['nocost'] = 'There is no cost to enrol in this course!';
$string['paymentaccount'] = 'Payment account';
$string['paymentaccount_help'] = 'Enrolment fees will be paid to this account.';
$string['pluginname'] = 'Enrolment on payment';
$string['pluginname_desc'] = 'The enrolment on payment enrolment method allows you to set up courses requiring a payment. If the fee for any course is set to zero, then students are not asked to pay for entry. There is a site-wide fee that you set here as a default for the whole site and then a course setting that you can set for each course individually. The course fee overrides the site fee.';
$string['privacy:metadata'] = 'The enrolment on payment enrolment plugin does not store any personal data.';
$string['purchasedescription'] = 'Enrolment in course {$a}';
$string['sendpaymentbutton'] = 'Select payment type';
$string['status'] = 'Allow enrolment on payment enrolments';
$string['status_desc'] = 'Allow users to make a payment to enrol into a course by default.';
+25
View File
@@ -0,0 +1,25 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Fee enrolment plugin.
*
* This plugin allows you to set up paid courses.
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 32.001 32.001" style="enable-background:new 0 0 32.001 32.001;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">
<g>
<g id="banknote">
<path style="fill:#010002;" d="M31.415,10.586l-10-10C20.919,0.09,20.2-0.109,19.519,0.059c-0.359,0.088-0.68,0.273-0.934,0.527
c-0.227,0.227-0.398,0.508-0.496,0.822c-0.453,1.469-1.236,2.746-2.395,3.904C14.146,6.859,12.13,8.031,9.997,9.27
c-2.264,1.312-4.603,2.672-6.52,4.588c-1.629,1.631-2.738,3.445-3.388,5.551c-0.219,0.711-0.028,1.48,0.496,2.006l10,10
c0.496,0.496,1.215,0.695,1.896,0.527c0.359-0.09,0.68-0.273,0.934-0.527c0.227-0.227,0.398-0.508,0.496-0.824
c0.454-1.469,1.237-2.746,2.397-3.904c1.547-1.547,3.562-2.717,5.697-3.955c2.262-1.314,4.602-2.674,6.518-4.59
c1.629-1.629,2.738-3.445,3.389-5.551C32.13,11.881,31.938,11.109,31.415,10.586z M12,30c-3.312-3.312-6.688-6.689-10-10
c2.842-9.201,15.16-8.799,18-18c3.312,3.311,6.689,6.688,10.002,10C27.159,21.199,14.841,20.799,12,30z"/>
<path style="fill:#010002;" d="M19.562,14.9c-0.326-0.273-0.654-0.459-0.984-0.551c-0.328-0.092-0.656-0.129-0.988-0.105
c-0.328,0.025-0.664,0.1-1,0.229c-0.336,0.131-0.674,0.273-1.014,0.438c-0.537-0.617-1.074-1.227-1.611-1.793
c0.242-0.219,0.477-0.33,0.703-0.338c0.227-0.01,0.445,0.014,0.652,0.066c0.211,0.053,0.404,0.098,0.582,0.133
c0.18,0.035,0.336-0.004,0.473-0.119c0.145-0.125,0.225-0.287,0.236-0.482c0.01-0.197-0.064-0.389-0.229-0.576
c-0.211-0.242-0.465-0.389-0.77-0.443c-0.301-0.053-0.609-0.049-0.93,0.021c-0.316,0.072-0.617,0.191-0.902,0.359
s-0.514,0.34-0.684,0.508c-0.065-0.062-0.13-0.123-0.195-0.184c-0.072-0.066-0.162-0.102-0.27-0.1
c-0.109,0-0.199,0.047-0.273,0.133c-0.072,0.084-0.105,0.182-0.092,0.285c0.01,0.107,0.053,0.189,0.127,0.252
c0.065,0.055,0.13,0.109,0.195,0.166c-0.256,0.309-0.467,0.65-0.633,1.01c-0.168,0.361-0.268,0.719-0.305,1.066
c-0.039,0.35-0.002,0.67,0.105,0.967c0.107,0.299,0.305,0.553,0.594,0.793c0.471,0.391,1.025,0.557,1.668,0.52
c0.641-0.039,1.332-0.23,2.075-0.629c0.59,0.682,1.182,1.359,1.773,1.988c-0.25,0.211-0.469,0.332-0.662,0.371
c-0.193,0.041-0.365,0.037-0.521-0.01c-0.156-0.049-0.301-0.119-0.434-0.209c-0.133-0.092-0.264-0.17-0.395-0.234
c-0.129-0.064-0.262-0.1-0.398-0.102s-0.281,0.064-0.441,0.201c-0.164,0.143-0.246,0.309-0.246,0.496
c0,0.186,0.086,0.375,0.254,0.566c0.17,0.191,0.391,0.352,0.658,0.479s0.569,0.207,0.901,0.229
c0.332,0.023,0.682-0.027,1.051-0.164c0.371-0.135,0.738-0.379,1.1-0.742c0.174,0.17,0.35,0.332,0.525,0.488
c0.074,0.064,0.164,0.096,0.273,0.088c0.105-0.004,0.197-0.053,0.27-0.141c0.074-0.09,0.105-0.189,0.094-0.293
c-0.01-0.105-0.053-0.186-0.125-0.244c-0.176-0.141-0.352-0.289-0.527-0.445c0.299-0.367,0.539-0.754,0.717-1.137
c0.178-0.385,0.283-0.756,0.318-1.1c0.035-0.346-0.006-0.658-0.119-0.941C20.046,15.383,19.847,15.137,19.562,14.9z
M13.971,15.578c-0.283,0.012-0.53-0.082-0.746-0.291c-0.092-0.088-0.156-0.195-0.195-0.322c-0.041-0.127-0.055-0.266-0.039-0.418
c0.014-0.15,0.059-0.307,0.137-0.465c0.074-0.158,0.184-0.316,0.324-0.469c0.507,0.504,1.013,1.057,1.52,1.629
C14.588,15.453,14.254,15.566,13.971,15.578z M18.688,17.58c-0.09,0.166-0.193,0.314-0.314,0.443
c-0.561-0.566-1.121-1.188-1.68-1.826c0.143-0.064,0.293-0.131,0.455-0.199s0.324-0.113,0.486-0.141
c0.166-0.025,0.33-0.018,0.494,0.021c0.162,0.041,0.316,0.129,0.459,0.268c0.141,0.141,0.23,0.287,0.266,0.445
c0.039,0.16,0.041,0.322,0.014,0.488C18.839,17.246,18.78,17.412,18.688,17.58z"/>
<path style="fill:#010002;" d="M14.717,22.18h-0.002c-0.625,0.48-1.235,0.986-1.8,1.553c-0.543,0.543-1.034,1.115-1.461,1.699
l-0.684,0.934l0.002,0.002c-0.125,0.195-0.104,0.457,0.066,0.627c0.195,0.195,0.514,0.195,0.71,0
c0.03-0.031,0.054-0.064,0.074-0.1l0.639-0.875c0.396-0.541,0.854-1.074,1.361-1.58c0.561-0.561,1.081-0.994,1.714-1.475
l-0.002-0.002c0.018-0.014,0.035-0.025,0.051-0.041c0.196-0.195,0.196-0.514,0-0.709C15.204,22.029,14.914,22.021,14.717,22.18z"
/>
<path style="fill:#010002;" d="M18.378,7.715c-0.523,0.523-1.09,0.994-1.678,1.443c-0.041,0.023-0.082,0.049-0.117,0.086
c-0.197,0.197-0.197,0.518,0,0.715c0.191,0.193,0.5,0.197,0.699,0.014l0.004,0.002c0.625-0.48,1.234-0.988,1.799-1.553
c0.543-0.543,1.033-1.113,1.461-1.697l0.684-0.938l-0.002-0.002c0.17-0.199,0.162-0.496-0.025-0.684
c-0.197-0.197-0.516-0.197-0.713,0c-0.037,0.037-0.064,0.08-0.088,0.123l-0.664,0.91C19.341,6.678,18.884,7.209,18.378,7.715z"/>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

+79
View File
@@ -0,0 +1,79 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Settings for the Fee enrolment plugin
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($ADMIN->fulltree) {
$currencies = enrol_get_plugin('fee')->get_possible_currencies();
if (empty($currencies)) {
$notify = new \core\output\notification(
get_string('nocurrencysupported', 'core_payment'),
\core\output\notification::NOTIFY_WARNING
);
$settings->add(new admin_setting_heading('enrol_fee_nocurrency', '', $OUTPUT->render($notify)));
}
$settings->add(new admin_setting_heading('enrol_fee_settings', '', get_string('pluginname_desc', 'enrol_fee')));
// Note: let's reuse the ext sync constants and strings here, internally it is very similar,
// it describes what should happen when users are not supposed to be enrolled any more.
$options = array(
ENROL_EXT_REMOVED_KEEP => get_string('extremovedkeep', 'enrol'),
ENROL_EXT_REMOVED_SUSPENDNOROLES => get_string('extremovedsuspendnoroles', 'enrol'),
ENROL_EXT_REMOVED_UNENROL => get_string('extremovedunenrol', 'enrol'),
);
$settings->add(new admin_setting_configselect(
'enrol_fee/expiredaction',
get_string('expiredaction', 'enrol_fee'),
get_string('expiredaction_help', 'enrol_fee'),
ENROL_EXT_REMOVED_SUSPENDNOROLES,
$options));
$settings->add(new admin_setting_heading('enrol_fee_defaults',
get_string('enrolinstancedefaults', 'admin'), get_string('enrolinstancedefaults_desc', 'admin')));
$options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
ENROL_INSTANCE_DISABLED => get_string('no'));
$settings->add(new admin_setting_configselect('enrol_fee/status',
get_string('status', 'enrol_fee'), get_string('status_desc', 'enrol_fee'), ENROL_INSTANCE_DISABLED, $options));
if (!empty($currencies)) {
$settings->add(new admin_setting_configtext('enrol_fee/cost', get_string('cost', 'enrol_fee'), '', 0, PARAM_FLOAT, 4));
$settings->add(new admin_setting_configselect('enrol_fee/currency', get_string('currency', 'enrol_fee'), '', 'USD',
$currencies));
}
if (!during_initial_install()) {
$options = get_default_enrol_roles(context_system::instance());
$student = get_archetype_roles('student');
$student = reset($student);
$settings->add(new admin_setting_configselect('enrol_fee/roleid',
get_string('defaultrole', 'enrol_fee'), get_string('defaultrole_desc', 'enrol_fee'), $student->id ?? null, $options));
}
$settings->add(new admin_setting_configduration('enrol_fee/enrolperiod',
get_string('enrolperiod', 'enrol_fee'), get_string('enrolperiod_desc', 'enrol_fee'), 0));
}
@@ -0,0 +1,80 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template enrol_fee/payment_region
This template will render information about course fee along with a button for payment.
Classes required for JS:
* none
Data attributes required for JS:
* data-component
* data-paymentarea
* data-itemid
* data-cost
* data-description
* data-successurl
Context variables required for this template:
* cost - Human readable cost string including amount and currency
* instanceid - Id of the enrolment instance
* description - The description for this purchase
* successurl - The URL of the course
Example context (json):
{
"cost": "$108.50",
"instanceid": 11,
"description": "Enrolment in course Introduction to algorithms",
"successurl": "https://moodlesite/course/view.php?id=2",
"isguestuser": false
}
}}
<div class="enrol_fee_payment_region text-center">
{{#isguestuser}}
<div class="mdl-align">
<p>{{# str }} paymentrequired {{/ str}}</p>
<p><b>{{cost}}</b></p>
<p><a href="{{config.wwwroot}}/login/">{{# str }} loginsite {{/ str }}</a></p>
</div>
{{/isguestuser}}
{{^isguestuser}}
<p>{{# str }} paymentrequired {{/ str}}</p>
<p><b>{{cost}}</b></p>
<button
class="btn btn-secondary"
type="button"
id="gateways-modal-trigger-{{ uniqid }}"
data-action="core_payment/triggerPayment"
data-component="enrol_fee"
data-paymentarea="fee"
data-itemid="{{instanceid}}"
data-cost="{{cost}}"
data-successurl="{{successurl}}"
data-description="{{description}}"
>
{{# str }} sendpaymentbutton, enrol_fee {{/ str }}
</button>
{{/isguestuser}}
</div>
{{#js}}
require(['core_payment/gateways_modal'], function(modal) {
modal.init();
});
{{/js}}
+51
View File
@@ -0,0 +1,51 @@
@enrol @enrol_fee
Feature: Signing up for a course with a fee enrolment method
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | teacher1@example.com |
| student1 | Student | 1 | student1@example.com |
| manager1 | Manager | 1 | manager1@example.com |
And the following "courses" exist:
| fullname | shortname | format | summary |
| Course 1 | C1 | topics | |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| manager1 | C1 | manager |
And the following "core_payment > payment accounts" exist:
| name | gateways |
| Account1 | paypal |
And I log in as "admin"
And I navigate to "Plugins > Enrolments > Manage enrol plugins" in site administration
And I click on "Enable" "link" in the "Enrolment on payment" "table_row"
And I log out
And I log in as "manager1"
And I am on the "Course 1" "enrolment methods" page
And I select "Enrolment on payment" from the "Add method" singleselect
And I set the following fields to these values:
| Payment account | Account1 |
| Enrolment fee | 123.45 |
| Currency | Euro |
And I press "Add method"
And I log out
@javascript
Scenario: Student can see the payment prompt on the course enrolment page
When I log in as "student1"
And I am on course index
And I follow "Course 1"
Then I should see "This course requires a payment for entry."
And I should see "123.45"
And I press "Select payment type"
And I should see "PayPal" in the "Select payment type" "dialogue"
And I click on "Cancel" "button" in the "Select payment type" "dialogue"
Scenario: Guest can see the login prompt on the course enrolment page
When I log in as "guest"
And I am on course index
And I follow "Course 1"
Then I should see "This course requires a payment for entry."
And I should see "123.45"
And I should see "Log in to the site"
@@ -0,0 +1,133 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for the enrol_fee's payment subsystem callback implementation.
*
* @package enrol_fee
* @category test
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace enrol_fee\payment;
/**
* Unit tests for the enrol_fee's payment subsystem callback implementation.
*
* @coversDefaultClass \enrol_fee\payment\service_provider
*/
class service_provider_test extends \advanced_testcase {
/**
* Test for service_provider::get_payable().
*
* @covers ::get_payable
*/
public function test_get_payable(): void {
global $DB;
$this->resetAfterTest();
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
$feeplugin = enrol_get_plugin('fee');
$generator = $this->getDataGenerator();
$account = $generator->get_plugin_generator('core_payment')->create_payment_account(['gateways' => 'paypal']);
$course = $generator->create_course();
$data = [
'courseid' => $course->id,
'customint1' => $account->get('id'),
'cost' => 250,
'currency' => 'USD',
'roleid' => $studentrole->id,
];
$id = $feeplugin->add_instance($course, $data);
$payable = service_provider::get_payable('fee', $id);
$this->assertEquals($account->get('id'), $payable->get_account_id());
$this->assertEquals(250, $payable->get_amount());
$this->assertEquals('USD', $payable->get_currency());
}
/**
* Test for service_provider::get_success_url().
*
* @covers ::get_success_url
*/
public function test_get_success_url(): void {
global $CFG, $DB;
$this->resetAfterTest();
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
$feeplugin = enrol_get_plugin('fee');
$generator = $this->getDataGenerator();
$account = $generator->get_plugin_generator('core_payment')->create_payment_account(['gateways' => 'paypal']);
$course = $generator->create_course();
$data = [
'courseid' => $course->id,
'customint1' => $account->get('id'),
'cost' => 250,
'currency' => 'USD',
'roleid' => $studentrole->id,
];
$id = $feeplugin->add_instance($course, $data);
$successurl = service_provider::get_success_url('fee', $id);
$this->assertEquals(
$CFG->wwwroot . '/course/view.php?id=' . $course->id,
$successurl->out(false)
);
}
/**
* Test for service_provider::deliver_order().
*
* @covers ::deliver_order
*/
public function test_deliver_order(): void {
global $DB;
$this->resetAfterTest();
$studentrole = $DB->get_record('role', ['shortname' => 'student']);
$feeplugin = enrol_get_plugin('fee');
$generator = $this->getDataGenerator();
$account = $generator->get_plugin_generator('core_payment')->create_payment_account(['gateways' => 'paypal']);
$course = $generator->create_course();
$context = \context_course::instance($course->id);
$user = $generator->create_user();
$data = [
'courseid' => $course->id,
'customint1' => $account->get('id'),
'cost' => 250,
'currency' => 'USD',
'roleid' => $studentrole->id,
];
$id = $feeplugin->add_instance($course, $data);
$paymentid = $generator->get_plugin_generator('core_payment')->create_payment([
'accountid' => $account->get('id'),
'amount' => 10,
'userid' => $user->id
]);
service_provider::deliver_order('fee', $id, $paymentid, $user->id);
$this->assertTrue(is_enrolled($context, $user));
$this->assertTrue(user_has_role_assignment($user->id, $studentrole->id, $context->id));
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Fee enrolment plugin version specification.
*
* @package enrol_fee
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'enrol_fee'; // Full name of the plugin (used for diagnostics).