2 // This file is part of Moodle - http://moodle.org/
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.
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/>.
18 * Glossary Random block.
20 * @package block_glossary_random
21 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 define('BGR_RANDOMLY', '0');
26 define('BGR_LASTMODIFIED', '1');
27 define('BGR_NEXTONE', '2');
28 define('BGR_NEXTALPHA', '3');
30 class block_glossary_random
extends block_base
{
33 * @var cm_info|stdClass has properties 'id' (course module id) and 'uservisible'
34 * (whether the glossary is visible to the current user)
36 protected $glossarycm = null;
39 $this->title
= get_string('pluginname','block_glossary_random');
42 function specialization() {
45 require_once($CFG->libdir
. '/filelib.php');
47 $this->course
= $this->page
->course
;
49 // load userdefined title and make sure it's never empty
50 if (empty($this->config
->title
)) {
51 $this->title
= get_string('pluginname','block_glossary_random');
53 $this->title
= format_string($this->config
->title
, true, ['context' => $this->context
]);
56 if (empty($this->config
->glossary
)) {
60 if (!isset($this->config
->nexttime
)) {
61 $this->config
->nexttime
= 0;
64 //check if it's time to put a new entry in cache
65 if (time() > $this->config
->nexttime
) {
67 if (!($cm = $this->get_glossary_cm()) ||
!$cm->uservisible
) {
68 // Skip generating of the cache if we can't display anything to the current user.
72 // place glossary concept and definition in $pref->cache
73 if (!$numberofentries = $DB->count_records('glossary_entries',
74 array('glossaryid'=>$this->config
->glossary
, 'approved'=>1))) {
75 $this->config
->cache
= get_string('noentriesyet','block_glossary_random');
76 $this->instance_config_commit();
79 $glossaryctx = context_module
::instance($cm->id
);
84 $orderby = 'timemodified ASC';
86 switch ($this->config
->type
) {
89 $i = ($numberofentries > 1) ?
rand(1, $numberofentries) : 1;
94 if (isset($this->config
->previous
)) {
95 $i = $this->config
->previous +
1;
99 if ($i > $numberofentries) { // Loop back to beginning
106 $orderby = 'concept ASC';
107 if (isset($this->config
->previous
)) {
108 $i = $this->config
->previous +
1;
112 if ($i > $numberofentries) { // Loop back to beginning
118 default: // BGR_LASTMODIFIED
119 $i = $numberofentries;
121 $orderby = 'timemodified DESC, id DESC';
125 if ($entry = $DB->get_records_sql("SELECT id, concept, definition, definitionformat, definitiontrust
126 FROM {glossary_entries}
127 WHERE glossaryid = ? AND approved = 1
128 ORDER BY $orderby", array($this->config
->glossary
), $limitfrom, $limitnum)) {
130 $entry = reset($entry);
132 if (empty($this->config
->showconcept
)) {
135 $text = "<h3>".format_string($entry->concept
,true)."</h3>";
138 $options = new stdClass();
139 $options->trusted
= $entry->definitiontrust
;
140 $options->overflowdiv
= true;
141 $entry->definition
= file_rewrite_pluginfile_urls($entry->definition
, 'pluginfile.php', $glossaryctx->id
, 'mod_glossary', 'entry', $entry->id
);
142 $text .= format_text($entry->definition
, $entry->definitionformat
, $options);
144 $this->config
->nexttime
= usergetmidnight(time()) + DAYSECS
* $this->config
->refresh
;
145 $this->config
->previous
= $i;
148 $text = get_string('noentriesyet','block_glossary_random');
151 $this->config
->cache
= $text;
152 $this->instance_config_commit();
157 * Replace the instance's configuration data with those currently in $this->config;
159 function instance_config_commit($nolongerused = false) {
160 // Unset config variables that are no longer used.
161 unset($this->config
->globalglossary
);
162 unset($this->config
->courseid
);
163 parent
::instance_config_commit($nolongerused);
167 * Checks if glossary is available - it should be either located in the same course or be global
169 * @return null|cm_info|stdClass object with properties 'id' (course module id) and 'uservisible'
171 protected function get_glossary_cm() {
173 if (empty($this->config
->glossary
)) {
174 // No glossary is configured.
178 if (!empty($this->glossarycm
)) {
179 return $this->glossarycm
;
182 if (!empty($this->page
->course
->id
)) {
183 // First check if glossary belongs to the current course (we don't need to make any DB queries to find it).
184 $modinfo = get_fast_modinfo($this->page
->course
);
185 if (isset($modinfo->instances
['glossary'][$this->config
->glossary
])) {
186 $this->glossarycm
= $modinfo->instances
['glossary'][$this->config
->glossary
];
187 if ($this->glossarycm
->uservisible
) {
188 // The glossary is in the same course and is already visible to the current user,
189 // no need to check if it is global, save on DB query.
190 return $this->glossarycm
;
195 // Find course module id for the given glossary, only if it is global.
196 $cm = $DB->get_record_sql("SELECT cm.id, cm.visible AS uservisible
197 FROM {course_modules} cm
198 JOIN {modules} md ON md.id = cm.module
199 JOIN {glossary} g ON g.id = cm.instance
200 WHERE g.id = :instance AND md.name = :modulename AND g.globalglossary = 1",
201 ['instance' => $this->config
->glossary
, 'modulename' => 'glossary']);
204 // This is a global glossary, create an object with properties 'id' and 'uservisible'. We don't need any
205 // other information so why bother retrieving it. Full access check is skipped for global glossaries for
206 // performance reasons.
207 $this->glossarycm
= $cm;
208 } else if (empty($this->glossarycm
)) {
209 // Glossary does not exist. Remove it in the config so we don't repeat this check again later.
210 $this->config
->glossary
= 0;
211 $this->instance_config_commit();
214 return $this->glossarycm
;
217 function instance_allow_multiple() {
218 // Are you going to allow multiple instances of each block?
219 // If yes, then it is assumed that the block WILL USE per-instance configuration
223 function get_content() {
224 if ($this->content
!== null) {
225 return $this->content
;
227 $this->content
= (object)['text' => '', 'footer' => ''];
229 if (!$cm = $this->get_glossary_cm()) {
230 if ($this->user_can_edit()) {
231 $this->content
->text
= get_string('notyetconfigured', 'block_glossary_random');
233 return $this->content
;
236 if (empty($this->config
->cache
)) {
237 $this->config
->cache
= '';
240 if ($cm->uservisible
) {
241 // Show glossary if visible and place links in footer.
242 $this->content
->text
= $this->config
->cache
;
243 if (has_capability('mod/glossary:write', context_module
::instance($cm->id
))) {
244 $this->content
->footer
= html_writer
::link(new moodle_url('/mod/glossary/edit.php', ['cmid' => $cm->id
]),
245 format_string($this->config
->addentry
)) . '<br/>';
248 $this->content
->footer
.= html_writer
::link(new moodle_url('/mod/glossary/view.php', ['id' => $cm->id
]),
249 format_string($this->config
->viewglossary
));
251 // Otherwise just place some text, no link.
252 $this->content
->footer
= format_string($this->config
->invisible
);
255 return $this->content
;