Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

311 multi files #37

Open
wants to merge 2 commits into
base: MOODLE_311_STABLE
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/admin_presets_base.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ protected function _get_settings($dbsettings, $sitedbvalues = false, $settings,
}
}
}

return $settings;
}

Expand Down
4 changes: 2 additions & 2 deletions lib/admin_presets_export.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public function download_xml() {

$tagname = strtoupper($plugin);

// To aviod xml slash problems.
// To avoid xml slash problems.
if (strstr($tagname, '/') != false) {
$tagname = str_replace('/', '__', $tagname);
}
Expand All @@ -209,7 +209,7 @@ public function download_xml() {
}
}

$xmlwriter->full_tag(strtoupper($setting->name), $setting->value, $attributes);
$xmlwriter->full_tag(strtoupper(trim($setting->name)), trim($setting->value), $attributes);
}

$xmlwriter->end_tag('SETTINGS');
Expand Down
4 changes: 3 additions & 1 deletion lib/admin_presets_load.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public function execute() {
// Only for selected items.
$appliedchanges = array();
$unnecessarychanges = array();
foreach (filter_input_array(INPUT_POST) as $varname => $value) {
foreach ($_POST as $varname => $value) {

unset($updatesetting);

Expand Down Expand Up @@ -148,6 +148,8 @@ public function execute() {
$appliedchanges[$varname]->oldvisiblevalue = $sitesetting->get_visiblevalue();
$appliedchanges[$varname]->visiblevalue = $presetsetting->get_visiblevalue();

purge_caches();

// Unnecessary changes (actual setting value).
} else {
$unnecessarychanges[$varname] = $presetsetting;
Expand Down
264 changes: 264 additions & 0 deletions lib/admin_presets_settings_types.php
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,270 @@ protected function set_visiblevalue() {
}
}

class admin_preset_admin_setting_configstoredfile extends admin_preset_setting {

private $base64;
private $extensions = [];
private $filenames = [];
private $separator = '_separator_';
private $multiseparator = '_multis_';

public function __construct(admin_setting $settingdata, $dbsettingvalue) {

// Check if preview context (multiseparator present or pathinfo extension not set)
$pathinfo = pathinfo($dbsettingvalue);
if (!isset($pathinfo['extension']) || strpos($dbsettingvalue, $this->multiseparator) !== false) {
// Manage multiple files
$multisplits = explode($this->multiseparator, $dbsettingvalue);
foreach ($multisplits as $multisplit) {
$split = explode($this->separator, $multisplit);
if (!empty($split[2])) {
$this->filenames[$split[2]] = $split[2];
$this->extensions[$split[2]] = $split[1];
if (base64_encode(base64_decode($split[0], true)) === $split[0]) {
$this->base64 .= $split[0] . $this->separator . $split[1] . $this->separator . $split[2] . $this->multiseparator; // We store the base64 with his extension and filename.
}
}
}
} else {
$this->base64 = $this->get_current_files($settingdata->plugin, $settingdata->name);
}

parent::__construct($settingdata, $dbsettingvalue);

}

/**
* Defines the value as equal to the base64 of the image followed by its extension
* (to be able to retrieve the extension more easily)
*
* @param string $value
* @return boolean Cleaned or not, but always true
*/
protected function set_value($value) {
if ($this->base64) {
$this->value = $this->base64;
} else {
$this->value = $value;
}
return true;
}

/**
* Defines the visible value as an html image built from the base64 of the image
* (Because it is stored as a base64 in the xml and in the database)
*/
protected function set_visiblevalue() {
$this->visiblevalue = '';

if ($this->base64) {
$multisplits = explode($this->multiseparator, $this->base64);
foreach ($multisplits as $multisplit) {
if (!empty($multisplit)) {
$split = explode($this->separator, $multisplit);
if ($this->checkImageExtension($this->extensions[$split[2]])) {
// Remove the extension.
$base64 = str_replace($this->separator . $this->extensions[$split[2]], '', $split[0]);
$base64 = str_replace($this->separator . $this->filenames[$split[2]], '', $base64);
// Render a preview of the image instead of the base64 value.
$this->visiblevalue .= '<img style="display:block; width:200px" src="data:' .
$this->extensions[$split[2]] . ';base64, ' . $base64 . '" />';
} else {
$this->visiblevalue .= '<span style="display:block; width: 250px; overflow: hidden; text-overflow: ellipsis;"><b>' .
$this->filenames[$split[2]] . '</b> ' . substr(base64_decode($split[0]), 0, 250) . '...</span>';
}
}
}
}
}

/**
* Stores the setting into database, logs the change and returns the config_log inserted id
*
* @param bool $name
* @param mixed $value
* @return integer config_log inserted id
* @throws dml_exception
* @throws moodle_exception
*/
public function save_value($name = false, $value = null) {

// Object values if no arguments.
if ($value === null) {
$value = $this->value;
}
if (!$name) {
$name = $this->settingdata->name;
}

// Plugin name or null.
$plugin = $this->settingdata->plugin;
if ($plugin == 'none' || $plugin == '') {
$plugin = null;
}

// Manage multiple files
$i = 0;
$filename = '';
$configlogid = '';
$fs = get_file_storage();
$multisplits = explode($this->multiseparator, $value);
foreach ($multisplits as $multisplit) {
$split = explode($this->separator, $multisplit);
// Manage filename for config
if ($i == 0) {
$filename = $split[2];
}
$i++;
if (!empty($split[2])) {
$currentfile = $this->get_file_from_fs($plugin, $name, $split[2]);
if ($currentfile) {
$oldvalue = base64_encode($currentfile->get_content());
// skip same value
if ($oldvalue == $split[0]) {
continue;
}
// Delete the old file.
$currentfile->delete();
}
// Prepare new file record object.
$fileinfo = [
'contextid' => 1,
'component' => $plugin,
'filearea' => $this->fileareaMapping($plugin, $name),
'itemid' => 0,
'filepath' => '/',
'filename' => $split[2]
];
$fs->create_file_from_string($fileinfo, base64_decode($split[0]));
}
}
// update config & log
if ($filename) {
unset_config($name, $plugin);
set_config($name, '/' . $filename, $plugin);
$configlogid = $this->to_log($plugin, $name, $filename, get_config($plugin, $name) ?? '');
}

return $configlogid;
}

/**
* Get the file actually stored in the configuration
*
* @param $plugin
* @param $name
* @return mixed
* @throws dml_exception
*/
private function get_current_files($plugin, $name) {
global $DB;

$content = '';
$datas = [
'component' => $plugin,
'filearea' => $this->fileareaMapping($plugin, $name),
'itemid' => 0,
'contextid' => 1,
];
// Retrieve the file. So we can convert it to base64 (to add it in the xml or compare with new value in "load" context).
$dbfiles = $DB->get_records_sql(
'SELECT * FROM {files}
WHERE component = :component
AND filearea = :filearea
AND itemid = :itemid
AND contextid = :contextid
',
$datas
);

if ($dbfiles) {
$fs = get_file_storage();
foreach ($dbfiles as $dbfile) {
$pathinfo = pathinfo($dbfile->filename);
if (!empty($pathinfo['extension']) && !empty($pathinfo['basename'])) {
$this->filenames[$pathinfo['basename']] = $pathinfo['basename'];
$this->extensions[$pathinfo['basename']] = $pathinfo['extension'];
$content .= base64_encode($fs->get_file_by_hash($dbfile->pathnamehash)->get_content()) . $this->separator . $pathinfo['extension'] . $this->separator . $pathinfo['basename'] . $this->multiseparator;
}
}
}
return $content;
}

/**
* @param $plugin
* @param $name
* @param $filename
* @return bool|stored_file|null
* @throws dml_exception
*/
private function get_file_from_fs($plugin, $name, $filename) {
global $DB;

$datas = [
'component' => $plugin,
'filearea' => $this->fileareaMapping($plugin, $name),
'itemid' => 0,
'contextid' => 1,
];
if ($filename) {
$wherefilename = 'filename = "' . $filename . '"';
} else {
// Must be set.
$wherefilename = 'filename NOT IN ("", ".")';
}
// Retrieve the file. So we can convert it to base64 (to add it in the xml or compare with new value in "load" context).
$dbfile = $DB->get_record_sql(
'SELECT * FROM {files}
WHERE component = :component
AND filearea = :filearea
AND itemid = :itemid
AND contextid = :contextid
AND ' . $wherefilename,
$datas
);
if ($dbfile) {
$fs = get_file_storage();
return $fs->get_file_by_hash($dbfile->pathnamehash);
}
return null;
}

/**
* @param $extension
* @return bool
*/
private function checkImageExtension($extension)
{
$img = ['gif' , 'jpeg' , 'jpg' , 'jif' , 'jfif' , 'png' , 'bmp', 'svg', 'tiff'];

if (in_array($extension, $img)) {
return true;
}
return false;
}

/**
* Because some plugins (like Theme fordson use another filearea name than param name for associated files
*
* @param $plugin
* @param $name
* @return string
*/
private function fileareaMapping($plugin, $name)
{
$filearea = $name;
if ($plugin == 'theme_fordson') {
if ($name == 'presetfiles') {
$filearea = 'preset';
}
}
return $filearea;
}

}

class admin_preset_admin_setting_configcheckbox_with_advanced extends admin_preset_admin_setting_configcheckbox {

public function __construct(admin_setting $settingdata, $dbsettingvalue) {
Expand Down
2 changes: 1 addition & 1 deletion version.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

defined('MOODLE_INTERNAL') || die();

$plugin->version = 2021052700;
$plugin->version = 2021052701;
$plugin->requires = 2016052300; // Requires this Moodle version
$plugin->component = 'block_admin_presets';
$plugin->release = '3.4';
Expand Down