From 0d865f78efff6e5be8c5a682962e546b3e11d642 Mon Sep 17 00:00:00 2001
From: Ryan Cramer
Date: Wed, 22 Dec 2021 12:55:14 -0500
Subject: [PATCH] Additional installer updates and add support for a
/site/install/finish.php file that one can use to automatically apply
additional updates to the site once the site profile finishes installing.
Example being added to ProcessExportProfile module.
---
install.php | 309 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 222 insertions(+), 87 deletions(-)
diff --git a/install.php b/install.php
index 60e8be0b..e78df4af 100644
--- a/install.php
+++ b/install.php
@@ -154,8 +154,11 @@ class Installer {
*
*/
protected function checkFunction($name, $label) {
- if(function_exists($name)) $this->ok("$label");
- else $this->err("Fail: $label");
+ if(function_exists($name)) {
+ $this->ok("$label");
+ } else {
+ $this->err("Fail: $label");
+ }
}
/**
@@ -236,6 +239,7 @@ class Installer {
$path = rtrim(str_replace('install.php', '', $_SERVER['REQUEST_URI']), '/') . '/';
$url = htmlspecialchars($path, ENT_QUOTES, 'UTF-8') . 'site-name/';
+ $angleUpIcon = $this->icon('angle-up', false);
echo "
@@ -254,7 +258,7 @@ class Installer {
-
+ $angleUpIcon
Select an installation profile to see more information.
$out
@@ -479,8 +483,8 @@ class Installer {
$this->input('dbName', 'DB Name', $values['dbName']);
$this->input('dbUser', 'DB User', $values['dbUser']);
- $this->input('dbPass', 'DB Pass', $values['dbPass'], false, 'password', false);
- $this->input('dbHost', 'DB Host', $values['dbHost'], false);
+ $this->input('dbPass', 'DB Pass', $values['dbPass'], array('type' => 'password', 'required' => false));
+ $this->input('dbHost', 'DB Host', $values['dbHost']);
$this->input('dbPort', 'DB Port', $values['dbPort']);
$this->select('dbCharset', 'DB Charset', $values['dbCharset'], array('utf8', 'utf8mb4'));
@@ -546,7 +550,7 @@ class Installer {
$this->p("Permissions must be 3 digits each. Should you opt to use the defaults provided, you can also adjust these permissions later if desired by editing /site/config.php.", "detail");
$this->input('chmodDir', 'Directories', $values['chmodDir']);
- $this->input('chmodFile', 'Files', $values['chmodFile'], true);
+ $this->input('chmodFile', 'Files', $values['chmodFile'], array('clear' => true));
if($cgi) {
$this->p(
@@ -583,11 +587,11 @@ class Installer {
$yesChecked = empty($noChecked) ? "checked='checked'" : "";
$this->p(
"
" .
" "
);
@@ -1039,8 +1043,11 @@ class Installer {
$result = $this->copyRecursive($pathname, "./site/assets/$dirname/");
}
- if($result) $this->ok("Imported: $pathname => ./site/assets/$dirname/");
- else $this->err("Error Importing: $pathname => ./site/assets/$dirname/");
+ if($result) {
+ $this->ok("Imported: $pathname => ./site/assets/$dirname/");
+ } else {
+ $this->err("Error Importing: $pathname => ./site/assets/$dirname/");
+ }
}
}
@@ -1108,13 +1115,13 @@ class Installer {
$clean = array();
foreach($values as $key => $value) {
- if($wire && $wire->input->post->$key) $value = $wire->input->post->$key;
+ if($wire && $wire->input->post($key)) $value = $wire->input->post($key);
$value = htmlentities($value, ENT_QUOTES, "UTF-8");
$clean[$key] = $value;
}
$this->sectionStart("fa-sign-in Admin Panel");
- $this->input("admin_name", "Admin Login URL", $clean['admin_name'], false, "name");
+ $this->input("admin_name", "Admin Login URL", $clean['admin_name'], array('type' => 'name'));
$this->clear();
$this->p(
@@ -1128,10 +1135,10 @@ class Installer {
"You will use this account to login to your ProcessWire admin. It will have superuser access, so please make sure " .
"to create a strong password."
);
- $this->input("username", "User", $clean['username'], false, "name");
- $this->input("userpass", "Password", $clean['userpass'], false, "password");
- $this->input("userpass_confirm", "Password (again)", $clean['userpass_confirm'], false, "password");
- $this->input("useremail", "Email Address", $clean['useremail'], true, "email");
+ $this->input("username", "User", $clean['username'], array('type' => 'name'));
+ $this->input("userpass", "Password", $clean['userpass'], array('type' => 'password'));
+ $this->input("userpass_confirm", "Password (again)", $clean['userpass_confirm'], array('type' => 'password'));
+ $this->input("useremail", "Email Address", $clean['useremail'], array('clear' => true, 'type' => 'email'));
$this->p(
"fa-warning Please remember the password you enter above as you will not be able to retrieve it again.",
array('class' => 'detail', 'style' => 'margin-top:0')
@@ -1302,6 +1309,8 @@ class Installer {
$this->ok("User account saved: {$user->name}");
$this->sectionStop();
+
+ $this->finish($wire, $user);
$this->sectionStart("fa-life-buoy Complete & Secure Your Installation");
$this->getRemoveableItems(false, true);
@@ -1313,7 +1322,7 @@ class Installer {
$this->p(
"" .
- "Lean more about securing your ProcessWire installation "
+ "Lean more about securing your ProcessWire installation " . $this->icon('angle-right', false) . ""
);
$this->sectionStop();
@@ -1346,12 +1355,43 @@ class Installer {
}
+ /**
+ * Process custom theme finish.php file
+ *
+ * @param ProcessWire $wire
+ * @param User $user
+ *
+ */
+ protected function finish($wire, $user) {
+ $file = __DIR__ . '/site/install/finish.php';
+ if(is_file($file)) {
+ $fuel = array_merge($wire->wire('all')->getArray(), array('user' => $user));
+ $installer = $this;
+ if($installer) {} // ignore
+ extract($fuel);
+ include($file);
+ }
+ }
+
/******************************************************************************************************************
* OUTPUT FUNCTIONS
*
*/
/**
+ * @param string $str
+ * @param string $type
+ * @param string $icon
+ *
+ */
+ protected function alert($str, $type = 'primary', $icon = 'check') {
+ $icon = $this->icon($icon);
+ echo "\n$icon $str
";
+ }
+
+ /**
+ * Status/ok alert
+ *
* @param string $str
* @param string $icon
*
@@ -1360,11 +1400,13 @@ class Installer {
if($this->inSection) {
$this->ok($str);
} else {
- echo "\n $str
";
+ $this->alert($str, 'primary', $icon);
}
}
/**
+ * Warning alert
+ *
* @param string $str
*
*/
@@ -1373,11 +1415,13 @@ class Installer {
$this->warn($str);
} else {
$this->numErrors++;
- echo "\n $str
";
+ $this->alert($str, 'warning', 'exclamation-triangle');
}
}
/**
+ * Error alert
+ *
* @param string $str
*
*/
@@ -1386,7 +1430,7 @@ class Installer {
$this->err($str);
} else {
$this->numErrors++;
- echo "\n $str
";
+ $this->alert($str, 'danger', 'exclamation-triangle');
}
}
@@ -1397,13 +1441,13 @@ class Installer {
* @return bool
*
*/
- protected function err($str) {
+ public function err($str) {
if(!$this->inSection) {
$this->alertErr($str);
} else {
$this->numErrors++;
- //echo "\n $str";
- echo "\n $str
";
+ $icon = $this->icon('exclamation-triangle');
+ echo "\n$icon $str
";
}
return false;
}
@@ -1415,34 +1459,71 @@ class Installer {
* @return bool
*
*/
- protected function warn($str) {
+ public function warn($str) {
if(!$this->inSection) {
$this->alertWarn($str);
} else {
$this->numErrors++;
- //echo "\n $str";
- echo "\n $str
";
+ $icon = $this->icon('asterisk');
+ echo "\n$icon $str
";
}
return false;
}
/**
- * Report success
+ * Report a status/ok message
*
* @param string $str
* @param string $icon
* @return bool
*
*/
- protected function ok($str, $icon = 'check') {
+ public function ok($str, $icon = 'check') {
if(!$this->inSection) {
$this->alertOk($str);
} else {
- echo "\n $str
";
+ $icon = $this->icon($icon);
+ echo "\n$icon $str
";
}
return true;
}
+ /**
+ * Return markup for an icon
+ *
+ * @param string $name
+ * @param bool $fw Fixed width?
+ * @return string
+ *
+ */
+ public function icon($name, $fw = true) {
+ if(strpos($name, 'icon-') === 0 || strpos($name, 'fa-') === 0) {
+ list(,$name) = explode('-', $name, 2);
+ }
+ $class = 'fa' . ($fw ? ' fa-fw' : '');
+ return "";
+ }
+
+ /**
+ * Given label with 'icon-name' or 'fa-name' at the beginning convert to rendered icon with label
+ *
+ * @param string $label
+ * @param string $icon
+ * @return string
+ *
+ */
+ protected function iconize($label, $icon = '') {
+ if(empty($icon)) {
+ if(strpos($label, 'fa-') === 0 || strpos($label, 'icon-') === 0) {
+ list($icon, $label) = explode(' ', $label, 2);
+ }
+ }
+ if($icon) {
+ $label = $this->icon($icon) . ' ' . $label;
+ }
+ return $label;
+ }
+
/**
* Output a button
*
@@ -1450,7 +1531,7 @@ class Installer {
* @param array $options
*
*/
- protected function btn($label, array $options = array()) {
+ public function btn($label, array $options = array()) {
$defaults = array(
'name' => 'step',
'value' => '0',
@@ -1468,11 +1549,12 @@ class Installer {
$options['type'] = 'button';
echo "";
}
+ $icon = $this->icon($options['icon'], false);
echo "\n" .
"" .
"" .
"
";
if($options['href']) echo "";
@@ -1485,7 +1567,7 @@ class Installer {
* @param array $options
*
*/
- protected function btnContinue(array $options = array()) {
+ public function btnContinue(array $options = array()) {
$this->btn('Continue', $options);
}
@@ -1496,15 +1578,9 @@ class Installer {
* @param string $icon
*
*/
- protected function h($label, $icon = '') {
- if(strpos($label, 'fa-') === 0) {
- list($icon, $label) = explode(' ', $label, 2);
- }
- if($icon) {
- if(strpos($icon, 'fa-') !== 0) $icon = "fa-$icon";
- $icon = " ";
- }
- echo "\n$icon$label
";
+ public function h($label, $icon = '') {
+ $label = $this->iconize($label, $icon);
+ echo "\n$label
";
}
/**
@@ -1514,51 +1590,55 @@ class Installer {
* @param string|array $class Class name, or array of attributes
*
*/
- protected function p($text, $class = '') {
- $icon = '';
- if(strpos($text, 'fa-') === 0) list($icon, $text) = explode(' ', $text, 2);
- if($icon) $icon = " ";
+ public function p($text, $class = '') {
+ $text = $this->iconize($text);
if(is_array($class)) {
echo "\n $v) echo " $k='$v'";
- echo ">$icon$text
";
+ echo ">$text
";
} else if($class) {
- echo "\n$icon$text
";
+ echo "\n$text
";
} else {
- echo "\n$icon$text
";
+ echo "\n$text
";
}
}
/**
* Output an
- *
+ *
* @param string $name
* @param string $label
* @param string $value
- * @param bool $clear
- * @param string $type
- * @param bool $required
+ * @param array $options
*
*/
- protected function input($name, $label, $value, $clear = false, $type = "text", $required = true) {
- $width = 150;
- $required = $required ? "required='required'" : "";
+ public function input($name, $label, $value, array $options = array()) {
+ $defaults = array(
+ 'clear' => false,
+ 'type' => 'text',
+ 'required' => true,
+ 'width' => 150,
+ );
+ $options = array_merge($defaults, $options);
+ $width = $options['width'];
+ $required = $options['required'] ? "required='required'" : "";
$pattern = '';
$note = '';
- if($type == 'email') {
- $width = ($width*2);
+ if($options['type'] === 'email') {
+ $width = ($width*2);
$required = '';
- } else if($type == 'name') {
- $type = 'text';
+ } else if($options['type'] === 'name') {
+ $options['type'] = 'text';
$pattern = "pattern='[-_a-z0-9]{2,50}' ";
if($name == 'admin_name') $width = ($width*2);
$note = "(a-z 0-9)";
}
- $inputWidth = $width - 15;
- $value = htmlentities($value, ENT_QUOTES, "UTF-8");
+ $inputWidth = $width - 15;
+ $value = htmlentities($value, ENT_QUOTES, "UTF-8");
echo "\n";
- if($clear) $this->clear();
+ echo "";
+ echo "";
+ if($options['clear']) $this->clear();
}
/**
@@ -1567,11 +1647,11 @@ class Installer {
* @param string $name
* @param string $label
* @param string $value
- * @param array $options
+ * @param array $options Array of selectable options in format [ 'value' => 'label' ]
* @param int $width
*
*/
- protected function select($name, $label, $value, array $options, $width = 150) {
+ public function select($name, $label, $value, array $options, $width = 150) {
if($width) {
$inputWidth = $width - 15;
@@ -1594,7 +1674,13 @@ class Installer {
echo "\n\t";
echo "\n";
}
-
+
+ /**
+ * Render a timezone select
+ *
+ * @param $value
+ *
+ */
protected function selectTimezone($value) {
echo "\n";
echo "\n\t\n
";
}
-
- protected function textarea($name, $label, $value, $rows = 0) {
+
+ /**
+ * Render a textarea input
+ *
+ * @param string $name
+ * @param string $label
+ * @param string $value
+ * @param int $rows
+ *
+ */
+ public function textarea($name, $label, $value, $rows = 0) {
$rows = $rows ? " rows='$rows'" : "";
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');
echo "\n";
@@ -1616,29 +1711,53 @@ class Installer {
echo "\n\t";
echo "\n
";
}
-
- protected function sectionStart($headline = '', $type = 'muted') {
+
+ /**
+ * Start section
+ *
+ * @param string $headline
+ * @param string $type
+ *
+ */
+ public function sectionStart($headline = '', $type = 'muted') {
echo "\n";
echo "\n\t
";
- $icon = '';
- if(strpos($headline, 'fa-') === 0) {
- list($icon, $headline) = explode(' ', $headline, 2);
- $icon = " ";
+ if($headline) {
+ $headline = $this->iconize($headline);
+ echo "
$headline
";
}
- if($headline) echo "$icon$headline
";
$this->inSection = true;
}
-
- protected function sectionStop() {
+
+ /**
+ * Stop section
+ *
+ */
+ public function sectionStop() {
echo "\n\t\n
";
$this->inSection = false;
}
-
- protected function clear() {
+
+ /**
+ * Clear floated elements
+ *
+ */
+ public function clear() {
echo "\n";
}
-
- protected function post($key, $sanitizer = '') {
+
+ /**
+ * Get a POST variable, optionally sanitized name sanitizer
+ *
+ * Options for $sanitizer argument:
+ * int, intSigned, text, textarea, string, pageName, name, fieldName, bool, array
+ *
+ * @param string $key
+ * @param string $sanitizer
+ * @return int|mixed|null|string
+ *
+ */
+ public function post($key, $sanitizer = '') {
$value = isset($_POST[$key]) ? $_POST[$key] : null;
@@ -1720,7 +1839,7 @@ class Installer {
* @return bool
*
*/
- protected function mkdir($path, $showNote = true, $block = false) {
+ public function mkdir($path, $showNote = true, $block = false) {
if(self::TEST_MODE) return true;
$path = rtrim($path, '/') . '/';
$isDir = is_dir($path);
@@ -1751,8 +1870,16 @@ class Installer {
}
return $result;
}
-
- protected function copyFile($src, $dst) {
+
+ /**
+ * Copy a file
+ *
+ * @param string $src
+ * @param string $dst
+ * @return bool
+ *
+ */
+ public function copyFile($src, $dst) {
if(!@copy($src, $dst)) {
$this->alertErr("Unable to copy $src => $dst (please copy manually if possible)");
return false;
@@ -1760,8 +1887,16 @@ class Installer {
chmod($dst, octdec($this->chmodFile));
return true;
}
-
- protected function renameFile($src, $dst) {
+
+ /**
+ * Rename a file
+ *
+ * @param string $src
+ * @param string $dst
+ * @return bool
+ *
+ */
+ public function renameFile($src, $dst) {
if(!@rename($src, $dst)) {
$this->alertErr("Unable to rename $src => $dst (please rename manually if possible)");
return false;
@@ -1779,7 +1914,7 @@ class Installer {
* @return bool
*
*/
- protected function copyRecursive($src, $dst, $overwrite = true) {
+ public function copyRecursive($src, $dst, $overwrite = true) {
if(self::TEST_MODE) return true;