install.php
См. документацию.
1 <?php
2 
3 /**
4  * @file
5  * @brief установочный файл. После установки можно и рекомендуется удалить вместе с каталогом install/
6  *
7  * <a href="/docs/">Подробнее об установке Wrong MVC</a>
8  *
9  * данный файл включен в index.php и после успешной установки его включение комментируется
10  */
11 
12 
13 ob_start();
14 session_start();
15 
16 header("Cache-Control: no-cache");
17 header("Expires: Thu, 01 Jan 1970 00:00:01 GMT");
18 
19 use Wrong\Start\Env;
22 use Wrong\Auth\User;
24 
25 if (($dbh = Connect::getInstance(true)->dbh) && $dbh->query("SHOW TABLES")->fetchAll() && $dbh->query("SELECT COUNT(*) FROM `users`")->fetchColumn()) {
26  dd('Система установлена и есть зарегистрированные юзеры! Удалите в файле ' . $_SERVER['DOCUMENT_ROOT'] . '/index.php включение require \'../install/install.php\'; или очистите БД от таблиц и проведите установку заново');
27 }
28 
29 
30 if (!empty($_POST)) {
31 
32  if (empty($_POST['finish'])) {
33  if (!Locker::lock(basename(__FILE__, '.php'))) {
34  dd("Не удалось получить доступ к файлам блокировки\nУдалите вручную файлы:\n\n" . dirname(__DIR__) . "/temp/lock-dump.lock\n" . dirname(__DIR__) . "/temp/lock-install.lock\n\nи попробуйте <a href=\"#step-2\">заново</a>");
35  }
36  rd($_POST);
37  rd('Записываем конфигурацию...');
38 
39  foreach ($_POST as $name => $value) {
40  Env::$e->set($name, $value);
41  }
42  Env::$e->set('SERVER_ADDR', $_SERVER['SERVER_ADDR']);
43  Env::$e->set('HTTP_HOST', $_SERVER['HTTP_HOST']);
44  rd('Почти готово...');
45  exit('<script>
46  loading();
47  setTimeout(function(){
48  $.ajax({
49  type: "POST",
50  url: "?",
51  data: "finish=1&ADMIN_MAIL=' . $_POST['ADMIN_MAIL'] . '&ADMIN_PASSWORD=' . $_POST['ADMIN_PASSWORD'] . '",
52  dataType: "html",
53  cache: false,
54  success: function(response) {
55  setTimeout(() => {
56  $(\'#step-3\').html(response);
57  loading(\'hide\');
58  }, 3000);
59  }
60  });
61  }, 5000);
62  </script>');
63  }
64 
65  rd('Подключаемся к базе данных...');
66  $dbh = Connect::getInstance()->dbh;
67 
68  try {
69  if (round($dbh->query("SELECT VERSION()")->fetchColumn(), 2) < 10.3) {
70  Locker::unlock(basename(__FILE__, '.php'), true);
71  throw new \Error('Your mariadb version is less than 10.3');
72  }
73  } catch (\Throwable $th) {
74  dd($th);
75  }
76 
77  rd('Заливаем дамп таблиц...');
78  require __DIR__ . '/dump.php';
79 
80  rd('Установка Env переменных среды из таблицы settings...');
81  try {
82  Env::add($dbh->query("SELECT `name`, `value` FROM `settings`")->fetchAll(\PDO::FETCH_KEY_PAIR));
83  } catch (\Throwable $th) {
84  dd($dbh->errorInfo());
85  }
86 
87  rd('Регистрируем администратора...');
89  if (!($id = Users::create($_POST['ADMIN_MAIL'], $_POST['ADMIN_PASSWORD'], [1, 2], 1))) {
90  dd($dbh->errorInfo());
91  }
92  $user = new User($id);
93  $user->set_confirm(1);
94 
95  rd('Отключение установочного скрипта...');
96  try {
97  $index = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/index.php');
98  } catch (\Throwable $th) {
99  dd($th);
100  }
101  $rx = "#(require '\.\./install/install\.php';).*#";
102  $replacement = "// $1 // you can remove this line";
103  $index = preg_replace($rx, $replacement, $index);
104  try {
105  file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/index.php', $index);
106  } catch (\Throwable $th) {
107  dd($th);
108  }
109 
110  rd('Вы можете удалить каталог ' . __DIR__);
111  rd('Установка завершена...');
112  echo "Данные для входа администратора:\nEmail: <kbd contenteditable=\"true\">" . $user->email . "</kbd>\nПароль: <kbd contenteditable=\"true\">" . $_POST['ADMIN_PASSWORD'] . "</kbd>\n\n";
113  Locker::unlock(basename(__FILE__, '.php'), true);
114  Wrong\Task\Stackjs::add('$(function(){successToast("Система WRONG MVC успешно установлена!");$("#wrong").click();});', 0, 'install');
115  exit('<a id="completed" class="btn btn-primary btn-lg" href="/">Готово!</a>');
116 }
117 
118 ?>
119 <!doctype html>
120 <html lang="ru">
121 
122 <head>
123  <meta charset="utf-8">
124  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
125  <link rel="stylesheet" href="/assets/system/css/main.min.css">
126  <script src="/assets/system/js/main.min.js"></script>
127  <title>Установка Wrong MVC</title>
128 </head>
129 
130 
131 <body>
132  <div class="container">
133  <div id="preloader" style="display:none;">
134  <div class="position-fixed bg-secondary w-100 h-100 d-flex align-items-center justify-content-center text-white-50" style="top:0;left:0;z-index:999999;font-size:100px;opacity:0.5;"><i class="fa fa-circle-notch fa-spin" aria-hidden="true"></i></div>
135  </div>
136  <div id="step-1" class="jumbotron mt-3 pt-3 bg-secondary text-white rounded-lg">
137  <h1 class="display-4">WRONG MVC - система для создания систем!</h1>
138  <hr class="my-3">
139  <div class="bg-light text-dark rounded p-3">
140  <?= preg_replace('#.*?(<ul class="check-list">.*?</ul>).*#s', '$1', file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/page/system/main-guest.php')) ?>
141  <script>
142  $('[data-target="#todo"]').replaceWith('И это не всё!');
143  </script>
144  <div class="lead mt-2">
145  <a class="btn btn-primary btn-lg" href="#step-2" role="button">Начнем установку на <?= $_SERVER['HTTP_HOST'] ?></a>
146  </div>
147  </div>
148  </div>
149  <div id="step-2" class="jumbotron mt-5 pt-5 bg-secondary text-white rounded-lg position-relative" style="display:none;">
150  <a class="position-absolute text-white" style="left: 10px;top: 11px;font-size:30px;line-height: 30px;" href="#step-1"><i class="fa fa-arrow-circle-left"></i></a>
151  <h1 class="display-4">WRONG среда почти установлена!</h1>
152  <p class="lead">Быстро неправда ли?</p>
153  <div>Осталось лишь указать доступы к базе данных и аккаунту администратора</div>
154  <hr class="my-4">
155  <form id="install" action="?">
156  <div class="card text-black-50">
157  <div class="card-body">
158  <h6 class="card-title">База данных</h6>
159  <div class="input-group input-group-sm">
160  <div class="input-group-prepend w-25">
161  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Хост</span>
162  </div>
163  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="DB_HOST" value="<?= Env::$e->DB_HOST ?>" autocomplete="off" required>
164  </div>
165  <div class="input-group input-group-sm mt-3">
166  <div class="input-group-prepend w-25">
167  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Порт</span>
168  </div>
169  <input type="number" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="DB_PORT" value="<?= Env::$e->DB_PORT ?>" autocomplete="off" required>
170  </div>
171  <div class="input-group input-group-sm mt-3">
172  <div class="input-group-prepend w-25">
173  <span class="input-group-text w-100" id="inputGroup-sizing-sm">База данных</span>
174  </div>
175  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="DB_DATABASE" value="<?= Env::$e->DB_DATABASE ?>" autocomplete="off" required>
176  </div>
177  <div class="input-group input-group-sm mt-3">
178  <div class="input-group-prepend w-25">
179  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Пользователь</span>
180  </div>
181  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="DB_USERNAME" value="<?= Env::$e->DB_USERNAME ?>" autocomplete="off" required>
182  </div>
183  <div class="input-group input-group-sm mt-3">
184  <div class="input-group-prepend w-25">
185  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Пароль</span>
186  </div>
187  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="DB_PASSWORD" value="<?= Env::$e->DB_PASSWORD ?>" autocomplete="off" required>
188  </div>
189  </div>
190  </div>
191  <div class="card text-black-50 mt-3">
192  <div class="card-body">
193  <h6 class="card-title">Администратор</h6>
194  <div class="input-group input-group-sm mt-3">
195  <div class="input-group-prepend w-25">
196  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Email</span>
197  </div>
198  <input type="email" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="ADMIN_MAIL" value="support@<?= $_SERVER['HTTP_HOST'] ?>" minlength="5" autocomplete="off" required>
199  </div>
200  <div class="input-group input-group-sm mt-3">
201  <div class="input-group-prepend w-25">
202  <span class="input-group-text w-100" id="inputGroup-sizing-sm">Пароль</span>
203  </div>
204  <input type="text" class="form-control" aria-label="Small" aria-describedby="inputGroup-sizing-sm" name="ADMIN_PASSWORD" value="" minlength="5" autocomplete="off" required>
205  </div>
206  </div>
207  </div>
208  <p class="lead mt-3">
209  <button class="btn btn-success btn-lg" type="submit">Закончим установку</button>
210  </p>
211  </form>
212  </div>
213  <pre id="step-3" class="jumbotron mt-5 pt-5 bg-secondary text-white rounded-lg pre" style="display: none;line-height:1.8;"></pre>
214  </div>
215 </body>
216 <script>
217  $(document).on('click', '[href^="#step"]', function(e) {
218  e.preventDefault();
219  $(this).parents('[id^="step"]').hide();
220  $($(this).attr('href')).fadeIn();
221  $('[name="ADMIN_PASSWORD"]').each(function() {
222  !$(this).val() && $(this).val(Math.random().toString(36).slice(2, 10));
223  });
224  });
225 
226  $('#install').submit(function(e) {
227  e.preventDefault();
228  $("#install [type=submit]").attr("disabled", true);
229  $(this).parents('[id^="step"]').hide();
230  $('#step-3').fadeIn();
231  $('#preloader').show();
232  $.ajax({
233  type: "POST",
234  url: "?",
235  data: $(this).serialize(),
236  dataType: "html",
237  cache: false,
238  success: function(response) {
239  $('#step-3').html(response);
240  }
241  }).always(() => {
242  $('#preloader').hide();
243  $("#install [type=submit]").removeAttr("disabled");
244  });
245  });
246 
247  $(document).on('click', 'kbd', function(e) {
248  e.target.focus();
249  const selection = window.getSelection();
250  selection.removeAllRanges();
251  let range = new Range();
252  range.selectNodeContents(this);
253  selection.addRange(range);
254  document.execCommand('copy', false);
255  });
256 
257  $(document).on('copy', 'kbd', function(e) {
258  let text = this.innerText;
259  e.clipboardData.setData('text/plain', text);
260  e.preventDefault();
261  });
262 </script>
263 
264 </html>
265 <?php exit; ?>
$_POST['groups']
Definition: add-action.php:16
User отвечает за работу с данными пользователя
Definition: User.php:21
static session_reset()
Definition: User.php:184
Connect создает подключение к базе данных
Definition: Connect.php:19
Locker блокировщик файлов
Definition: Locker.php:25
Groups контроллер управления моделями пользователей, расширяет Controller.
Definition: Users.php:21
Env класс управляющий, добавляющий или записывающий переменные среды
Definition: Env.php:17
static add($code, $timeout=0, $key='')
Definition: Stackjs.php:25
rd(... $vars)
Definition: debug.php:26
dd(... $vars)
Definition: debug.php:15
$user
Definition: from-user.php:38
setcookie('FROM_UID', $uid, [ 'expires'=> time()+31536000, 'path'=> '/', 'domain'=> $_SERVER['HTTP_HOST'], 'secure'=> Wrong\Start\Env::$e->IS_SECURE, 'httponly'=> false, 'samesite'=> Wrong\Start\Env::$e->IS_SECURE ? 'None' :'Lax']) or setcookie('FROM_UID' $_SERVER['HTTP_HOST']
Definition: from-user.php:36
if(($dbh=Connect::getInstance(true) ->dbh) && $dbh->query("SHOW TABLES") ->fetchAll() && $dbh->query("SELECT COUNT(*) FROM `users`") ->fetchColumn()) if(!empty($_POST)) exit
Definition: install.php:198
$dbh
Definition: session.php:19
href
Definition: main.php:21