MDL-51360 core_grades: Improve documentation of grade_get_grades().
[moodle.git] / lib / classes / userfeedback.php
blob67e85054e7560d9739adf4911bafa5964cc7cd6c
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.
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/>.
17 /**
18 * This file contains the core_userfeedback class
20 * @package core
21 * @copyright 2020 Shamim Rezaie <shamim@moodle.com>
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 use core\hook\output\before_standard_footer_html_generation;
27 /**
28 * This Class contains helper functions for user feedback functionality.
30 * @copyright 2020 Shamim Rezaie <shamim@moodle.com>
31 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33 class core_userfeedback {
34 /**
35 * @var int Ask user to give feedback a few days after each major upgrade.
37 public const REMIND_AFTER_UPGRADE = 1;
39 /**
40 * @var int Ask user to give feedback periodically.
42 public const REMIND_PERIODICALLY = 2;
44 /**
45 * @var int Do not ask user to give feedback.
47 public const REMIND_NEVER = 3;
49 /**
50 * Displays the feedback reminder block.
52 public static function print_reminder_block(): void {
53 global $PAGE;
55 static $jscalled = false;
57 $actions = [
59 'title' => get_string('calltofeedback_give'),
60 'url' => static::make_link()->out(false),
61 'data' => [
62 'action' => 'give',
63 'record' => 1,
64 'hide' => 1,
66 'newwindow' => true,
69 'title' => get_string('calltofeedback_remind'),
70 'url' => '#',
71 'data' => [
72 'action' => 'remind',
73 'record' => 1,
74 'hide' => 1,
78 $icon = [
79 'pix' => 'i/bullhorn',
80 'component' => 'core'
83 \core\notification::add_call_to_action($icon, get_string('calltofeedback'), $actions, 'core/userfeedback');
85 if (!$jscalled) {
86 $jscalled = true;
87 // Calling the following more than once will register event listeners twice.
88 $PAGE->requires->js_call_amd('core/userfeedback', 'registerEventListeners');
92 /**
93 * Indicates whether the feedback reminder block should be shown or not.
95 * @return bool
97 public static function should_display_reminder(): bool {
98 global $CFG;
100 if (static::can_give_feedback()) {
101 $give = get_user_preferences('core_userfeedback_give');
102 $remind = get_user_preferences('core_userfeedback_remind');
104 $lastactiontime = max($give ?: 0, $remind ?: 0);
106 switch ($CFG->userfeedback_nextreminder) {
107 case static::REMIND_AFTER_UPGRADE:
108 $lastupgrade = static::last_major_upgrade_time();
109 if ($lastupgrade >= $lastactiontime) {
110 return $lastupgrade + ($CFG->userfeedback_remindafter * DAYSECS) < time();
112 break;
113 case static::REMIND_PERIODICALLY:
114 return $lastactiontime + ($CFG->userfeedback_remindafter * DAYSECS) < time();
115 break;
118 return false;
122 * Prepare and return the URL of the feedback site
124 * @return moodle_url
126 public static function make_link(): moodle_url {
127 global $CFG, $PAGE;
129 $baseurl = $CFG->userfeedback_url ?? 'https://feedback.moodle.org/lms';
130 $lang = clean_param(current_language(), PARAM_LANG); // Avoid breaking WS because of incorrect package langs.
131 $moodleurl = $CFG->wwwroot;
132 $moodleversion = $CFG->release;
133 $theme = $PAGE->theme->name;
134 $themeversion = get_config('theme_'.$theme, 'version');
136 $url = new moodle_url($baseurl, [
137 'lang' => $lang,
138 'moodle_url' => $moodleurl,
139 'moodle_version' => $moodleversion,
140 'theme' => $theme,
141 'theme_version' => $themeversion,
142 'newtest' => 'Y', // Respondents might be using the same device/browser to fill out the survey.
143 // The newtest param resets the session.
146 return $url;
150 * Callback for the before_standard_footer_html_generation hook to add a user feedback footer link if configured.
152 * @param before_standard_footer_html_generation $hook
154 public static function before_standard_footer_html_generation(
155 before_standard_footer_html_generation $hook,
156 ): void {
157 if (self::can_give_feedback()) {
158 $hook->add_html(html_writer::div(
159 $hook->renderer->render_from_template(
160 'core/userfeedback_footer_link',
162 'url' => self::make_link()->out(false),
170 * Whether the current can give feedback.
172 * @return bool
174 public static function can_give_feedback(): bool {
175 global $CFG;
177 return !empty($CFG->enableuserfeedback) && isloggedin() && !isguestuser();
181 * Returns the last major upgrade time
183 * @return int
185 private static function last_major_upgrade_time(): int {
186 global $DB;
188 $targetversioncast = $DB->sql_cast_char2real('targetversion');
189 $versioncast = $DB->sql_cast_char2real('version');
191 // A time difference more than 3 months has to be a core upgrade.
192 // Also, passing IGNORE_MULTIPLE because we are only interested in the first field and LIMIT is not cross-DB.
193 $time = $DB->get_field_sql("SELECT timemodified
194 FROM {upgrade_log}
195 WHERE plugin = 'core' AND $targetversioncast - $versioncast > 30000
196 ORDER BY timemodified DESC", null, IGNORE_MULTIPLE);
198 return (int)$time;