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
/**
18
 * File size admin setting.
19
 *
20
 * @package    core_admin
21
 * @copyright  2019 Shamim Rezaie <shamim@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace core_admin\local\settings;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once($CFG->libdir . '/adminlib.php');
30
 
31
/**
32
 * An admin setting to support entering and displaying of file sizes in Bytes, KB, MB or GB.
33
 *
34
 * @copyright   2019 Shamim Rezaie <shamim@moodle.com>
35
 * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
36
 */
37
class filesize extends \admin_setting {
38
 
39
    /** @var int The byte unit. Number of bytes in a byte */
40
    const UNIT_B = 1;
41
 
42
    /** @var int The kilobyte unit (number of bytes in a kilobyte) */
43
    const UNIT_KB = 1024;
44
 
45
    /** @var int The megabyte unit (number of bytes in a megabyte) */
46
    const UNIT_MB = 1048576;
47
 
48
    /** @var int The gigabyte unit (number of bytes in a gigabyte) */
49
    const UNIT_GB = 1073741824;
50
 
51
    /** @var int default size unit */
52
    protected $defaultunit;
53
 
54
    /**
55
     * Constructor
56
     *
57
     * @param string    $name           unique ascii name, either 'mysetting' for settings that in config,
58
     *                                  or 'myplugin/mysetting' for ones in config_plugins.
59
     * @param string    $visiblename    localised name
60
     * @param string    $description    localised long description
61
     * @param int|null  $defaultvalue   Value of the settings in bytes
62
     * @param int|null  $defaultunit    GB, MB, etc. (in bytes)
63
     */
64
    public function __construct(string $name, string $visiblename, string $description,
65
            int $defaultvalue = null, int $defaultunit = null) {
66
 
67
        $defaultsetting = self::parse_bytes($defaultvalue);
68
 
69
        if ($defaultunit && array_key_exists($defaultunit, self::get_units())) {
70
            $this->defaultunit = $defaultunit;
71
        } else {
72
            $this->defaultunit = self::UNIT_MB;
73
        }
74
        parent::__construct($name, $visiblename, $description, $defaultsetting);
75
    }
76
 
77
    /**
78
     * Returns selectable units.
79
     *
80
     * @return  array
81
     */
82
    protected static function get_units(): array {
83
        return [
84
            self::UNIT_GB => get_string('sizegb'),
85
            self::UNIT_MB => get_string('sizemb'),
86
            self::UNIT_KB => get_string('sizekb'),
87
            self::UNIT_B  => get_string('sizeb'),
88
        ];
89
    }
90
 
91
    /**
92
     * Converts bytes to some more user friendly string.
93
     *
94
     * @param   int     $bytes  The number of bytes we want to convert from
95
     * @return  string
96
     */
97
    protected static function get_size_text(int $bytes): string {
98
        if (empty($bytes)) {
99
            return get_string('none');
100
        }
101
        return display_size($bytes, 0);
102
    }
103
 
104
    /**
105
     * Finds suitable units for given file size.
106
     *
107
     * @param   int     $bytes  The number of bytes
108
     * @return  array           Parsed file size in the format of ['v' => value, 'u' => unit]
109
     */
110
    protected static function parse_bytes(int $bytes): array {
111
        foreach (self::get_units() as $unit => $unused) {
112
            if ($bytes % $unit === 0) {
113
                return ['v' => (int)($bytes / $unit), 'u' => $unit];
114
            }
115
        }
116
        return ['v' => (int)$bytes, 'u' => self::UNIT_B];
117
    }
118
 
119
    /**
120
     * Get the selected file size as array.
121
     *
122
     * @return  array|null  An array containing 'v' => xx, 'u' => xx, or null if not set
123
     */
124
    public function get_setting(): ?array {
125
        $bytes = $this->config_read($this->name);
126
        if (is_null($bytes)) {
127
            return null;
128
        }
129
        $bytes = intval($bytes);
130
 
131
        return self::parse_bytes($bytes);
132
    }
133
 
134
    /**
135
     * Store the file size as bytes.
136
     *
137
     * @param   array   $data   Must be form 'h' => xx, 'm' => xx
138
     * @return  string          The error string if any
139
     */
140
    public function write_setting($data): string {
141
        if (!is_array($data)) {
142
            return '';
143
        }
144
 
145
        if (!is_numeric($data['v']) || $data['v'] < 0) {
146
            return get_string('errorsetting', 'admin');
147
        }
148
 
149
        // Calculate size in bytes, ensuring we don't overflow PHP_INT_MAX.
150
        $bytes = $data['v'] * $data['u'];
151
        $result = (is_int($bytes) && $this->config_write($this->name, $bytes));
152
 
153
        return ($result ? '' : get_string('errorsetting', 'admin'));
154
    }
155
 
156
    /**
157
     * Returns file size text+select fields.
158
     *
159
     * @param   array   $data   The current setting value. Must be form 'v' => xx, 'u' => xx.
160
     * @param   string  $query  Admin search query to be highlighted.
161
     * @return  string          File size text+select fields and wrapping div(s).
162
     */
163
    public function output_html($data, $query = ''): string {
164
        global $OUTPUT;
165
 
166
        $default = $this->get_defaultsetting();
167
        if (is_number($default)) {
168
            $defaultinfo = self::get_size_text($default);
169
        } else if (is_array($default)) {
170
            $defaultinfo = self::get_size_text($default['v'] * $default['u']);
171
        } else {
172
            $defaultinfo = null;
173
        }
174
 
175
        $inputid = $this->get_id() . 'v';
176
        $units = self::get_units();
177
        $defaultunit = $this->defaultunit;
178
 
179
        $context = (object) [
180
            'id' => $this->get_id(),
181
            'name' => $this->get_full_name(),
182
            'value' => $data['v'],
183
            'readonly' => $this->is_readonly(),
184
            'options' => array_map(function($unit, $title) use ($data, $defaultunit) {
185
                return [
186
                    'value' => $unit,
187
                    'name' => $title,
188
                    'selected' => ($data['v'] == 0 && $unit == $defaultunit) || $unit == $data['u']
189
                ];
190
            }, array_keys($units), $units)
191
        ];
192
 
193
        $element = $OUTPUT->render_from_template('core_admin/setting_configfilesize', $context);
194
 
195
        return format_admin_setting($this, $this->visiblename, $element, $this->description, $inputid, '', $defaultinfo, $query);
196
    }
197
}