AutorÃa | Ultima modificación | Ver Log |
<?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/>.declare(strict_types=1);namespace customfield_number\local\numberproviders;use context_course;use core_plugin_manager;use customfield_number\data_controller;use customfield_number\provider_base;use MoodleQuickForm;/*** Class nofactivities to calculate number of activities in the course.** @package customfield_number* @author 2024 Marina Glancy* @copyright 2024 Moodle Pty Ltd <support@moodle.com>* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class nofactivities extends provider_base {/*** Provider name*/public function get_name(): string {return get_string('nofactivities', 'customfield_number');}/*** Check if the provider is available for the current field.** @return bool*/public function is_available(): bool {return $this->field->get_handler()->get_component() === 'core_course' &&$this->field->get_handler()->get_area() === 'course';}/*** Add autocomplete field for selecting activity type.* Also add checkbox to display the field when the number of activities is zero.** @param MoodleQuickForm $mform*/public function config_form_definition(MoodleQuickForm $mform): void {$options = [];$plugins = core_plugin_manager::instance()->get_plugins_of_type('mod');foreach ($plugins as $plugin) {$options[$plugin->name] = $plugin->displayname;}// Define the label for the autocomplete element.$valuelabel = get_string('activitytypes', 'customfield_number');// Add autocomplete element.$mform->addElement('autocomplete', 'configdata[activitytypes]', $valuelabel, $options, ['multiple' => true]);$mform->hideIf('configdata[activitytypes]', 'configdata[fieldtype]', 'ne', get_class($this));$mform->hideIf('configdata[decimalplaces]', 'configdata[fieldtype]', 'eq', get_class($this));$mform->hideIf('configdata[display]', 'configdata[fieldtype]', 'eq', get_class($this));$mform->hideIf('str_display_format', 'configdata[fieldtype]', 'eq', get_class($this));$mform->hideIf('configdata[defaultvalue]', 'configdata[fieldtype]', 'eq', get_class($this));$mform->hideIf('configdata[minimumvalue]', 'configdata[fieldtype]', 'eq', get_class($this));$mform->hideIf('configdata[maximumvalue]', 'configdata[fieldtype]', 'eq', get_class($this));}/*** Recalculate the number of activities in the course.** @param int|null $instanceid*/public function recalculate(?int $instanceid = null): void {global $DB;$types = $this->field->get_configdata_property('activitytypes');$displaywhenzero = $this->field->get_configdata_property('displaywhenzero');if (empty($types)) {return;}// Subquery to select all modules of selected types.[$sqlin, $params] = $DB->get_in_or_equal($types, SQL_PARAMS_NAMED);$cmsql = "SELECT m.idFROM {modules} mWHERE m.name $sqlinAND m.visible = 1";$where = '';if ($instanceid) {$where = "AND c.id = :courseid ";$params['courseid'] = $instanceid;}// Number of activities is stored in database. So we count the number and check if it matches the stored value.// We update value in database if it doesn't match counted value.$sql = "SELECT c.id, COUNT(cm.id) AS cnt, d.id AS dataid, d.decvalueFROM {course} cLEFT JOIN {customfield_data} dON d.fieldid = :fieldidAND d.instanceid = c.idLEFT JOIN {course_modules} cmON cm.course = c.idAND cm.visible = 1AND cm.deletioninprogress = 0AND cm.module IN ($cmsql)WHERE c.id <> :siteid $whereGROUP BY c.id, d.id, d.decvalue";$params['fieldid'] = $fieldid = $this->field->get('id');$records = $DB->get_records_sql($sql, $params + ['siteid' => SITEID]);foreach ($records as $record) {$value = (int)$record->cnt;if ((string)$displaywhenzero === '' && !$value) {// Do not display the field when the number of activities is zero.if ($record->dataid) {(new data_controller(0, (object)['id' => $record->dataid]))->delete();}} else if (empty($record->dataid) || (int)$record->decvalue != $value) {// Stored value is out of date.$data = \core_customfield\api::get_instance_fields_data([$fieldid => $this->field], (int)$record->id)[$fieldid];$data->set('contextid', context_course::instance($record->id)->id);$data->set('decvalue', $value);$data->save();}}}/*** Validate the data on the field configuration form for number of activities provider.** @param array $data* @param array $files* @return array associative array of error messages*/public function config_form_validation(array $data, array $files = []): array {$errors = [];if (empty($data['configdata']['activitytypes'])) {$errors['configdata[activitytypes]'] = get_string('err_required', 'form');}return $errors;}/*** Preparation for export for number of activities provider.** @param mixed $value String or float or null if the value is not present in the database for this instance* @param \context|null $context Context* @return ?string*/public function prepare_export_value(mixed $value, ?\context $context = null): ?string {if ($value === null) {return null;} else if (round((float)$value) == 0) {$whenzero = $this->field->get_configdata_property('displaywhenzero');if ((string) $whenzero === '') {return null;} else {return format_string($whenzero, true, ['context' => $context ?? \core\context\system::instance()]);}} else {return format_float((float)$value, 0);}}}