mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-53240 filetypes: Introduce admin_setting_filetypes class
This new type of admin settings makes use of the filetypes browser but for the admin settings.
This commit is contained in:
parent
8b493eb09d
commit
8cf36e9c81
52
admin/templates/setting_filetypes.mustache
Normal file
52
admin/templates/setting_filetypes.mustache
Normal file
@ -0,0 +1,52 @@
|
||||
{{!
|
||||
This file is part of Moodle - http://moodle.org/
|
||||
|
||||
Moodle is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Moodle is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
}}
|
||||
{{!
|
||||
@template core_admin/setting_filetypes
|
||||
|
||||
Renders the admin_setting_filetypes setting element.
|
||||
|
||||
Context variables required for this template:
|
||||
* id - element id
|
||||
* name - form element name
|
||||
* value - element value
|
||||
* descriptions - data for the core_form/filetypes-descriptions template
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"id": "test0",
|
||||
"name": "test",
|
||||
"value": ".jpg,.gif",
|
||||
"descriptions": {
|
||||
"hasdescriptions": true,
|
||||
"descriptions": [
|
||||
{
|
||||
"description": "Image (JPEG)",
|
||||
"extensions": ".jpeg .jpe .jpg"
|
||||
},
|
||||
{
|
||||
"description": "Image (GIF)",
|
||||
"extensions": ".gif"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}}
|
||||
<div class="form-text defaultsnext">
|
||||
<input type="text" name="{{name}}" value="{{value}}" size="30" id="{{id}}" class="text-ltr">
|
||||
<span data-filetypesbrowser="{{id}}"></span>
|
||||
<div data-filetypesdescriptions="{{id}}">{{#descriptions}}{{>core_form/filetypes-descriptions}}{{/descriptions}}</div>
|
||||
</div>
|
@ -42,6 +42,7 @@ $string['err_numeric'] = 'You must enter a number here.';
|
||||
$string['err_rangelength'] = 'You must enter between {$a->format[0]} and {$a->format[1]} characters here.';
|
||||
$string['err_required'] = 'You must supply a value here.';
|
||||
$string['filetypesany'] = 'All file types';
|
||||
$string['filetypesnotwhitelisted'] = 'These file types are not allowed here: {$a}';
|
||||
$string['filetypesothers'] = 'Other files';
|
||||
$string['general'] = 'General';
|
||||
$string['hideadvanced'] = 'Hide advanced';
|
||||
|
118
lib/adminlib.php
118
lib/adminlib.php
@ -10519,3 +10519,121 @@ class admin_setting_scsscode extends admin_setting_configtextarea {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Administration setting to define a list of file types.
|
||||
*
|
||||
* @copyright 2016 Jonathon Fowler <fowlerj@usq.edu.au>
|
||||
* @copyright 2017 David Mudrák <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class admin_setting_filetypes extends admin_setting_configtext {
|
||||
|
||||
/** @var array Allow selection from these file types only. */
|
||||
protected $onlytypes = [];
|
||||
|
||||
/** @var bool Allow selection of 'All file types' (will be stored as '*'). */
|
||||
protected $allowall = true;
|
||||
|
||||
/** @var core_form\filetypes_util instance to use as a helper. */
|
||||
protected $util = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $name Unique ascii name like 'mycoresetting' or 'myplugin/mysetting'
|
||||
* @param string $visiblename Localised label of the setting
|
||||
* @param string $description Localised description of the setting
|
||||
* @param string $defaultsetting Default setting value.
|
||||
* @param array $options Setting widget options, an array with optional keys:
|
||||
* 'onlytypes' => array Allow selection from these file types only; for example ['onlytypes' => ['web_image']].
|
||||
* 'allowall' => bool Allow to select 'All file types', defaults to true. Does not apply if onlytypes are set.
|
||||
*/
|
||||
public function __construct($name, $visiblename, $description, $defaultsetting = '', array $options = []) {
|
||||
|
||||
parent::__construct($name, $visiblename, $description, $defaultsetting, PARAM_RAW);
|
||||
|
||||
if (array_key_exists('onlytypes', $options) && is_array($options['onlytypes'])) {
|
||||
$this->onlytypes = $options['onlytypes'];
|
||||
}
|
||||
|
||||
if (!$this->onlytypes && array_key_exists('allowall', $options)) {
|
||||
$this->allowall = (bool)$options['allowall'];
|
||||
}
|
||||
|
||||
$this->util = new \core_form\filetypes_util();
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize the user's input and write it to the database as comma separated list.
|
||||
*
|
||||
* Comma separated list as a text representation of the array was chosen to
|
||||
* make this compatible with how the $CFG->courseoverviewfilesext values are stored.
|
||||
*
|
||||
* @param string $data Value submitted by the admin.
|
||||
* @return string Epty string if all good, error message otherwise.
|
||||
*/
|
||||
public function write_setting($data) {
|
||||
return parent::write_setting(implode(',', $this->util->normalize_file_types($data)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate data before storage
|
||||
*
|
||||
* @param string $data The setting values provided by the admin
|
||||
* @return bool|string True if ok, the string if error found
|
||||
*/
|
||||
public function validate($data) {
|
||||
|
||||
// No need to call parent's validation here as we are PARAM_RAW.
|
||||
|
||||
if ($this->util->is_whitelisted($data, $this->onlytypes)) {
|
||||
return true;
|
||||
|
||||
} else {
|
||||
$troublemakers = $this->util->get_not_whitelisted($data, $this->onlytypes);
|
||||
return get_string('filetypesnotwhitelisted', 'core_form', implode(' ', $troublemakers));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an HTML string for the setting element.
|
||||
*
|
||||
* @param string $data The current setting value
|
||||
* @param string $query Admin search query to be highlighted
|
||||
* @return string HTML to be displayed
|
||||
*/
|
||||
public function output_html($data, $query='') {
|
||||
global $OUTPUT, $PAGE;
|
||||
|
||||
$default = $this->get_defaultsetting();
|
||||
$context = (object) [
|
||||
'id' => $this->get_id(),
|
||||
'name' => $this->get_full_name(),
|
||||
'value' => $data,
|
||||
'descriptions' => $this->util->describe_file_types($data),
|
||||
];
|
||||
$element = $OUTPUT->render_from_template('core_admin/setting_filetypes', $context);
|
||||
|
||||
$PAGE->requires->js_call_amd('core_form/filetypes', 'init', [
|
||||
$this->get_id(),
|
||||
$this->visiblename,
|
||||
$this->onlytypes,
|
||||
$this->allowall,
|
||||
]);
|
||||
|
||||
return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $default, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the values be always displayed in LTR mode?
|
||||
*
|
||||
* We always return true here because these values are not RTL compatible.
|
||||
*
|
||||
* @return bool True because these values are not RTL compatible.
|
||||
*/
|
||||
public function get_force_ltr() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -414,25 +414,42 @@ class filetypes_util {
|
||||
* Should the given file type be considered as a part of the given whitelist.
|
||||
*
|
||||
* If multiple types are provided, all of them must be part of the
|
||||
* whitelist.
|
||||
* whitelist. Empty type is part of any whitelist. Any type is part of an
|
||||
* empty whitelist.
|
||||
*
|
||||
* @param string $types One or more types in a string (space , or ; separated)
|
||||
* @param string|array $whitelist an array or string of whitelisted types
|
||||
* @param string|array $types File types to be checked
|
||||
* @param string|array $whitelist An array or string of whitelisted types
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_whitelisted($types, $whitelist) {
|
||||
return empty($this->get_not_whitelisted($types, $whitelist));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all types that are not part of the give whitelist.
|
||||
*
|
||||
* This is similar check to the {@link self::is_whitelisted()} but this one
|
||||
* actually returns the extra types.
|
||||
*
|
||||
* @param string|array $types File types to be checked
|
||||
* @param string|array $whitelist An array or string of whitelisted types
|
||||
* @return array Types not present in the whitelist
|
||||
*/
|
||||
public function get_not_whitelisted($types, $whitelist) {
|
||||
|
||||
$whitelistedtypes = $this->expand($whitelist, true, true);
|
||||
|
||||
if (empty($whitelistedtypes) || $whitelistedtypes == ['*']) {
|
||||
return true;
|
||||
return [];
|
||||
}
|
||||
|
||||
$giventypes = $this->normalize_file_types($types);
|
||||
|
||||
$intersection = array_intersect($giventypes, $whitelistedtypes);
|
||||
if (empty($giventypes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return !empty($intersection);
|
||||
return array_diff($giventypes, $whitelistedtypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -219,6 +219,7 @@ class filetypes_util_testcase extends advanced_testcase {
|
||||
$this->assertTrue($util->is_whitelisted('audio', 'text/plain audio video'));
|
||||
$this->assertTrue($util->is_whitelisted('text/plain', 'text/plain audio video'));
|
||||
$this->assertTrue($util->is_whitelisted('jpg jpe jpeg', 'image/jpeg'));
|
||||
$this->assertTrue($util->is_whitelisted(['jpg', 'jpe', '.png'], 'image'));
|
||||
|
||||
// These should be intuitively false.
|
||||
$this->assertFalse($util->is_whitelisted('.gif', 'text/plain'));
|
||||
@ -229,9 +230,44 @@ class filetypes_util_testcase extends advanced_testcase {
|
||||
// Not all documents (and also the group itself) is not a plain text.
|
||||
$this->assertFalse($util->is_whitelisted('document', 'text/plain'));
|
||||
|
||||
// This may look wrong at the first sight as you might expect that the
|
||||
// mimetype should simply map to an extension ...
|
||||
$this->assertFalse($util->is_whitelisted('image/jpeg', '.jpg'));
|
||||
|
||||
// But it is principally same situation as this (there is no 1:1 mapping).
|
||||
$this->assertFalse($util->is_whitelisted('.c', '.txt'));
|
||||
$this->assertTrue($util->is_whitelisted('.txt .c', 'text/plain'));
|
||||
$this->assertFalse($util->is_whitelisted('text/plain', '.c'));
|
||||
|
||||
// Any type is included if the filter is empty.
|
||||
$this->assertTrue($util->is_whitelisted('txt', ''));
|
||||
$this->assertTrue($util->is_whitelisted('txt', '*'));
|
||||
|
||||
// Empty value is part of any whitelist.
|
||||
$this->assertTrue($util->is_whitelisted('', '.txt'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test getting types not present in a whitelist.
|
||||
*/
|
||||
public function test_get_not_whitelisted() {
|
||||
|
||||
$this->resetAfterTest(true);
|
||||
$util = new filetypes_util();
|
||||
|
||||
$this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain'));
|
||||
$this->assertEmpty($util->get_not_whitelisted('txt', '.doc .txt .rtf'));
|
||||
$this->assertEmpty($util->get_not_whitelisted('txt', 'text/plain'));
|
||||
$this->assertEmpty($util->get_not_whitelisted(['jpg', 'jpe', 'jpeg'], 'image/jpeg'));
|
||||
$this->assertEmpty($util->get_not_whitelisted('', 'foo/bar'));
|
||||
$this->assertEmpty($util->get_not_whitelisted('.foobar', ''));
|
||||
$this->assertEmpty($util->get_not_whitelisted('.foobar', '*'));
|
||||
|
||||
// Returned list is normalized so extensions have the dot added.
|
||||
$this->assertContains('.exe', $util->get_not_whitelisted('exe', '.c .h'));
|
||||
|
||||
// If this looks wrong to you, see {@link test_is_whitelisted()} for more details on this behaviour.
|
||||
$this->assertContains('image/jpeg', $util->get_not_whitelisted('image/jpeg', '.jpg .jpeg'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,13 @@
|
||||
This files describes API changes in core libraries and APIs,
|
||||
information provided here is intended especially for developers.
|
||||
|
||||
=== 3.4 ===
|
||||
|
||||
* Added new moodleform element 'filetypes' and new admin setting widget 'admin_setting_filetypes'. These new widgets
|
||||
allow users to define a list of file types; either by typing them manually or selecting them from a list. The widgets
|
||||
directly support the syntax used to feed the 'accepted_types' option of the filemanager and filepicker elements. File
|
||||
types can be specified as extensions (.jpg or just jpg), mime types (text/plain) or groups (image).
|
||||
|
||||
=== 3.3.1 ===
|
||||
|
||||
* ldap_get_entries_moodle() now always returns lower-cased attribute names in the returned entries.
|
||||
|
Loading…
x
Reference in New Issue
Block a user