Add storage options form in admin/site page
This commit is contained in:
parent
f7b6fef197
commit
fdc6608af8
6 changed files with 169 additions and 16 deletions
|
@ -19,6 +19,7 @@ use Friendica\Core\System;
|
||||||
use Friendica\Core\Theme;
|
use Friendica\Core\Theme;
|
||||||
use Friendica\Core\Update;
|
use Friendica\Core\Update;
|
||||||
use Friendica\Core\Worker;
|
use Friendica\Core\Worker;
|
||||||
|
use Friendica\Core\StorageManager;
|
||||||
use Friendica\Database\DBA;
|
use Friendica\Database\DBA;
|
||||||
use Friendica\Database\DBStructure;
|
use Friendica\Database\DBStructure;
|
||||||
use Friendica\Model\Contact;
|
use Friendica\Model\Contact;
|
||||||
|
@ -1171,6 +1172,39 @@ function admin_page_site_post(App $a)
|
||||||
$relay_user_tags = !empty($_POST['relay_user_tags']);
|
$relay_user_tags = !empty($_POST['relay_user_tags']);
|
||||||
$active_panel = (!empty($_POST['active_panel']) ? "#" . Strings::escapeTags(trim($_POST['active_panel'])) : '');
|
$active_panel = (!empty($_POST['active_panel']) ? "#" . Strings::escapeTags(trim($_POST['active_panel'])) : '');
|
||||||
|
|
||||||
|
$storagebackend = Strings::escapeTags(trim(defaults($_POST, 'storagebackend', '')));
|
||||||
|
StorageManager::setBackend($storagebackend);
|
||||||
|
|
||||||
|
// save storage backend form
|
||||||
|
$storage_opts = $storagebackend::getOptions();
|
||||||
|
$storage_form_prefix=preg_replace('|[^a-zA-Z0-9]|' ,'', $storagebackend);
|
||||||
|
$storage_opts_data = [];
|
||||||
|
foreach($storage_opts as $name => $info) {
|
||||||
|
$fieldname = $storage_form_prefix . '_' . $name;
|
||||||
|
switch ($info[0]) { // type
|
||||||
|
case 'checkbox':
|
||||||
|
case 'yesno':
|
||||||
|
$value = !empty($_POST[$fieldname]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$value = defaults($_POST, $fieldname, '');
|
||||||
|
}
|
||||||
|
$storage_opts_data[$name] = $value;
|
||||||
|
}
|
||||||
|
unset($name);
|
||||||
|
unset($info);
|
||||||
|
|
||||||
|
$storage_form_errors = $storagebackend::saveOptions($storage_opts_data);
|
||||||
|
if (count($storage_form_errors)) {
|
||||||
|
foreach($storage_form_errors as $name => $err) {
|
||||||
|
notice('Storage backend, ' . $storage_opts[$name][1] . ': ' . $err);
|
||||||
|
}
|
||||||
|
$a->internalRedirect('admin/site' . $active_panel);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Has the directory url changed? If yes, then resubmit the existing profiles there
|
// Has the directory url changed? If yes, then resubmit the existing profiles there
|
||||||
if ($global_directory != Config::get('system', 'directory') && ($global_directory != '')) {
|
if ($global_directory != Config::get('system', 'directory') && ($global_directory != '')) {
|
||||||
Config::set('system', 'directory', $global_directory);
|
Config::set('system', 'directory', $global_directory);
|
||||||
|
@ -1482,6 +1516,31 @@ function admin_page_site(App $a)
|
||||||
$optimize_max_tablesize = -1;
|
$optimize_max_tablesize = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* storage backend */
|
||||||
|
$storage_backends = StorageManager::listBackends();
|
||||||
|
$storage_current_backend = StorageManager::getBackend();
|
||||||
|
|
||||||
|
$storage_backends_choices = [
|
||||||
|
'' => L10n::t('None')
|
||||||
|
];
|
||||||
|
foreach($storage_backends as $name=>$class) {
|
||||||
|
$storage_backends_choices[$class] = $name;
|
||||||
|
}
|
||||||
|
unset($storage_backends);
|
||||||
|
|
||||||
|
// build storage config form,
|
||||||
|
$storage_form_prefix=preg_replace('|[^a-zA-Z0-9]|' ,'', $storage_current_backend);
|
||||||
|
|
||||||
|
$storage_form = [];
|
||||||
|
foreach($storage_current_backend::getOptions() as $name => $info) {
|
||||||
|
$type = $info[0];
|
||||||
|
$info[0] = $storage_form_prefix . '_' . $name;
|
||||||
|
$info['type'] = $type;
|
||||||
|
$info['field'] = 'field_' . $type . '.tpl';
|
||||||
|
$storage_form[$name] = $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$t = Renderer::getMarkupTemplate('admin/site.tpl');
|
$t = Renderer::getMarkupTemplate('admin/site.tpl');
|
||||||
return Renderer::replaceMacros($t, [
|
return Renderer::replaceMacros($t, [
|
||||||
'$title' => L10n::t('Administration'),
|
'$title' => L10n::t('Administration'),
|
||||||
|
@ -1515,6 +1574,9 @@ function admin_page_site(App $a)
|
||||||
'$force_ssl' => ['force_ssl', L10n::t("Force SSL"), Config::get('system', 'force_ssl'), L10n::t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")],
|
'$force_ssl' => ['force_ssl', L10n::t("Force SSL"), Config::get('system', 'force_ssl'), L10n::t("Force all Non-SSL requests to SSL - Attention: on some systems it could lead to endless loops.")],
|
||||||
'$hide_help' => ['hide_help', L10n::t("Hide help entry from navigation menu"), Config::get('system', 'hide_help'), L10n::t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")],
|
'$hide_help' => ['hide_help', L10n::t("Hide help entry from navigation menu"), Config::get('system', 'hide_help'), L10n::t("Hides the menu entry for the Help pages from the navigation menu. You can still access it calling /help directly.")],
|
||||||
'$singleuser' => ['singleuser', L10n::t("Single user instance"), Config::get('system', 'singleuser', '---'), L10n::t("Make this instance multi-user or single-user for the named user"), $user_names],
|
'$singleuser' => ['singleuser', L10n::t("Single user instance"), Config::get('system', 'singleuser', '---'), L10n::t("Make this instance multi-user or single-user for the named user"), $user_names],
|
||||||
|
|
||||||
|
'$storagebackend' => ['storagebackend', L10n::t("File storage backend"), $storage_current_backend, L10n::t('Backend used to store uploaded files data'), $storage_backends_choices],
|
||||||
|
'$storageform' => $storage_form,
|
||||||
'$maximagesize' => ['maximagesize', L10n::t("Maximum image size"), Config::get('system', 'maximagesize'), L10n::t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")],
|
'$maximagesize' => ['maximagesize', L10n::t("Maximum image size"), Config::get('system', 'maximagesize'), L10n::t("Maximum size in bytes of uploaded images. Default is 0, which means no limits.")],
|
||||||
'$maximagelength' => ['maximagelength', L10n::t("Maximum image length"), Config::get('system', 'max_image_length'), L10n::t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")],
|
'$maximagelength' => ['maximagelength', L10n::t("Maximum image length"), Config::get('system', 'max_image_length'), L10n::t("Maximum length in pixels of the longest side of uploaded images. Default is -1, which means no limits.")],
|
||||||
'$jpegimagequality' => ['jpegimagequality', L10n::t("JPEG image quality"), Config::get('system', 'jpeg_quality'), L10n::t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")],
|
'$jpegimagequality' => ['jpegimagequality', L10n::t("JPEG image quality"), Config::get('system', 'jpeg_quality'), L10n::t("Uploaded JPEGS will be saved at this quality setting [0-100]. Default is 100, which is full quality.")],
|
||||||
|
|
|
@ -51,4 +51,8 @@ class Database implements IStorage
|
||||||
{
|
{
|
||||||
return DBA::delete('storage', ['id' => $ref]);
|
return DBA::delete('storage', ['id' => $ref]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getOptions() { return []; }
|
||||||
|
|
||||||
|
public static function saveOptions($data) { return []; }
|
||||||
}
|
}
|
|
@ -24,11 +24,11 @@ use Friendica\Util\Strings;
|
||||||
class Filesystem implements IStorage
|
class Filesystem implements IStorage
|
||||||
{
|
{
|
||||||
// Default base folder
|
// Default base folder
|
||||||
const DEFAULT_BASE_FOLDER = "storage";
|
const DEFAULT_BASE_FOLDER = 'storage';
|
||||||
|
|
||||||
private static function getBasePath()
|
private static function getBasePath()
|
||||||
{
|
{
|
||||||
return Config::get("storage", "filesystem_path", self::DEFAULT_BASE_FOLDER);
|
return Config::get('storage', 'filesystem_path', self::DEFAULT_BASE_FOLDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,7 +43,7 @@ class Filesystem implements IStorage
|
||||||
$fold2 = substr($ref, 2, 2);
|
$fold2 = substr($ref, 2, 2);
|
||||||
$file = substr($ref, 4);
|
$file = substr($ref, 4);
|
||||||
|
|
||||||
return "{$base}/{$fold1}/{$fold2}/{$file}";
|
return implode('/', [$base, $fold1, $fold2, $file]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,8 +57,8 @@ class Filesystem implements IStorage
|
||||||
|
|
||||||
if (!is_dir($path)) {
|
if (!is_dir($path)) {
|
||||||
if (!mkdir($path, 0770, true)) {
|
if (!mkdir($path, 0770, true)) {
|
||||||
Logger::log("Failed to create dirs {$path}");
|
Logger::log('Failed to create dirs ' . $path);
|
||||||
throw new StorageException(L10n::t("Filesystem storage failed to create '%s'. Check you write permissions.", $path));
|
throw new StorageException(L10n::t('Filesystem storage failed to create "%s". Check you write permissions.', $path));
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,13 @@ class Filesystem implements IStorage
|
||||||
$base = self::getBasePath();
|
$base = self::getBasePath();
|
||||||
|
|
||||||
while ($path !== $base) {
|
while ($path !== $base) {
|
||||||
if (!is_file($path . "/index.html")) {
|
if (!is_file($path . '/index.html')) {
|
||||||
file_put_contents($path . "/index.html", "");
|
file_put_contents($path . '/index.html', '');
|
||||||
}
|
}
|
||||||
$path = dirname($path);
|
$path = dirname($path);
|
||||||
}
|
}
|
||||||
if (!is_file($path . "/index.html")) {
|
if (!is_file($path . '/index.html')) {
|
||||||
file_put_contents($path . "/index.html", "");
|
file_put_contents($path . '/index.html', '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,15 +80,15 @@ class Filesystem implements IStorage
|
||||||
{
|
{
|
||||||
$file = self::pathForRef($ref);
|
$file = self::pathForRef($ref);
|
||||||
if (!is_file($file)) {
|
if (!is_file($file)) {
|
||||||
return "";
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
return file_get_contents($file);
|
return file_get_contents($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function put($data, $ref = "")
|
public static function put($data, $ref = '')
|
||||||
{
|
{
|
||||||
if ($ref === "") {
|
if ($ref === '') {
|
||||||
$ref = Strings::getRandomHex();
|
$ref = Strings::getRandomHex();
|
||||||
}
|
}
|
||||||
$file = self::pathForRef($ref);
|
$file = self::pathForRef($ref);
|
||||||
|
@ -97,8 +97,8 @@ class Filesystem implements IStorage
|
||||||
|
|
||||||
$r = file_put_contents($file, $data);
|
$r = file_put_contents($file, $data);
|
||||||
if ($r === FALSE) {
|
if ($r === FALSE) {
|
||||||
Logger::log("Failed to write data to {$file}");
|
Logger::log('Failed to write data to ' . $file);
|
||||||
throw new StorageException(L10n::t("Filesystem storage failed to save data to '%s'. Check your write permissions", $file));
|
throw new StorageException(L10n::t('Filesystem storage failed to save data to "%s". Check your write permissions', $file));
|
||||||
killme();
|
killme();
|
||||||
}
|
}
|
||||||
return $ref;
|
return $ref;
|
||||||
|
@ -114,4 +114,28 @@ class Filesystem implements IStorage
|
||||||
return unlink($file);
|
return unlink($file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getOptions()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'storagepath' => [
|
||||||
|
'input',
|
||||||
|
L10n::t('Storage base path'),
|
||||||
|
self::getBasePath(),
|
||||||
|
L10n::t('Folder were uploaded files are saved. For maximum security, This should be a path outside web server folder tree')
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function saveOptions($data)
|
||||||
|
{
|
||||||
|
$storagepath = defaults($data, 'storagepath', '');
|
||||||
|
if ($storagepath === '' || !is_dir($storagepath)) {
|
||||||
|
return [
|
||||||
|
'storagepath' => L10n::t('Enter a valid existing folder')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
Config::set('storage', 'filesystem_path', $storagepath);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,4 +32,58 @@ interface IStorage
|
||||||
* @return boolean True on success
|
* @return boolean True on success
|
||||||
*/
|
*/
|
||||||
public static function delete($ref);
|
public static function delete($ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get info about storage options
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* This method return an array with informations about storage options
|
||||||
|
* from which the form presented to the user is build.
|
||||||
|
*
|
||||||
|
* The returned array is:
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* 'option1name' => [ ..info.. ],
|
||||||
|
* 'option2name' => [ ..info.. ],
|
||||||
|
* ...
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* An empty array can be returned if backend doesn't have any options
|
||||||
|
*
|
||||||
|
* The info array for each option MUST be as follows:
|
||||||
|
*
|
||||||
|
* [
|
||||||
|
* 'type', // define the field used in form, and the type of data.
|
||||||
|
* // one of 'checkbox', 'combobox', 'custom', 'datetime',
|
||||||
|
* // 'input', 'intcheckbox', 'password', 'radio', 'richtext'
|
||||||
|
* // 'select', 'select_raw', 'textarea', 'yesno'
|
||||||
|
*
|
||||||
|
* 'label', // Translatable label of the field
|
||||||
|
* 'value', // Current value
|
||||||
|
* 'help text', // Translatable description for the field
|
||||||
|
* extra data // Optional. Depends on 'type':
|
||||||
|
* // select: array [ value => label ] of choices
|
||||||
|
* // intcheckbox: value of input element
|
||||||
|
* // select_raw: prebuild html string of < option > tags
|
||||||
|
* // yesno: array [ 'label no', 'label yes']
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* See https://github.com/friendica/friendica/wiki/Quick-Template-Guide
|
||||||
|
*/
|
||||||
|
public static function getOptions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate and save options
|
||||||
|
*
|
||||||
|
* @param array $data Array [optionname => value] to be saved
|
||||||
|
*
|
||||||
|
* @return array Validation errors: [optionname => error message]
|
||||||
|
*
|
||||||
|
* Return array must be empty if no error.
|
||||||
|
*/
|
||||||
|
public static function saveOptions($data);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,11 @@
|
||||||
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
|
<div class="submit"><input type="submit" name="page_site" value="{{$submit}}" /></div>
|
||||||
|
|
||||||
<h3>{{$upload}}</h3>
|
<h3>{{$upload}}</h3>
|
||||||
|
{{include file="field_select.tpl" field=$storagebackend}}
|
||||||
|
{{foreach from=$storageform item=$field}}
|
||||||
|
{{include file=$field.field field=$field}}
|
||||||
|
{{/foreach}}
|
||||||
|
<hr>
|
||||||
{{include file="field_input.tpl" field=$maximagesize}}
|
{{include file="field_input.tpl" field=$maximagesize}}
|
||||||
{{include file="field_input.tpl" field=$maximagelength}}
|
{{include file="field_input.tpl" field=$maximagelength}}
|
||||||
{{include file="field_input.tpl" field=$jpegimagequality}}
|
{{include file="field_input.tpl" field=$jpegimagequality}}
|
||||||
|
|
|
@ -135,7 +135,11 @@
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div id="admin-settings-upload-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-upload">
|
<div id="admin-settings-upload-collapse" class="panel-collapse collapse" role="tabpanel" aria-labelledby="admin-settings-upload">
|
||||||
|
{{include file="field_select.tpl" field=$storagebackend}}
|
||||||
|
{{foreach from=$storageform item=$field}}
|
||||||
|
{{include file=$field.field field=$field}}
|
||||||
|
{{/foreach}}
|
||||||
|
<hr>
|
||||||
{{include file="field_input.tpl" field=$maximagesize}}
|
{{include file="field_input.tpl" field=$maximagesize}}
|
||||||
{{include file="field_input.tpl" field=$maximagelength}}
|
{{include file="field_input.tpl" field=$maximagelength}}
|
||||||
{{include file="field_input.tpl" field=$jpegimagequality}}
|
{{include file="field_input.tpl" field=$jpegimagequality}}
|
||||||
|
|
Loading…
Reference in a new issue