mirror of
https://github.com/processwire/processwire.git
synced 2025-08-09 08:17:12 +02:00
Upgrade ProcessWire installer (and related site profile files) to support specification of debug mode as one of the interactive installation options. Also updated some wording in various parts of the installer.
This commit is contained in:
102
install.php
102
install.php
@@ -15,7 +15,6 @@
|
|||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
* @todo have installer set session name
|
* @todo have installer set session name
|
||||||
* @todo have installer support enabling debug mode if user chooses it
|
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -543,11 +542,35 @@ class Installer {
|
|||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
$this->sectionStart('fa-server HTTP Host Names');
|
$this->sectionStart('fa-server HTTP Host Names');
|
||||||
$this->p("What host names will this installation run on now and in the future? Please enter one host per line. You may also choose to leave this blank to auto-detect on each request, but we recommend using this whitelist for the best security in production environments.");
|
$this->p(
|
||||||
$this->p("This field is recommended but not required. You can set this later by editing the file <u>/site/config.php</u> (setting \$config->httpHosts).", "detail");
|
"What host names will this installation run on now and in the future? Please enter one host per line. " .
|
||||||
|
"You can also modify this setting later by editing the <code>\$config->httpHosts</code> setting in the <u>/site/config.php</u> file."
|
||||||
|
);
|
||||||
$rows = substr_count($values['httpHosts'], "\n") + 2;
|
$rows = substr_count($values['httpHosts'], "\n") + 2;
|
||||||
$this->textarea('httpHosts', '', $values['httpHosts'], $rows);
|
$this->textarea('httpHosts', '', $values['httpHosts'], $rows);
|
||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
|
$this->sectionStart('fa-bug Debug mode?');
|
||||||
|
$this->p(
|
||||||
|
"When debug mode is enabled, errors and exceptions are visible in ProcessWire’s output. This is helpful when developing a website or testing ProcessWire. " .
|
||||||
|
"When debug mode is NOT enabled, fatal errors/exceptions halt the request with an ambiguous http 500 error, and non-fatal errors are not shown. " .
|
||||||
|
"Regardless of debug mode, fatal errors are always logged and always visible to superusers. " .
|
||||||
|
"Debug mode should not be enabled for live or production sites, but at this stage (installation) it is worthwhile to have it enabled. "
|
||||||
|
);
|
||||||
|
$noChecked = empty($values['debugMode']) ? "checked='checked'" : "";
|
||||||
|
$yesChecked = empty($noChecked) ? "checked='checked'" : "";
|
||||||
|
$this->p(
|
||||||
|
"<label><input type='radio' name='debugMode' $yesChecked value='1'> <strong>Enabled</strong> " .
|
||||||
|
"<span class='uk-text-small uk-text-muted'>(recommended while sites are in development or while testing ProcessWire)</span></label><br />" .
|
||||||
|
"<label><input type='radio' name='debugMode' $noChecked value='0'> <strong>Disabled</strong> " .
|
||||||
|
"<span class='uk-text-small uk-text-muted'>(recommended once a site goes live or becomes publicly accessible)</span></label> "
|
||||||
|
);
|
||||||
|
$this->p(
|
||||||
|
"You can also enable or disable debug mode at any time by editing the <u>/site/config.php</u> file and setting " .
|
||||||
|
"<code>\$config->debug = true;</code> or <code>\$config->debug = false;</code>"
|
||||||
|
);
|
||||||
|
$this->sectionStop();
|
||||||
|
|
||||||
$this->btn("Continue", 4);
|
$this->btn("Continue", 4);
|
||||||
$this->p("Note: After you click the button above, be patient … it may take a minute.", "detail");
|
$this->p("Note: After you click the button above, be patient … it may take a minute.", "detail");
|
||||||
}
|
}
|
||||||
@@ -570,6 +593,7 @@ class Installer {
|
|||||||
$values[$field] = $value;
|
$values[$field] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timezone
|
||||||
$timezone = (int) $_POST['timezone'];
|
$timezone = (int) $_POST['timezone'];
|
||||||
$timezones = $this->timezones();
|
$timezones = $this->timezones();
|
||||||
if(isset($timezones[$timezone])) {
|
if(isset($timezones[$timezone])) {
|
||||||
@@ -583,6 +607,7 @@ class Installer {
|
|||||||
$values['timezone'] = 'America/New_York';
|
$values['timezone'] = 'America/New_York';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http hosts
|
||||||
$values['httpHosts'] = array();
|
$values['httpHosts'] = array();
|
||||||
$httpHosts = trim($_POST['httpHosts']);
|
$httpHosts = trim($_POST['httpHosts']);
|
||||||
if(strlen($httpHosts)) {
|
if(strlen($httpHosts)) {
|
||||||
@@ -595,6 +620,9 @@ class Installer {
|
|||||||
$values['httpHosts'] = $httpHosts;
|
$values['httpHosts'] = $httpHosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// debug mode
|
||||||
|
$values['debugMode'] = (int) $_POST['debugMode'];
|
||||||
|
|
||||||
// db configuration
|
// db configuration
|
||||||
$fields = array('dbUser', 'dbName', 'dbPass', 'dbHost', 'dbPort', 'dbEngine', 'dbCharset');
|
$fields = array('dbUser', 'dbName', 'dbPass', 'dbHost', 'dbPort', 'dbEngine', 'dbCharset');
|
||||||
|
|
||||||
@@ -822,6 +850,18 @@ class Installer {
|
|||||||
$cfg = rtrim($cfg, ", ") . ");\n\n";
|
$cfg = rtrim($cfg, ", ") . ");\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cfg .=
|
||||||
|
"\n/**" .
|
||||||
|
"\n * Installer: Debug mode?" .
|
||||||
|
"\n * " .
|
||||||
|
"\n * When debug mode is true, errors and exceptions are visible. " .
|
||||||
|
"\n * When false, they are not visible except to superuser and in logs. " .
|
||||||
|
"\n * Should be true for development sites and false for live/production sites. " .
|
||||||
|
"\n * " .
|
||||||
|
"\n */" .
|
||||||
|
"\n\$config->debug = " . ($values['debugMode'] ? 'true;' : 'false;') .
|
||||||
|
"\n\n";
|
||||||
|
|
||||||
if(($fp = fopen("./site/config.php", "a")) && fwrite($fp, $cfg)) {
|
if(($fp = fopen("./site/config.php", "a")) && fwrite($fp, $cfg)) {
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
$this->alertOk("Saved configuration to ./site/config.php");
|
$this->alertOk("Saved configuration to ./site/config.php");
|
||||||
@@ -1052,7 +1092,7 @@ class Installer {
|
|||||||
|
|
||||||
$this->sectionStart("fa-bath Cleanup");
|
$this->sectionStart("fa-bath Cleanup");
|
||||||
$this->p("Directories and files listed below are no longer needed and should be removed. If you choose to leave any of them in place, you should delete them before migrating to a production environment.", "detail");
|
$this->p("Directories and files listed below are no longer needed and should be removed. If you choose to leave any of them in place, you should delete them before migrating to a production environment.", "detail");
|
||||||
$this->p($this->getRemoveableItems($wire, true));
|
$this->p($this->getRemoveableItems(true));
|
||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
$this->btn("Continue", 5);
|
$this->btn("Continue", 5);
|
||||||
@@ -1061,17 +1101,16 @@ class Installer {
|
|||||||
/**
|
/**
|
||||||
* Get post-install optionally removable items
|
* Get post-install optionally removable items
|
||||||
*
|
*
|
||||||
* @param ProcessWire $wire
|
|
||||||
* @param bool $getMarkup Get markup of options/form inputs rather than array of items?
|
* @param bool $getMarkup Get markup of options/form inputs rather than array of items?
|
||||||
* @param bool $removeNow Allow processing of submitted form (via getMarkup) to remove items now?
|
* @param bool $removeNow Allow processing of submitted form (via getMarkup) to remove items now?
|
||||||
* @return array|string
|
* @return array|string
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function getRemoveableItems($wire, $getMarkup = false, $removeNow = false) {
|
protected function getRemoveableItems($getMarkup = false, $removeNow = false) {
|
||||||
|
|
||||||
$root = dirname(__FILE__) . '/';
|
$root = dirname(__FILE__) . '/';
|
||||||
$isPost = $wire->input->post('remove_items') !== null;
|
$isPost = isset($_POST['remove_items']);
|
||||||
$postItems = $isPost ? $wire->input->post('remove_items') : array();
|
$postItems = $isPost ? $_POST['remove_items'] : array();
|
||||||
if(!is_array($postItems)) $postItems = array();
|
if(!is_array($postItems)) $postItems = array();
|
||||||
$out = '';
|
$out = '';
|
||||||
|
|
||||||
@@ -1124,7 +1163,7 @@ class Installer {
|
|||||||
$success = true;
|
$success = true;
|
||||||
}
|
}
|
||||||
if($success) {
|
if($success) {
|
||||||
$this->ok("Completed: " . $item['label']);
|
// $this->ok("Completed: " . $item['label']);
|
||||||
} else {
|
} else {
|
||||||
$this->err("Unable to remove $item[file] - please remove manually, as it is no longer needed");
|
$this->err("Unable to remove $item[file] - please remove manually, as it is no longer needed");
|
||||||
}
|
}
|
||||||
@@ -1136,7 +1175,9 @@ class Installer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(empty($out)) $out = "None found";
|
||||||
if($getMarkup) return $out;
|
if($getMarkup) return $out;
|
||||||
|
|
||||||
return $items;
|
return $items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1226,22 +1267,36 @@ class Installer {
|
|||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
$this->sectionStart("fa-life-buoy Complete & Secure Your Installation");
|
$this->sectionStart("fa-life-buoy Complete & Secure Your Installation");
|
||||||
$this->getRemoveableItems($wire, false, true);
|
$this->getRemoveableItems(false, true);
|
||||||
|
|
||||||
$this->ok("Note that future runtime errors are logged to <b>/site/assets/logs/errors.txt</b> (not web accessible).");
|
$this->ok("Note that future runtime errors are logged to <b>/site/assets/logs/errors.txt</b> (not web accessible).");
|
||||||
$this->ok("For more configuration options see <b>/wire/config.php</b> and place any edits in /site/config.php.");
|
$this->ok("For more configuration options see <b>/wire/config.php</b> and place any edits in <u>/site/config.php</u>.");
|
||||||
|
$this->ok("Consider making your <b>/site/config.php</b> file non-writable, and readable only to you and Apache.");
|
||||||
|
$this->ok("View and edit your <b>.htaccess</b> file to force HTTPS, setup redirects, and more.");
|
||||||
|
|
||||||
$this->p(
|
$this->p(
|
||||||
"Please make your <b>/site/config.php</b> file non-writable, and readable only to you and Apache.<br />" .
|
"<a target='_blank' href='https://processwire.com/docs/security/'>" .
|
||||||
"<a target='_blank' href='https://processwire.com/docs/security/file-permissions/#securing-your-site-config.php-file'>" .
|
"Lean more about securing your ProcessWire installation <i class='fa fa-angle-right'></i></a>"
|
||||||
"How to secure your /site/config.php file <i class='fa fa-angle-right'></i></a>"
|
|
||||||
);
|
);
|
||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
if(is_writable("./site/modules/")) wireChmod("./site/modules/", true);
|
if(is_writable("./site/modules/")) wireChmod("./site/modules/", true);
|
||||||
|
|
||||||
$this->sectionStart("fa-coffee Use The Site!");
|
$this->sectionStart("fa-coffee Get Started!");
|
||||||
$this->ok("Your admin URL is <a href='./$adminName/'>/$adminName/</a>");
|
$this->ok(
|
||||||
$this->p("If you'd like, you may change this later by editing the admin page and changing the name.", "detail");
|
"Your admin URL is <a target='_blank' href='./$adminName/'>/$adminName/</a>"
|
||||||
|
);
|
||||||
|
$this->ok(
|
||||||
|
"Learn more about ProcessWire in the <a target='_blank' href='https://processwire.com/docs/'>documentation</a> " .
|
||||||
|
"and <a target='_blank' href='https://processwire.com/api/ref/'>API reference</a>. "
|
||||||
|
);
|
||||||
|
$this->ok(
|
||||||
|
"Visit our <a target='_blank' href='https://processwire.com/talk/'>support forums</a> for friendly help and discussion."
|
||||||
|
);
|
||||||
|
$this->ok(
|
||||||
|
"<a target='_blank' href='https://processwire.com/community/newsletter/subscribe/'>Subscribe to keep up-to-date</a> " .
|
||||||
|
"with new versions and important updates."
|
||||||
|
);
|
||||||
$this->sectionStop();
|
$this->sectionStop();
|
||||||
|
|
||||||
$this->btn("Login to Admin", 1, 'sign-in', false, true, "./$adminName/");
|
$this->btn("Login to Admin", 1, 'sign-in', false, true, "./$adminName/");
|
||||||
@@ -1261,13 +1316,14 @@ class Installer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $str
|
* @param string $str
|
||||||
|
* @param string $icon
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function alertOk($str) {
|
protected function alertOk($str, $icon = 'check') {
|
||||||
if($this->inSection) {
|
if($this->inSection) {
|
||||||
$this->ok($str);
|
$this->ok($str);
|
||||||
} else {
|
} else {
|
||||||
echo "\n<div class='uk-alert uk-alert-primary'><i class='fa fa-fw fa-check'></i> $str</div>";
|
echo "\n<div class='uk-alert uk-alert-primary'><i class='fa fa-fw fa-$icon'></i> $str</div>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1337,15 +1393,15 @@ class Installer {
|
|||||||
* Report success
|
* Report success
|
||||||
*
|
*
|
||||||
* @param string $str
|
* @param string $str
|
||||||
|
* @param string $icon
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
protected function ok($str) {
|
protected function ok($str, $icon = 'check') {
|
||||||
if(!$this->inSection) {
|
if(!$this->inSection) {
|
||||||
$this->alertOk($str);
|
$this->alertOk($str);
|
||||||
} else {
|
} else {
|
||||||
//echo "\n<li class='ui-state-highlight'><i class='fa fa-check-square-o'></i> $str</li>";
|
echo "\n<div class=''><i class='fa fa-fw fa-$icon'></i> $str</div>";
|
||||||
echo "\n<div class=''><i class='fa fa-fw fa-check'></i> $str</div>";
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1366,7 +1422,7 @@ class Installer {
|
|||||||
if($float) $class .= " uk-float-left";
|
if($float) $class .= " uk-float-left";
|
||||||
$type = 'submit';
|
$type = 'submit';
|
||||||
if($href) $type = 'button';
|
if($href) $type = 'button';
|
||||||
if($href) echo "<a href='$href'>";
|
if($href) echo "<a href='$href' target='_blank'>";
|
||||||
echo "\n<p><button name='step' type='$type' class='ui-button ui-widget ui-state-default $class ui-corner-all' value='$value'>";
|
echo "\n<p><button name='step' type='$type' class='ui-button ui-widget ui-state-default $class ui-corner-all' value='$value'>";
|
||||||
echo "<span class='ui-button-text'><i class='fa fa-$icon'></i> $label</span>";
|
echo "<span class='ui-button-text'><i class='fa fa-$icon'></i> $label</span>";
|
||||||
echo "</button></p>";
|
echo "</button></p>";
|
||||||
|
@@ -28,18 +28,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/** @var Config $config */
|
/** @var Config $config */
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepend template file
|
* Prepend template file
|
||||||
*
|
*
|
||||||
|
@@ -28,18 +28,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/** @var Config $config */
|
/** @var Config $config */
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow core API variables to also be accessed as functions?
|
* Allow core API variables to also be accessed as functions?
|
||||||
*
|
*
|
||||||
|
@@ -28,18 +28,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/** @var Config $config */
|
/** @var Config $config */
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow core API variables to also be accessed as functions?
|
* Allow core API variables to also be accessed as functions?
|
||||||
*
|
*
|
||||||
|
@@ -28,18 +28,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/** @var Config $config */
|
/** @var Config $config */
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepend template file
|
* Prepend template file
|
||||||
*
|
*
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php namespace ProcessWire;
|
<?php namespace ProcessWire;
|
||||||
|
|
||||||
|
if(!defined("PROCESSWIRE")) die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProcessWire Request Finished
|
* ProcessWire Request Finished
|
||||||
* ============================
|
* ============================
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php namespace ProcessWire;
|
<?php namespace ProcessWire;
|
||||||
|
|
||||||
|
if(!defined("PROCESSWIRE")) die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProcessWire Bootstrap Initialization
|
* ProcessWire Bootstrap Initialization
|
||||||
* ====================================
|
* ====================================
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
<?php namespace ProcessWire;
|
<?php namespace ProcessWire;
|
||||||
|
|
||||||
|
if(!defined("PROCESSWIRE")) die();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ProcessWire Bootstrap API Ready
|
* ProcessWire Bootstrap API Ready
|
||||||
* ===============================
|
* ===============================
|
||||||
|
@@ -28,18 +28,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/** @var Config $config */
|
/** @var Config $config */
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepend template file
|
* Prepend template file
|
||||||
*
|
*
|
||||||
|
@@ -4,14 +4,14 @@
|
|||||||
* ProcessWire Configuration File
|
* ProcessWire Configuration File
|
||||||
*
|
*
|
||||||
* Site-specific configuration for ProcessWire.
|
* Site-specific configuration for ProcessWire.
|
||||||
* This config.php file was generated by the ProcessExportProfile module.
|
* https://processwire.com/api/ref/config/
|
||||||
*
|
*
|
||||||
* Please see the file /wire/config.php which contains all configuration options you may
|
* Please see the file /wire/config.php which contains all configuration options you may
|
||||||
* specify here. Simply copy any of the configuration options from that file and paste
|
* specify here. Simply copy any of the configuration options from that file and paste
|
||||||
* them into this file in order to modify them.
|
* them into this file in order to modify them.
|
||||||
*
|
*
|
||||||
* ProcessWire 3.x
|
* ProcessWire 3.x
|
||||||
* Copyright (C) 2018 by Ryan Cramer
|
* Copyright (C) 2019 by Ryan Cramer
|
||||||
*
|
*
|
||||||
* https://processwire.com
|
* https://processwire.com
|
||||||
*
|
*
|
||||||
@@ -21,18 +21,6 @@ if(!defined("PROCESSWIRE")) die();
|
|||||||
|
|
||||||
/*** SITE CONFIG *************************************************************************/
|
/*** SITE CONFIG *************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable debug mode?
|
|
||||||
*
|
|
||||||
* Debug mode causes additional info to appear for use during dev and debugging.
|
|
||||||
* This is almost always recommended for sites in development. However, you should
|
|
||||||
* always have this disabled for live/production sites.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
$config->debug = true;
|
|
||||||
|
|
||||||
$config->prependTemplateFile = '_init.php';
|
$config->prependTemplateFile = '_init.php';
|
||||||
$config->appendTemplateFile = '_main.php';
|
$config->appendTemplateFile = '_main.php';
|
||||||
$config->useMarkupRegions = true;
|
$config->useMarkupRegions = true;
|
||||||
|
@@ -11,6 +11,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if(!defined("PROCESSWIRE")) die();
|
||||||
|
|
||||||
/** @var ProcessWire $wire */
|
/** @var ProcessWire $wire */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user