Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
declare(strict_types=1);
18
 
19
namespace customfield_number\local\numberproviders;
20
 
21
use context_course;
22
use core_plugin_manager;
23
use customfield_number\data_controller;
24
use customfield_number\provider_base;
25
use MoodleQuickForm;
26
 
27
/**
28
 * Class nofactivities to calculate number of activities in the course.
29
 *
30
 * @package    customfield_number
31
 * @author     2024 Marina Glancy
32
 * @copyright  2024 Moodle Pty Ltd <support@moodle.com>
33
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34
 */
35
class nofactivities extends provider_base {
36
 
37
    /**
38
     * Provider name
39
     */
40
    public function get_name(): string {
41
        return get_string('nofactivities', 'customfield_number');
42
    }
43
 
44
    /**
45
     * Check if the provider is available for the current field.
46
     *
47
     * @return bool
48
     */
49
    public function is_available(): bool {
50
        return $this->field->get_handler()->get_component() === 'core_course' &&
51
            $this->field->get_handler()->get_area() === 'course';
52
    }
53
 
54
    /**
55
     * Add autocomplete field for selecting activity type.
56
     * Also add checkbox to display the field when the number of activities is zero.
57
     *
58
     * @param MoodleQuickForm $mform
59
     */
60
    public function config_form_definition(MoodleQuickForm $mform): void {
61
        $options = [];
62
        $plugins = core_plugin_manager::instance()->get_plugins_of_type('mod');
63
        foreach ($plugins as $plugin) {
64
            $options[$plugin->name] = $plugin->displayname;
65
        }
66
 
67
        // Define the label for the autocomplete element.
68
        $valuelabel = get_string('activitytypes', 'customfield_number');
69
        // Add autocomplete element.
70
        $mform->addElement('autocomplete', 'configdata[activitytypes]', $valuelabel, $options, ['multiple' => true]);
71
        $mform->hideIf('configdata[activitytypes]', 'configdata[fieldtype]', 'ne', get_class($this));
72
        $mform->hideIf('configdata[decimalplaces]', 'configdata[fieldtype]', 'eq', get_class($this));
73
        $mform->hideIf('configdata[display]', 'configdata[fieldtype]', 'eq', get_class($this));
74
        $mform->hideIf('str_display_format', 'configdata[fieldtype]', 'eq', get_class($this));
75
        $mform->hideIf('configdata[defaultvalue]', 'configdata[fieldtype]', 'eq', get_class($this));
76
        $mform->hideIf('configdata[minimumvalue]', 'configdata[fieldtype]', 'eq', get_class($this));
77
        $mform->hideIf('configdata[maximumvalue]', 'configdata[fieldtype]', 'eq', get_class($this));
78
    }
79
 
80
    /**
81
     * Recalculate the number of activities in the course.
82
     *
83
     * @param int|null $instanceid
84
     */
85
    public function recalculate(?int $instanceid = null): void {
86
        global $DB;
87
        $types = $this->field->get_configdata_property('activitytypes');
88
        $displaywhenzero = $this->field->get_configdata_property('displaywhenzero');
89
 
90
        if (empty($types)) {
91
            return;
92
        }
93
 
94
        // Subquery to select all modules of selected types.
95
        [$sqlin, $params] = $DB->get_in_or_equal($types, SQL_PARAMS_NAMED);
96
        $cmsql = "SELECT m.id
97
                    FROM {modules} m
98
                   WHERE m.name $sqlin
99
                     AND m.visible = 1";
100
 
101
        $where = '';
102
        if ($instanceid) {
103
            $where = "AND c.id = :courseid ";
104
            $params['courseid'] = $instanceid;
105
        }
106
 
107
        // Number of activities is stored in database. So we count the number and check if it matches the stored value.
108
        // We update value in database if it doesn't match counted value.
109
        $sql = "SELECT c.id, COUNT(cm.id) AS cnt, d.id AS dataid, d.decvalue
110
                  FROM {course} c
111
             LEFT JOIN {customfield_data} d
112
                    ON d.fieldid = :fieldid
113
                   AND d.instanceid = c.id
114
             LEFT JOIN {course_modules} cm
115
                    ON cm.course = c.id
116
                   AND cm.visible = 1
117
                   AND cm.deletioninprogress = 0
118
                   AND cm.module IN ($cmsql)
119
                 WHERE c.id <> :siteid $where
120
              GROUP BY c.id, d.id, d.decvalue
121
        ";
122
        $params['fieldid'] = $fieldid = $this->field->get('id');
123
        $records = $DB->get_records_sql($sql, $params + ['siteid' => SITEID]);
124
        foreach ($records as $record) {
125
            $value = (int)$record->cnt;
126
            if ((string)$displaywhenzero === '' && !$value) {
127
                // Do not display the field when the number of activities is zero.
128
                if ($record->dataid) {
129
                    (new data_controller(0, (object)['id' => $record->dataid]))->delete();
130
                }
131
            } else if (empty($record->dataid) || (int)$record->decvalue != $value) {
132
                // Stored value is out of date.
133
                $data = \core_customfield\api::get_instance_fields_data(
134
                    [$fieldid => $this->field], (int)$record->id)[$fieldid];
135
                $data->set('contextid', context_course::instance($record->id)->id);
136
                $data->set('decvalue', $value);
137
                $data->save();
138
            }
139
        }
140
    }
141
 
142
    /**
143
     * Validate the data on the field configuration form for number of activities provider.
144
     *
145
     * @param array $data
146
     * @param array $files
147
     * @return array associative array of error messages
148
     */
149
    public function config_form_validation(array $data, array $files = []): array {
150
        $errors = [];
151
        if (empty($data['configdata']['activitytypes'])) {
152
            $errors['configdata[activitytypes]'] = get_string('err_required', 'form');
153
        }
154
        return $errors;
155
    }
156
 
157
    /**
158
     * Preparation for export for number of activities provider.
159
     *
160
     * @param mixed $value String or float or null if the value is not present in the database for this instance
161
     * @param \context|null $context Context
162
     * @return ?string
163
     */
164
    public function prepare_export_value(mixed $value, ?\context $context = null): ?string {
165
        if ($value === null) {
166
            return null;
167
        } else if (round((float)$value) == 0) {
168
            $whenzero = $this->field->get_configdata_property('displaywhenzero');
169
            if ((string) $whenzero === '') {
170
                return null;
171
            } else {
172
                return format_string($whenzero, true, ['context' => $context ?? \core\context\system::instance()]);
173
            }
174
        } else {
175
            return format_float((float)$value, 0);
176
        }
177
    }
178
}