From 01cab83a0031a30e5e4dbaad407831409b478422 Mon Sep 17 00:00:00 2001 From: Magdalena Holczik Date: Thu, 19 Dec 2024 14:32:55 +0100 Subject: [PATCH] First steps to adding disabling rules for bookingoptions #656 --- classes/booking_rules/booking_rules.php | 15 ++ classes/option/field_base.php | 1 - classes/option/fields/rules.php | 219 ++++++++++++++++++++++++ lang/de/booking.php | 5 + lang/en/booking.php | 4 + lib.php | 2 + 6 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 classes/option/fields/rules.php diff --git a/classes/booking_rules/booking_rules.php b/classes/booking_rules/booking_rules.php index 191fa2789..69e18394b 100644 --- a/classes/booking_rules/booking_rules.php +++ b/classes/booking_rules/booking_rules.php @@ -141,4 +141,19 @@ public static function delete_rules_by_context(int $contextid) { rules_info::delete_rule($rule->id); } } + + /** + * Check if rules in a given contextid match with the bookingid. + * @param int $bookingid + * @param int $contextid + */ + public static function booking_matches_rulecontext(int $bookingcmid, int $contextid) { + + if ($contextid == 1) { + return true; + } + // Context of the rule. + $context = context::instance_by_id($contextid); + return $context->instanceid == $bookingcmid; + } } diff --git a/classes/option/field_base.php b/classes/option/field_base.php index d9071a5e0..e30ae810c 100644 --- a/classes/option/field_base.php +++ b/classes/option/field_base.php @@ -112,7 +112,6 @@ public static function instance_form_definition( $fieldstoinstanciate = [], $applyheader = true ) { - } /** diff --git a/classes/option/fields/rules.php b/classes/option/fields/rules.php new file mode 100644 index 000000000..53643c9ef --- /dev/null +++ b/classes/option/fields/rules.php @@ -0,0 +1,219 @@ +. + +/** + * Control and manage booking dates. + * + * @package mod_booking + * @copyright 2024 Wunderbyte GmbH + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace mod_booking\option\fields; + +use mod_booking\booking_option; +use mod_booking\booking_option_settings; +use mod_booking\booking_rules\booking_rules; +use mod_booking\option\fields; +use mod_booking\option\fields_info; +use mod_booking\option\field_base; +use mod_booking\singleton_service; +use moodle_url; +use MoodleQuickForm; +use stdClass; + +/** + * Class to handle one property of the booking_option_settings class. + * + * @copyright Wunderbyte GmbH + * @author Georg Maißer + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class rules extends field_base { + + /** + * This ID is used for sorting execution. + * @var int + */ + public static $id = MOD_BOOKING_OPTION_FIELD_RULES; + + /** + * Some fields are saved with the booking option... + * This is normal behaviour. + * Some can be saved only post save (when they need the option id). + * @var int + */ + public static $save = MOD_BOOKING_EXECUTION_NORMAL; + + /** + * This identifies the header under which this particular field should be displayed. + * @var string + */ + public static $header = MOD_BOOKING_HEADER_RULES; + + /** + * An int value to define if this field is standard or used in a different context. + * @var array + */ + public static $fieldcategories = [MOD_BOOKING_OPTION_FIELD_STANDARD]; + + /** + * Additionally to the classname, there might be others keys which should instantiate this class. + * @var array + */ + public static $alternativeimportidentifiers = ['rules']; + + /** + * This is an array of incompatible field ids. + * @var array + */ + public static $incompatiblefields = []; + + /** + * This function interprets the value from the form and, if useful... + * ... relays it to the new option class for saving or updating. + * @param stdClass $formdata + * @param stdClass $newoption + * @param int $updateparam + * @param ?mixed $returnvalue + * @return string // If no warning, empty string. + */ + public static function prepare_save_field( + stdClass &$formdata, + stdClass &$newoption, + int $updateparam, + $returnvalue = null): array { + + // REgex ids gecheckte boxen von rules. + $rulesdeactivated = []; + + foreach ($formdata as $key => $value) { + // Check if the key matches the pattern 'ruleinactive_' followed by a number. + if (preg_match('/^ruleinactive_(\d+)$/', $key, $matches)) { + // If the value is not empty, add the rule ID to the array. + if (!empty($value)) { + $rulesdeactivated[] = (int)$matches[1]; + } + } + } + if (empty($rulesdeactivated)) { + // This will store the correct JSON to $optionvalues->json. + booking_option::remove_key_from_json($newoption, "rulesdeactivated"); + } else { + booking_option::add_data_to_json($newoption, "rulesdeactivated", $rulesdeactivated); + } + + // TODO: Correctly check for changes! + $mockdata = new stdClass(); + $mockdata->id = $formdata->id; + $instance = new rules(); + $changes = $instance->check_for_changes($formdata, $instance, $mockdata); + + return $changes; + } + + /** + * Instance form definition + * @param MoodleQuickForm $mform + * @param array $formdata + * @param array $optionformconfig + * @param array $fieldstoinstanciate + * @param bool $applyheader + * @return void + */ + public static function instance_form_definition( + MoodleQuickForm &$mform, + array &$formdata, + array $optionformconfig, + $fieldstoinstanciate = [], + $applyheader = true + ) { + + global $CFG, $COURSE; + + // Standardfunctionality to add a header to the mform (only if its not yet there). + if ($applyheader) { + fields_info::add_header_to_mform($mform, self::$header); + } + + $booking = singleton_service::get_instance_of_booking_by_bookingid($formdata['bookingid'] ?? 0); + + $allrules = booking_rules::get_list_of_saved_rules(); + + if (empty($allrules)) { + $mform->addElement('static', 'norules', '', get_string('norulesfound', 'mod_booking')); + } + // Order rules by context. + $rulesbycontext = []; + foreach ($allrules as $rule) { + $rulesbycontext[$rule->contextid][] = $rule; + } + + foreach ($rulesbycontext as $context => $rules) { + if ( + !booking_rules::booking_matches_rulecontext($booking->cmid, $context) + ) { + unset($rulesbycontext[$context]); + continue; + } + // Add header. + if ($context == 1) { + $url = new moodle_url('/mod/booking/edit_rules.php', ['cmid' => $booking->cmid]); + $mform->addElement( + 'static', + 'rulesheader_' . $context, + '', + get_string('rulesincontextglobalheader', 'mod_booking', $url->out()) + ); + } else { + $url = new moodle_url('/mod/booking/edit_rules.php', ['cmid' => $booking->cmid]); + $a = (object) [ + 'rulesincontexturl' => $url->out(), + 'bookingname' => $booking->settings->name, + ]; + $mform->addElement('static', 'rulesheader_' . $context, '', get_string('rulesincontextheader', 'mod_booking', $a)); + } + + foreach ($rules as $rule) { + $data = json_decode($rule->rulejson); + $mform->addElement( + 'advcheckbox', + 'ruleinactive_' . $rule->id, + $data->name, + get_string('bookingruledeactivate', 'mod_booking'), + 0, + [0, 1] + ); + } + } + } + + /** + * Standard function to transfer stored value to form. + * @param stdClass $data + * @param booking_option_settings $settings + * @return void + * @throws dml_exception + */ + public static function set_data(stdClass &$data, booking_option_settings $settings) { + + $deactivatedrules = booking_option::get_value_of_json_by_key($data->id, "rulesdeactivated"); + foreach ($deactivatedrules as $ruleid) { + $key = 'ruleinactive_' . $ruleid; + $data->$key = 1; + } + } +} diff --git a/lang/de/booking.php b/lang/de/booking.php index 2053bfda0..3ebef28d1 100755 --- a/lang/de/booking.php +++ b/lang/de/booking.php @@ -516,6 +516,7 @@ $string['bookingruleaction'] = "Aktion der Regel"; $string['bookingruleapply'] = "Regel anwenden"; $string['bookingruleapplydesc'] = "Entfernen Sie den Haken, wenn Sie die Regel deaktivieren möchten."; +$string['bookingruledeactivate'] = "Regel für diese Buchungsoption deaktivieren"; $string['bookingrulecondition'] = "Kondition der Regel"; $string['bookingruleisactive'] = "Regel ist aktiv und wird angewandt"; $string['bookingruleisnotactive'] = "Regel ist nicht aktiv und wird nicht angewandt"; @@ -1903,6 +1904,10 @@ $string['rulesendmailcpf_desc'] = 'Wählen Sie ein Event aus, auf das reagiert werden soll. Legen Sie eine E-Mail-Vorlage an (Sie können auch Platzhalter wie {bookingdetails} verwenden) und legen Sie fest, an welche Nutzer:innen die E-Mail versendet werden soll. Beispiel: Alle Nutzer:innen, die im benutzerdefinierten Feld "Studienzentrumsleitung" den Wert "SZL Wien" stehen haben.'; +$string['rulesheader'] = '  Regeln'; +$string['rulesincontextglobalheader'] = 'Globale Regeln'; +$string['rulesincontextheader'] = 'Regeln in Buchungsinstanz "{$a->bookingname}"'; +$string['rulesnotfound'] = 'Keine Regeln für diese Buchungsoption gefunden'; $string['rulessettings'] = "Einstellungen für Regeln"; $string['rulessettingsdesc'] = 'Einstellungen, die für die Funktion Buchungs Regeln gelten.'; $string['rulevalue'] = 'Wert'; diff --git a/lang/en/booking.php b/lang/en/booking.php index fb7f34ef3..e46656e0f 100755 --- a/lang/en/booking.php +++ b/lang/en/booking.php @@ -1963,6 +1963,10 @@ $string['rulesendmailcpf_desc'] = 'Choose an event that should trigger the "Send an e-mail" rule. Enter an e-mail template (you can use placeholders like {bookingdetails}) and define to which users the e-mail should be sent. Example: All users having the value "Vienna center" in a custom user profile field called "Study center".'; +$string['rulesheader'] = '  Regeln'; +$string['rulesincontextglobalheader'] = 'Global rules'; +$string['rulesincontextheader'] = 'Rules in bookinginstance "{$a->bookingname}"'; +$string['rulesnotfound'] = 'No rules found for this bookingoption'; $string['rulessettings'] = "Settings for Booking Rules"; $string['rulessettingsdesc'] = 'Settings that apply to the Booking Rules Feature.'; $string['rulevalue'] = 'Value'; diff --git a/lib.php b/lib.php index f847e51b2..323166bd7 100755 --- a/lib.php +++ b/lib.php @@ -253,6 +253,7 @@ define('MOD_BOOKING_OPTION_FIELD_TIMEMODIFIED', 530); define('MOD_BOOKING_OPTION_FIELD_TEMPLATESAVE', 600); define('MOD_BOOKING_OPTION_FIELD_EVENTSLIST', 700); +define('MOD_BOOKING_OPTION_FIELD_RULES', 800); define('MOD_BOOKING_OPTION_FIELD_AFTERSUBMITACTION', 999); // To define execution of field methods. @@ -276,6 +277,7 @@ define('MOD_BOOKING_HEADER_CUSTOMFIELDS', 'category_'); // There can be multiple headers, with custom names. define('MOD_BOOKING_HEADER_TEMPLATESAVE', 'templateheader'); define('MOD_BOOKING_HEADER_COURSES', 'coursesheader'); +define('MOD_BOOKING_HEADER_RULES', 'rulesheader'); define('MOD_BOOKING_MAX_CUSTOM_FIELDS', 3); define('MOD_BOOKING_FORM_OPTIONDATEID', 'optiondateid_');