Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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_cache\output;
18
 
19
use cache_factory;
20
use cache_store;
21
use context;
22
use core_collator;
23
use html_table;
24
use html_table_cell;
25
use html_table_row;
26
use html_writer;
27
use lang_string;
28
use moodle_url;
29
use single_select;
30
 
31
/**
32
 * The cache renderer (mainly admin interfaces).
33
 *
34
 * @package    core_cache
35
 * @copyright  2012 Sam Hemelryk
36
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37
 */
38
class renderer extends \plugin_renderer_base {
39
 
40
    /**
41
     * Displays store summaries.
42
     *
43
     * @param array $storeinstancesummaries information about each store instance,
44
     *      as returned by core_cache\administration_helper::get_store_instance_summaries().
45
     * @param array $storepluginsummaries information about each store plugin as
46
     *      returned by core_cache\administration_helper::get_store_plugin_summaries().
47
     * @return string HTML
48
     */
49
    public function store_instance_summariers(array $storeinstancesummaries, array $storepluginsummaries) {
50
        $table = new html_table();
51
        $table->head = array(
52
            get_string('storename', 'cache'),
53
            get_string('plugin', 'cache'),
54
            get_string('storeready', 'cache'),
55
            get_string('mappings', 'cache'),
56
            get_string('modes', 'cache'),
57
            get_string('supports', 'cache'),
58
            get_string('locking', 'cache') . ' ' . $this->output->help_icon('locking', 'cache'),
59
            get_string('actions', 'cache'),
60
        );
61
        $table->colclasses = array(
62
            'storename',
63
            'plugin',
64
            'storeready',
65
            'mappings',
66
            'modes',
67
            'supports',
68
            'locking',
69
            'actions'
70
        );
71
        $table->data = array();
72
 
73
        $defaultstoreactions = get_string('defaultstoreactions', 'cache');
74
 
75
        foreach ($storeinstancesummaries as $name => $storesummary) {
76
            $htmlactions = cache_factory::get_administration_display_helper()->get_store_instance_actions($name, $storesummary);
77
            $modes = array();
78
            foreach ($storesummary['modes'] as $mode => $enabled) {
79
                if ($enabled) {
80
                    $modes[] = get_string('mode_'.$mode, 'cache');
81
                }
82
            }
83
 
84
            $supports = array();
85
            foreach ($storesummary['supports'] as $support => $enabled) {
86
                if ($enabled) {
87
                    $supports[] = get_string('supports_'.$support, 'cache');
88
                }
89
            }
90
 
91
            $info = '';
92
            if (!empty($storesummary['default'])) {
93
                $info = $this->output->pix_icon('i/info', $defaultstoreactions, '', array('class' => 'icon'));
94
            }
95
 
96
            $isready = $storesummary['isready'] && $storesummary['requirementsmet'];
97
            $readycell = new html_table_cell;
98
            if ($isready) {
99
                $readycell->text = $this->output->pix_icon('i/valid', '1');
100
            }
101
 
102
            $storename = $storesummary['name'];
103
            if (!empty($storesummary['default'])) {
104
                $storename = get_string('store_'.$storesummary['name'], 'cache');
105
            }
106
            if (!$isready && (int)$storesummary['mappings'] > 0) {
107
                $readycell->text = $this->output->help_icon('storerequiresattention', 'cache');
108
                $readycell->attributes['class'] = 'store-requires-attention';
109
            }
110
 
111
            $lock = $storesummary['lock']['name'];
112
            if (!empty($storesummary['lock']['default'])) {
113
                $lock = get_string($storesummary['lock']['name'], 'cache');
114
            }
115
 
116
            $row = new html_table_row(array(
117
                $storename,
118
                get_string('pluginname', 'cachestore_'.$storesummary['plugin']),
119
                $readycell,
120
                $storesummary['mappings'],
121
                join(', ', $modes),
122
                join(', ', $supports),
123
                $lock,
124
                $info.join(', ', $htmlactions)
125
            ));
126
            $row->attributes['class'] = 'store-'.$name;
127
            if ($storesummary['default']) {
128
                $row->attributes['class'] .= ' default-store';
129
            }
130
            $table->data[] = $row;
131
        }
132
 
133
        $html  = html_writer::start_tag('div', array('id' => 'core-cache-store-summaries'));
134
        $html .= $this->output->heading(get_string('storesummaries', 'cache'), 3);
135
        $html .= html_writer::table($table);
136
        $html .= html_writer::end_tag('div');
137
        return $html;
138
    }
139
 
140
    /**
141
     * Displays plugin summaries.
142
     *
143
     * @param array $storepluginsummaries information about each store plugin as
144
     *      returned by core_cache\administration_helper::get_store_plugin_summaries().
145
     * @return string HTML
146
     */
147
    public function store_plugin_summaries(array $storepluginsummaries) {
148
        $table = new html_table();
149
        $table->head = array(
150
            get_string('plugin', 'cache'),
151
            get_string('storeready', 'cache'),
152
            get_string('stores', 'cache'),
153
            get_string('modes', 'cache'),
154
            get_string('supports', 'cache'),
155
            get_string('actions', 'cache'),
156
        );
157
        $table->colclasses = array(
158
            'plugin',
159
            'storeready',
160
            'stores',
161
            'modes',
162
            'supports',
163
            'actions'
164
        );
165
        $table->data = array();
166
 
167
        foreach ($storepluginsummaries as $name => $plugin) {
168
            $htmlactions = cache_factory::get_administration_display_helper()->get_store_plugin_actions($name, $plugin);
169
 
170
            $modes = array();
171
            foreach ($plugin['modes'] as $mode => $enabled) {
172
                if ($enabled) {
173
                    $modes[] = get_string('mode_'.$mode, 'cache');
174
                }
175
            }
176
 
177
            $supports = array();
178
            foreach ($plugin['supports'] as $support => $enabled) {
179
                if ($enabled) {
180
                    $supports[] = get_string('supports_'.$support, 'cache');
181
                }
182
            }
183
 
184
            $row = new html_table_row(array(
185
                $plugin['name'],
186
                ($plugin['requirementsmet']) ? $this->output->pix_icon('i/valid', '1') : '',
187
                $plugin['instances'],
188
                join(', ', $modes),
189
                join(', ', $supports),
190
                join(', ', $htmlactions)
191
            ));
192
 
193
            $row->attributes['class'] = 'plugin-'.$name;
194
            $table->data[] = $row;
195
        }
196
 
197
        $html  = html_writer::start_tag('div', array('id' => 'core-cache-plugin-summaries'));
198
        $html .= $this->output->heading(get_string('pluginsummaries', 'cache'), 3);
199
        $html .= html_writer::table($table);
200
        $html .= html_writer::end_tag('div');
201
        return $html;
202
    }
203
 
204
    /**
205
     * Displays definition summaries.
206
     *
207
     * @param array $definitionsummaries information about each definition, as returned by
208
     *      core_cache\administration_helper::get_definition_summaries().
209
     * @param context $context the system context.
210
     *
211
     * @return string HTML.
212
     */
213
    public function definition_summaries(array $definitionsummaries, context $context) {
214
        $table = new html_table();
215
        $table->head = array(
216
            get_string('definition', 'cache'),
217
            get_string('mode', 'cache'),
218
            get_string('component', 'cache'),
219
            get_string('area', 'cache'),
220
            get_string('mappings', 'cache'),
221
            get_string('sharing', 'cache'),
222
            get_string('canuselocalstore', 'cache'),
223
            get_string('actions', 'cache')
224
        );
225
        $table->colclasses = array(
226
            'definition',
227
            'mode',
228
            'component',
229
            'area',
230
            'mappings',
231
            'sharing',
232
            'canuselocalstore',
233
            'actions'
234
        );
235
        $table->data = array();
236
 
237
        core_collator::asort_array_of_arrays_by_key($definitionsummaries, 'name');
238
 
239
        $none = new lang_string('none', 'cache');
240
        foreach ($definitionsummaries as $id => $definition) {
241
            $htmlactions = cache_factory::get_administration_display_helper()->get_definition_actions($context, $definition);
242
            if (!empty($definition['mappings'])) {
243
                $mapping = join(', ', $definition['mappings']);
244
            } else {
245
                $mapping = '<em>'.$none.'</em>';
246
            }
247
 
248
            $uselocalcachecol = get_string('no');
249
            if ($definition['mode'] != cache_store::MODE_REQUEST) {
250
                if (isset($definition['canuselocalstore']) && $definition['canuselocalstore']) {
251
                    $uselocalcachecol = get_string('yes');
252
                }
253
            }
254
 
255
            $row = new html_table_row(array(
256
                $definition['name'],
257
                get_string('mode_'.$definition['mode'], 'cache'),
258
                $definition['component'],
259
                $definition['area'],
260
                $mapping,
261
                join(', ', $definition['selectedsharingoption']),
262
                $uselocalcachecol,
263
                join(', ', $htmlactions)
264
            ));
265
            $row->attributes['class'] = 'definition-'.$definition['component'].'-'.$definition['area'];
266
            $table->data[] = $row;
267
        }
268
 
269
        $html  = html_writer::start_tag('div', array('id' => 'core-cache-definition-summaries'));
270
        $html .= $this->output->heading(get_string('definitionsummaries', 'cache'), 3);
271
        $html .= html_writer::table($table);
272
 
273
        $url = new moodle_url('/cache/admin.php', array('action' => 'rescandefinitions', 'sesskey' => sesskey()));
274
        $link = html_writer::link($url, get_string('rescandefinitions', 'cache'));
275
        $html .= html_writer::tag('div', $link, array('id' => 'core-cache-rescan-definitions'));
276
 
277
        $html .= html_writer::end_tag('div');
278
        return $html;
279
    }
280
 
281
    /**
282
     * Displays mode mappings
283
     *
284
     * @param string $applicationstore
285
     * @param string $sessionstore
286
     * @param string $requeststore
287
     * @param moodle_url $editurl
288
     * @return string HTML
289
     */
290
    public function mode_mappings($applicationstore, $sessionstore, $requeststore, moodle_url $editurl) {
291
        $table = new html_table();
292
        $table->colclasses = array(
293
            'mode',
294
            'mapping',
295
        );
296
        $table->rowclasses = array(
297
            'mode_application',
298
            'mode_session',
299
            'mode_request'
300
        );
301
        $table->head = array(
302
            get_string('mode', 'cache'),
303
            get_string('mappings', 'cache'),
304
        );
305
        $table->data = array(
306
            array(get_string('mode_'.cache_store::MODE_APPLICATION, 'cache'), $applicationstore),
307
            array(get_string('mode_'.cache_store::MODE_SESSION, 'cache'), $sessionstore),
308
            array(get_string('mode_'.cache_store::MODE_REQUEST, 'cache'), $requeststore)
309
        );
310
 
311
        $html = html_writer::start_tag('div', array('id' => 'core-cache-mode-mappings'));
312
        $html .= $this->output->heading(get_string('defaultmappings', 'cache'), 3);
313
        $html .= html_writer::table($table);
314
        $link = html_writer::link($editurl, get_string('editmappings', 'cache'));
315
        $html .= html_writer::tag('div', $link, array('class' => 'edit-link'));
316
        $html .= html_writer::end_tag('div');
317
        return $html;
318
    }
319
 
320
    /**
321
     * Display basic information about lock instances.
322
     *
323
     * @todo Add some actions so that people can configure lock instances.
324
     *
325
     * @param array $locks
326
     * @return string
327
     */
328
    public function lock_summaries(array $locks) {
329
        $table = new html_table();
330
        $table->colclasses = array(
331
            'name',
332
            'type',
333
            'default',
334
            'uses',
335
            'actions'
336
        );
337
        $table->rowclasses = array(
338
            'lock_name',
339
            'lock_type',
340
            'lock_default',
341
            'lock_uses',
342
            'lock_actions',
343
        );
344
        $table->head = array(
345
            get_string('lockname', 'cache'),
346
            get_string('locktype', 'cache'),
347
            get_string('lockdefault', 'cache'),
348
            get_string('lockuses', 'cache'),
349
            get_string('actions', 'cache')
350
        );
351
        $table->data = array();
352
        $tick = $this->output->pix_icon('i/valid', '');
353
        foreach ($locks as $lock) {
354
            $actions = array();
355
            if ($lock['uses'] === 0 && !$lock['default']) {
356
                $url = new moodle_url('/cache/admin.php', array('lock' => $lock['name'], 'action' => 'deletelock'));
357
                $actions[] = html_writer::link($url, get_string('delete', 'cache'));
358
            }
359
            $table->data[] = new html_table_row(array(
360
                new html_table_cell($lock['name']),
361
                new html_table_cell($lock['type']),
362
                new html_table_cell($lock['default'] ? $tick : ''),
363
                new html_table_cell($lock['uses']),
364
                new html_table_cell(join(' ', $actions))
365
            ));
366
        }
367
 
368
        $html = html_writer::start_tag('div', array('id' => 'core-cache-lock-summary'));
369
        $html .= $this->output->heading(get_string('locksummary', 'cache'), 3);
370
        $html .= html_writer::table($table);
371
        $html .= html_writer::end_tag('div');
372
        return $html;
373
    }
374
 
375
    /**
376
     * Renders additional actions for locks, such as Add.
377
     *
378
     * @return string
379
     */
380
    public function additional_lock_actions(): string {
381
        $url = new moodle_url('/cache/admin.php', array('action' => 'newlockinstance'));
382
        $select = new single_select($url, 'lock', cache_factory::get_administration_display_helper()->get_addable_lock_options());
383
        $select->label = get_string('addnewlockinstance', 'cache');
384
 
385
        $html = html_writer::start_tag('div', array('id' => 'core-cache-lock-additional-actions'));
386
        $html .= html_writer::tag('div', $this->output->render($select), array('class' => 'new-instance'));
387
        $html .= html_writer::end_tag('div');
388
        return $html;
389
    }
390
 
391
    /**
392
     * Renders an array of notifications for the cache configuration screen.
393
     *
394
     * Takes an array of notifications with the form:
395
     * $notifications = array(
396
     *     array('This is a success message', true),
397
     *     array('This is a failure message', false),
398
     * );
399
     *
400
     * @param array $notifications
401
     * @return string
402
     */
403
    public function notifications(array $notifications = array()) {
404
        if (count($notifications) === 0) {
405
            // There are no notifications to render.
406
            return '';
407
        }
408
        $html = html_writer::start_div('notifications');
409
        foreach ($notifications as $notification) {
410
            list($message, $notifysuccess) = $notification;
411
            $html .= $this->notification($message, ($notifysuccess) ? 'notifysuccess' : 'notifyproblem');
412
        }
413
        $html .= html_writer::end_div();
414
        return $html;
415
    }
416
 
417
    /**
418
     * Creates the two tables which display on the usage page.
419
     *
420
     * @param array $usage Usage information (from cache_helper::usage)
421
     * @return array Array of 2 tables (main and summary table)
422
     * @throws \coding_exception
423
     */
424
    public function usage_tables(array $usage): array {
425
        $table = new \html_table();
426
        $table->id = 'usage_main';
427
        $table->head = [
428
            get_string('definition', 'cache'),
429
            get_string('storename', 'cache'),
430
            get_string('plugin', 'cache'),
431
            get_string('usage_items', 'cache'),
432
            get_string('usage_mean', 'cache'),
433
            get_string('usage_sd', 'cache'),
434
            get_string('usage_total', 'cache'),
435
            get_string('usage_totalmargin', 'cache')];
436
        $table->align = [
437
            'left', 'left', 'left',
438
            'right', 'right', 'right', 'right', 'right'
439
        ];
440
        $table->data = [];
441
 
442
        $summarytable = new \html_table();
443
        $summarytable->id = 'usage_summary';
444
        $summarytable->head = [
445
            get_string('storename', 'cache'),
446
            get_string('plugin', 'cache'),
447
            get_string('usage_total', 'cache'),
448
            get_string('usage_realtotal', 'cache')
449
        ];
450
        $summarytable->align = [
451
            'left', 'left',
452
            'right', 'right',
453
        ];
454
        $summarytable->data = [];
455
        $summarytable->attributes['class'] = 'generaltable w-auto';
456
        $storetotals = [];
457
 
458
        // We will highlight all cells that are more than 2% of total size, so work that out first.
459
        $total = 0;
460
        foreach ($usage as $definition) {
461
            foreach ($definition->stores as $storedata) {
462
                $total += $storedata->items * $storedata->mean;
463
            }
464
        }
465
        $highlightover = round($total / 50);
466
 
467
        foreach ($usage as $definition) {
468
            foreach ($definition->stores as $storedata) {
469
                $row = [];
470
                $row[] = s($definition->cacheid);
471
                $row[] = s($storedata->name);
472
                $row[] = s($storedata->class);
473
                if (!$storedata->supported) {
474
                    // We don't have data for this store because it isn't searchable.
475
                    $row[] = '-';
476
                } else {
477
                    $row[] = $storedata->items;
478
                }
479
                if ($storedata->items) {
480
                    $row[] = display_size(round($storedata->mean));
481
                    if ($storedata->items > 1) {
482
                        $row[] = display_size(round($storedata->sd));
483
                    } else {
484
                        $row[] = '';
485
                    }
486
                    $cellsize = round($storedata->items * $storedata->mean);
487
                    $row[] = display_size($cellsize, 1, 'MB');
488
 
489
                    if (!array_key_exists($storedata->name, $storetotals)) {
490
                        $storetotals[$storedata->name] = (object)[
491
                            'plugin' => $storedata->class,
492
                            'total' => 0,
493
                            'storetotal' => $storedata->storetotal,
494
                        ];
495
                    }
496
                    $storetotals[$storedata->name]->total += $cellsize;
497
                } else {
498
                    $row[] = '';
499
                    $row[] = '';
500
                    $cellsize = 0;
501
                    $row[] = '';
502
                }
503
                if ($storedata->margin) {
504
                    // Plus or minus.
505
                    $row[] = '&#xb1;' . display_size($storedata->margin * $storedata->items, 1, 'MB');
506
                } else {
507
                    $row[] = '';
508
                }
509
                $htmlrow = new \html_table_row($row);
510
                if ($cellsize > $highlightover) {
511
                    $htmlrow->attributes = ['class' => 'table-warning'];
512
                }
513
                $table->data[] = $htmlrow;
514
            }
515
        }
516
 
517
        ksort($storetotals);
518
 
519
        foreach ($storetotals as $storename => $storedetails) {
520
            $row = [s($storename), s($storedetails->plugin)];
521
            $row[] = display_size($storedetails->total, 1, 'MB');
522
            if ($storedetails->storetotal !== null) {
523
                $row[] = display_size($storedetails->storetotal, 1, 'MB');
524
            } else {
525
                $row[] = '-';
526
            }
527
            $summarytable->data[] = $row;
528
        }
529
 
530
        return [$table, $summarytable];
531
    }
532
 
533
    /**
534
     * Renders the usage page.
535
     *
536
     * @param \html_table $maintable Main table
537
     * @param \html_table $summarytable Summary table
538
     * @param \moodleform $samplesform Form to select number of samples
539
     * @return string HTML for page
540
     */
541
    public function usage_page(\html_table $maintable, \html_table $summarytable, \moodleform $samplesform): string {
542
        $data = [
543
            'maintable' => \html_writer::table($maintable),
544
            'summarytable' => \html_writer::table($summarytable),
545
            'samplesform' => $samplesform->render()
546
        ];
547
 
548
        return $this->render_from_template('core_cache/usage', $data);
549
    }
550
}