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
namespace core_badges\external;
18
 
19
use core_badges\badge;
20
use core_external\external_api;
21
use core_external\external_function_parameters;
22
use core_external\external_single_structure;
23
use core_external\external_multiple_structure;
24
use core_external\external_value;
25
use core_external\external_warnings;
26
use moodle_exception;
27
 
28
defined('MOODLE_INTERNAL') || die();
29
 
30
global $CFG;
31
require_once($CFG->libdir . '/badgeslib.php');
32
 
33
/**
34
 * External service to enable badges.
35
 *
36
 * @package   core_badges
37
 * @category  external
38
 * @copyright 2024 Sara Arjona <sara@moodle.com>
39
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 * @since     Moodle 4.5
41
 */
42
class enable_badges extends external_api {
43
 
44
    /**
45
     * Describes the parameters.
46
     *
47
     * @return external_function_parameters
48
     */
49
    public static function execute_parameters(): external_function_parameters {
50
        return new external_function_parameters([
51
            'badgeids' => new external_multiple_structure(
52
                new external_value(PARAM_TEXT, 'The badge identifiers to update', VALUE_REQUIRED),
53
            ),
54
        ]);
55
    }
56
 
57
    /**
58
     * Enable the given badges.
59
     *
60
     * @param array $badgeids List of badge identifiers to enable.
61
     * @return array The number of awarded users for each badge or 'cron' when there are more than 1000 users.
62
     */
63
    public static function execute(array $badgeids): array {
64
        global $CFG, $DB;
65
 
66
        $result = [];
67
        $warnings = [];
68
 
69
        [
70
            'badgeids' => $badgeids,
71
        ] = self::validate_parameters(self::execute_parameters(), [
72
            'badgeids' => $badgeids,
73
        ]);
74
 
75
        // Check if badges are enabled.
76
        if (empty($CFG->enablebadges)) {
77
            throw new moodle_exception('badgesdisabled', 'badges');
78
        }
79
 
80
        foreach ($badgeids as $badgeid) {
81
            $badge = new badge($badgeid);
82
 
83
            // Check capabilities.
84
            $context = $badge->get_context();
85
            self::validate_context($context);
86
            if (!has_capability('moodle/badges:configurecriteria', $context)) {
87
                $warnings[] = [
88
                    'item'        => $badgeid,
89
                    'warningcode' => 'nopermissions',
90
                    'message'     => get_string('nopermissions', 'error'),
91
                ];
92
                continue;
93
            }
94
 
95
            // Check if course badges are enabled.
96
            if (empty($CFG->badges_allowcoursebadges) && ($badge->type == BADGE_TYPE_COURSE)) {
97
                $warnings[] = [
98
                    'item'        => $badgeid,
99
                    'warningcode' => 'coursebadgesdisabled',
100
                    'message'     => get_string('coursebadgesdisabled', 'badges'),
101
                ];
102
                continue;
103
            }
104
 
105
            // Check if the badge has criteria.
106
            if (!$badge->has_criteria()) {
107
                $warnings[] = [
108
                    'item'        => $badgeid,
109
                    'warningcode' => 'nocriteria',
110
                    'message'     => get_string('nocriteria', 'badges'),
111
                ];
112
                continue;
113
            }
114
 
115
            // Activate the badge.
116
            $status = ($badge->status == BADGE_STATUS_INACTIVE) ? BADGE_STATUS_ACTIVE : BADGE_STATUS_ACTIVE_LOCKED;
117
            $badge->set_status($status);
118
            $awards = self::review_criteria($badge);
119
 
120
            $result[] = [
121
                'badgeid' => $badgeid,
122
                'awards' => $awards,
123
            ];
124
        }
125
 
126
        return [
127
            'result' => $result,
128
            'warnings' => $warnings,
129
        ];
130
    }
131
 
132
    /**
133
     * Describe the return structure of the external service.
134
     *
135
     * @return external_single_structure
136
     */
137
    public static function execute_returns(): external_single_structure {
138
        return new external_single_structure([
139
            'result' => new external_multiple_structure(
140
                new external_single_structure([
141
                    'badgeid' => new external_value(PARAM_INT, 'The badge identifier'),
142
                    'awards' => new external_value(PARAM_ALPHANUM, 'The processing result'),
143
                ]),
144
            ),
145
            'warnings' => new external_warnings(),
146
        ]);
147
    }
148
 
149
    /**
150
     * Review the criteria of the badge.
151
     *
152
     * @param \core_badges\badge $badge The badge to review the criteria.
153
     * @return string The number of awarded users or 'cron' when there are more than 1000 users.
154
     */
155
    private static function review_criteria(badge $badge): string {
156
        global $CFG, $DB;
157
 
158
        if ($badge->type == BADGE_TYPE_SITE) {
159
            // Review on cron if there are more than 1000 users who can earn a site-level badge.
160
            $sql = 'SELECT COUNT(u.id) as num
161
                        FROM {user} u
162
                    LEFT JOIN {badge_issued} bi
163
                        ON u.id = bi.userid AND bi.badgeid = :badgeid
164
                        WHERE bi.badgeid IS NULL AND u.id != :guestid AND u.deleted = 0';
165
            $toearn = $DB->get_record_sql(
166
                $sql,
167
                [
168
                    'badgeid' => $badge->id,
169
                    'guestid' => $CFG->siteguest,
170
                ],
171
            );
172
            if ($toearn->num < 1000) {
173
                $awards = $badge->review_all_criteria();
174
            } else {
175
                $awards = 'cron';
176
            }
177
        } else {
178
            $awards = $badge->review_all_criteria();
179
        }
180
 
181
        return $awards;
182
    }
183
}