YaWK  24.1
Yet another WebKit
installer.php
Go to the documentation of this file.
1 <?php
2 namespace YAWK {
3 
4  /**
5  * @details <b>installer Class</b>
6  * @brief This class handles the setup / installation process
7  */
8  class installer
9  {
10  /** * @param int $step holds the installation step variable */
11  public $step;
12  /** * @param string $url URL of that website */
13  public $url;
14  /** * @param string $rootPath the root path where yawk is installed*/
15  public $rootPath;
16  /** * @param string $configFile the path and filename to install.ini which helds the setup configuration */
17  public $configFile = "system/setup/install.ini";
18  /** * @param string $dbConfigPhp the path and filename to dbconfig.php which helds the mysql configuration */
19  public $dbConfigPhp = "system/classes/dbconfig.php";
20  /** * @param string $sqlFile the path and filename to yawk's core sql database file */
21  public $sqlFile = "system/setup/yawk_database.sql";
22  /** * @param string $filePointer the path and filename to the sql file's filepointer */
23  public $filePointer = "system/setup/yawk_database.sql_filepointer";
24  /** * @param string $yawkVersion detected from install.ini */
25  public $yawkVersion;
26  /** * @param string $version Installer version */
27  public $version = "1.0";
28  /** * @param bool $phpVersionStatus PHP Version */
30  /** * @param string $phpVersionRequired required PHP version */
31  public $phpVersionRequired = "8.x";
32  /** * @param string $phpCheckIcon php version icon: depending on true or false, check or times */
33  public $phpCheckIcon;
34  /** * @param string $apacheStatus Apache Version */
35  public $apacheStatus;
36  /** * @param string $apacheCheckIcon apache version icon: depending on true or false, check or times */
38  /** * @param string $zlib zlib enalbed? string: true or false */
39  public $zlib;
40  /** * @param string $zlibCheckIcon zlib icon: depending on true or false, check or times */
42  /** * @param string $modRewriteStatus is mod_rewrite available? */
44  /** * @param string $modRewriteCheckIcon mod_rewrite icon depending on true or false, check or times */
46  /** * @param bool $serverRequirements does the server fulfil requirements? true or false */
48  /** * @param string $serverRequirementCount how many requirements were met? */
50  public $setupIndicator = 'system/setup/setup.indicator';
51 
52  /**
53  * @brief installer constructor.
54  * build and return the html head
55  * @author Daniel Retzl <[email protected]>
56  * @copyright 2017 Daniel Retzl
57  * @license https://opensource.org/licenses/MIT
58  */
59  function __construct()
60  {
61  echo '
62 <html>
63  <head>
64  <meta charset="utf-8">
65  <meta http-equiv="X-UA-Compatible" content="IE=edge">
66  <title>SETUP YaWK | Yet another Web Kit</title>
67  <!-- Tell the browser to be responsive to screen width -->
68  <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
69  <!-- favicon -->
70  <link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
71  <!-- Bootstrap 4 -->
72  <link rel="stylesheet" href="system/engines/bootstrap4/css/bootstrap.min.css">
73  <!-- Animate CSS -->
74  <link rel="stylesheet" href="system/engines/animateCSS/animate.min.css">
75  <!-- Font Awesome -->
76  <link rel="stylesheet" href="system/engines/font-awesome/css/font-awesome.min.css">
77  <!-- Admin LTE -->
78  <link rel="stylesheet" href="system/engines/AdminLTE/css/AdminLTE.min.css">
79  <!-- jQuery 3.2.1 -->
80  <script type="text/javascript" src="system/engines/jquery/jquery-3.6.4.min.js"></script>
81  <!-- jQuery validation plugin -->
82  <script type="text/javascript" src="system/engines/jquery/jquery.validate.min.js"></script>
83  <!-- popper.js used by bootstrap to help positioning the tooltips -->
84  <script type="text/javascript" src="system/engines/jquery/popper.min.js"></script>
85  <!-- Notify JS -->
86  <script src="system/engines/jquery/notify/bootstrap-notify.min.js"></script>
87  <!-- Bootstrap 4 JS -->
88  <script type="text/javascript" src="system/engines/bootstrap4/js/bootstrap.min.js"></script>
89  <!-- pace JS -->
90  <script src="system/engines/pace/pace.min.js"></script>
91  <link rel="stylesheet" href="system/engines/pace/pace-minimal-installer.css">
92  <!-- custom YaWK setup css -->
93  <link rel="stylesheet" href="system/setup/setup.css">
94  </head>
95 
96  <body style="background-color: #ebebeb; margin-top:50px;">
97  <div class="container animated fadeIn slow shadow-lg" style="background-color: #fff;">
98  <form method="POST" id="installerForm">
99  ';
100  }
101 
102  /**
103  * @brief Initialize the installer.
104  * @details check and set the current / supported language, check if install.ini exists and start setup process
105  * @author Daniel Retzl <[email protected]>
106  * @copyright 2017 Daniel Retzl
107  * @license https://opensource.org/licenses/MIT
108  */
109  public function init(): void
110  { // set setup indicator
111  $_SESSION['SETUP'] = TRUE;
112  /* CHECK + SET LANGUAGE */
113  // include language class
114  $language = '';
115  require_once ('system/classes/language.php');
116  /* check if language object is set*/
117  if ((empty($lang)))
118  { // set new language object
119  $language = new language();
120  // default language if detection not works
121  $language->defaultLanguage = "en-EN";
122  // set the path to the language file
123  $language->pathToFile = "admin/language/";
124 
125  // try to get the client language
126  if ($language->detectedLanguage = $language->getClientLanguage())
127  { // currentLanguageGlobal is set due call of getClientLanguage
128  if ($language->isSupported($language->currentLanguageGlobal))
129  { // client language is supported, set it
130  $language->currentLanguage = $language->currentLanguageGlobal;
131  $language->setLanguage($language->currentLanguageGlobal);
132  }
133  else
134  { // client language is not supported - set default (eg. en-EN)
135  $language->setDefault($language->defaultLanguage);
136  }
137  }
138  // if current language is sent via form (POST data)
139  if (isset($_POST['currentLanguage']) && (!empty($_POST['currentLanguage'])))
140  { // check if POST language is supported
141  if ($language->isSupported($_POST['currentLanguage']))
142  { // POST language is supported
143  $language->detectedLanguage = $_POST['currentLanguage'];
144  $language->setLanguage($language->detectedLanguage);
145  }
146  else
147  { // POST language is NOT supported - set default (eg. en-EN)
148  $language->currentLanguage = $language->defaultLanguage;
149  $language->setDefault($language->defaultLanguage);
150  }
151  }
152  // convert language object param to array $lang[] that contains all the language data
153  $lang = (array) $language->lang;
154  }
155 
156  /* INSTALLER SCRIPT */
157  // check if system/setup/install.ini file is available
158  if (file_exists($this->configFile) && (is_readable($this->configFile)))
159  { // install.ini found, next step...
160  // check, if filepointer is found and readable
161  // if so, that means we may got a corrupt installation, probably due to a failed database import
162  // this can happen, if the database user has no rights to create tables or if - more common -
163  // the user has interrupted the import process (browser abort button / browser reload / browser close)
164 
165  // check if filepointer exists
166  if (file_exists($this->filePointer) || (file_exists($this->setupIndicator) && (empty($_POST)))) { // filepointer found, which indicates, that something strange has happened during db import
167  // no we try to fix the broken installation by re-installing db and deleting the filepointer
168  // check if db config file already exists and is readable
169  if (file_exists($this->dbConfigPhp) && (is_readable($this->dbConfigPhp))) { // yep, good chance to reset the database
170  // CALL RESET DATABASE METHOD
171  $this->resetInstallation($language, $lang);
172  }
173  else
174  { // TELL: no db config file found, unable to reset database
175  die ("$lang[INSTALLER_FIX_FAILED] $lang[INSTALLER_FIX_FAILED_SUBTEXT] $lang[MISSING_FILE] $this->dbConfigPhp $lang[INSTALLER_FIX_FAILED_EXPLAIN]");
176  }
177  }
178  else
179  { // filepointer not found, so we assume, that this is a fresh installation
180  /* LOAD INSTALLER */
181  $this->setup($language, $lang);
182  }
183  }
184  else
185  { // init() failed - INSTALL.INI is not found or not readable
186  // the only thing we can do is to tell the user, that something is wrong and tell him to restart the setup again
187  die ("$lang[INSTALLER_BROKEN] $lang[INSTALLER_BROKEN_SUBTEXT] $lang[MISSING_FILE] $this->configFile");
188  }
189  } // ./ end installer init()
190 
191  /**
192  * @brief Start the setup process.
193  * @details include core functions and check server requirements. handles the installation steps
194  * @param object $language language object
195  * @param array $lang language data array
196  * @author Daniel Retzl <[email protected]>
197  * @copyright 2017 Daniel Retzl
198  * @license https://opensource.org/licenses/MIT
199  */
200  public function setup($language, $lang)
201  { /* CHECK + SET LANGUAGE */
202 
203  // include other core classes
204  require_once('system/classes/settings.php');
205  require_once('system/classes/alert.php');
206  require_once('system/classes/sys.php');
207  require_once('system/classes/user.php');
208 
209  // run server checks and save status variables
211 
212  // get install data into array
213  if ($setup = parse_ini_file($this->configFile, FALSE))
214  { // get the yawk version
215  $this->yawkVersion = $setup['VERSION']; // used in the footer
216  if (is_file('system/update/system.ini'))
217  {
218  if ($system = parse_ini_file('system/update/system.ini', FALSE))
219  { // get the yawk version
220  $this->yawkVersion = $system['currentVersion'];
221  }
222  }
223  // if INSTALL is set to true
224  if ($setup['INSTALL'] === "true")
225  { // if no step variable is set, setup run for the first time
226  if (empty($_POST['step']))
227  { // STEP 1 -- LANGUAGE SELECTION
228  $_POST['step'] = 1;
229  // STEP 1 - language selector
230  $this->step1($language, $lang);
231  }
232 
233  // STEP 1 - Language Data
234  if (isset($_POST['step']) && $_POST['step'] === "1")
235  { // in this step, the user sets the language
236  $this->step1($language, $lang);
237  }
238 
239  // STEP 2 - MySQL data
240  if (isset($_POST['step']) && $_POST['step'] === "2")
241  { // in this step, the user set the mysql configuration
242  $this->step2($setup, $language, $lang);
243  }
244 
245  // STEP 3 - common website and project data
246  if (isset($_POST['step']) && $_POST['step'] === "3")
247  { // common project data like url, title and description
248  $this->step3($setup, $language, $lang);
249  }
250 
251  // STEP 4 - admin user data
252  if (isset($_POST['step']) && ($_POST['step'] === "4"))
253  { // set admin user data
254  $this->step4($setup, $language, $lang);
255  }
256 
257  // STEP 5 - finish & login
258  if (isset($_POST['step']) && ($_POST['step'] === "5"))
259  { // finish and login
260  $this->step5($setup, $language, $lang);
261  }
262  }
263  }
264  else
265  { // unable to parse setup.ini file - something is wrong there is nothing we can do, but to tell the user to re-download the installation package
266  die ("$lang[INSTALLER_BROKEN] $lang[INSTALLER_BROKEN_SUBTEXT] $lang[PARSE_ERROR] $this->configFile");
267  }
268  // prevent from displaying anything else than the single steps
269  exit;
270  }
271 
272 
273  /** @brief RESET - RESET DATABASE xor CORRUPT INSTALLATION
274  * @param array $lang language data array
275  * @author Daniel Retzl <[email protected]>
276  * @license https://opensource.org/licenses/MIT
277  */
278  public function resetInstallation($language, $lang)
279  {
280  // include database and settings class
281  if (!isset($db)) {
282  require_once('system/classes/db.php');
283  $db = new \YAWK\db();
284  }
285  require_once('system/classes/dbconfig.php');
286  // ok, lets test the database connection...
287  $tableName = "cms_assets"; // replace with your table name
288  $sql = "SHOW TABLES LIKE '{$tableName}'";
289  $result = $db->query($sql);
290  if ($result->num_rows > 0) {
291  // table already exists, truncate all tables
292  $sql = "SHOW TABLES";
293  $result = $db->query($sql);
294  while ($row = $result->fetch_array()) {
295  $tableName = $row[0];
296  $sql = "DROP TABLE {$tableName}";
297  $db->query($sql);
298  }
299  }
300  // check if setup indicator file exists
301  if (file_exists($this->setupIndicator))
302  { // delete setup indicator file to reset setup
303  unlink($this->setupIndicator);
304  }
305  // check if file pointer file exists
306  if (file_exists($this->filePointer))
307  { // delete file pointer file to reset setup
308  unlink($this->filePointer);
309  }
310 
311  // all tables dropped, all files deleted now we can start the installation process again
312  $this->setup($language, $lang);
313  }
314 
315  /** @brief step 1 - SELECT LANGUAGE
316  * @param object $language language object
317  * @param array $lang language data array
318  * @author Daniel Retzl <[email protected]>
319  * @license https://opensource.org/licenses/MIT
320  */
321  public function step1($language, array $lang) // STEP 1 - LANGUAGE SELECTION
322  {
323  $this->step = 1;
324  echo "<div class=\"row\">
325  <div class=\"col-md-2 text-justify\">
326 
327  </div>
328  <div class=\"col-md-8\">
329  <h1 class=\"mt-5\">YaWK <small>$lang[INSTALLATION]</small></h1>
330  <h4><i class=\"fa fa-language\"></i> &nbsp; $lang[STEP] $_POST[step]/5 <small>$lang[PREPARATION]</small></h4>
331  <hr>
332  <label for=\"currentLanguage\">$lang[LANG_LABEL]
333  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_SUPPORTED_LANGUAGES]\"></i></small>
334  </label>
335  <select required class=\"form-control\" id=\"currentLanguage\" name=\"currentLanguage\">
336  ".$this->getLanguageSelectOptions($language, $lang)."
337  </select>
338  <br>
339  <button class=\"btn btn-success pull-right\" type=\"submit\" id=\"saveBtn\"><small>$_POST[step]/5</small> &nbsp;$lang[NEXT_STEP] &nbsp;<i class=\"fa fa-arrow-right\"></i></button>
340  <input type=\"hidden\" name=\"step\" value=\"2\">
341  <br><br><br>
342  </div>
343  <div class=\"col-md-2 text-justify\">
344 
345  </div>
346  </div>";
347  }
348 
349  /** @brief step 2 - DB DATA + SERVER REQUIREMENTS
350  * @param array $setup installation settings
351  * @param object $language language object
352  * @param array $lang language data array
353  * @author Daniel Retzl <[email protected]>
354  * @license https://opensource.org/licenses/MIT
355  */
356  public function step2(array $setup, $language, array $lang) // STEP 2 - MYSQL DATA
357  {
358  $this->step = 2;
359  echo '
360  <!-- YaWK Setup Helper -->
361  <script src="system/setup/setupHelper.js"></script>';
362  echo "<div class=\"row\">
363  <div class=\"col-md-7\">
364  <h1>YaWK <small>$lang[INSTALLATION]</small></h1>
365  <h4><i class=\"fa fa-database\"></i> &nbsp; $lang[STEP] $_POST[step]/5 <small>$lang[DATABASE]</small></h4>
366  <hr>
367  <h4>$lang[MYSQL_DATA] <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_CREDENTIALS]\"></i></small></h4>
368  <label for=\"DB_HOST\">$lang[DB_HOST] <small><i>$lang[DB_HOST_SUBTEXT]</i></small>
369  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBHOST]\"></i></small>
370  </label>
371  <input required type=\"text\" class=\"form-control\" name=\"DB_HOST\" id=\"DB_HOST\" placeholder=\"$setup[DB_HOST]\">
372 
373  <label for=\"DB_NAME\">$lang[DB_NAME] <small><i>$lang[DB_NAME_SUBTEXT]</i></small>
374  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBNAME]\"></i></small>
375  </label>
376  <input required type=\"text\" class=\"form-control\" name=\"DB_NAME\" id=\"DB_NAME\" placeholder=\"$setup[DB_NAME]\">
377 
378  <label for=\"DB_USER\">$lang[DB_USER] <small><i>$lang[DB_USER_SUBTEXT]</i></small>
379  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBUSER]\"></i></small>
380  </label>
381  <input required type=\"text\" class=\"form-control\" name=\"DB_USER\" id=\"DB_USER\" placeholder=\"$setup[DB_USER]\">
382 
383  <label for=\"DB_PASS\">$lang[DB_PASS] <small><i>$lang[DB_PASS_SUBTEXT]</i></small>
384  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBPASS]\"></i></small>
385  </label>
386  <input required type=\"password\" class=\"form-control\" name=\"DB_PASS\" id=\"DB_PASS\" placeholder=\"$setup[DB_PASS]\"><br>";
387 
388 
389  if ($this->serverRequirements === true)
390  {
391  echo "<button type=\"submit\" name=\"save\" id=\"savebutton\" class=\"btn btn-success pull-right\"><small>$_POST[step]/5</small> &nbsp;$lang[CHECK_DB] &nbsp;<i id=\"savebuttonIcon\" class=\"fa fa-arrow-right\"></i></button>";
392  }
393  else
394  {
395  echo "<button type=\"submit\" class=\"btn btn-warning pull-right\" disabled aria-disabled=\"true\"><small>$_POST[step]/5</small> &nbsp;$lang[CHECK_DB] &nbsp;<i class=\"fa fa-arrow-right\"></i></button>";
396  }
397 
398  echo "<br><h4 class=\"mt-5\">$lang[MYSQL_DATA_EXT]</h4>
399 
400  <label for=\"DB_PREFIX\">$lang[DB_PREFIX] <small><i>$lang[DB_PREFIX_SUBTEXT]</i></small>
401  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBPREFIX]\"></i></small>
402  </label>
403  <input required type=\"text\" class=\"form-control\" name=\"DB_PREFIX\" id=\"DB_PREFIX\" placeholder=\"$setup[DB_PREFIX]\" value=\"$setup[DB_PREFIX]\">
404 
405  <label for=\"DB_PORT\">$lang[DB_PORT] <small><i>$lang[DB_PORT_SUBTEXT]</i></small>
406  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_DBPORT]\"></i></small>
407  </label>
408  <input required type=\"text\" class=\"form-control\" name=\"DB_PORT\" id=\"DB_PORT\" placeholder=\"$setup[DB_PORT]\" value=\"$setup[DB_PORT]\">
409 
410  <!-- <button type=\"button\" class=\"btn btn-default\" onClick=\"history.go(-1);return true;\"><i class=\"fa fa-arrow-left\"></i> &nbsp;back</button> -->
411  ";
412 
413  echo"<input type=\"hidden\" name=\"step\" value=\"3\">
414  <input type=\"hidden\" name=\"currentLanguage\" value=\"$language->currentLanguage\">
415  <input type=\"hidden\" name=\"DB_CHECK_TO\" value=\"$lang[DB_CHECK_TO]\">
416  <input type=\"hidden\" name=\"DB_CHECK_EST\" value=\"$lang[DB_CHECK_EST]\">
417  <input type=\"hidden\" name=\"DB_CHECK_FAILED\" value=\"$lang[DB_CHECK_FAILED]\">
418  <input type=\"hidden\" name=\"DB_CHECK_DATA\" value=\"$lang[DB_CHECK_DATA]\">
419  <input type=\"hidden\" name=\"DB_IMPORT_MSG\" value=\"$lang[DB_IMPORT_MSG]\">
420  <input type=\"hidden\" name=\"DB_CHECK_AGAIN\" value=\"$lang[DB_CHECK_AGAIN]\">
421  <input type=\"hidden\" name=\"DB_IMPORT_BTN\" value=\"$lang[DB_IMPORT_BTN]\">
422  </div>
423 
424  <div class=\"col-md-5 text-justify\">
425  <br><br>
426  <br><br>
427  <h4>$lang[INSTALL_NOTICE_HEADING]</h4>
428  $lang[INSTALL_NOTICE]
429  <br><br><br>
430  <h4>$lang[SYS_REQ]</h4>
431  <ul class=\"list-unstyled\">
432  <li>$this->apacheCheckIcon <b>Apache 2.x</b> $lang[OR] <b>nginx</b></li>
433  <li>$this->phpCheckIcon PHP $this->phpVersionRequired <small><i><small>($lang[USES]: ".phpversion().")</small></i></small></li>
434 
435  <ul class=\"list-unstyled small\">
436  <li>&nbsp;&nbsp;&nbsp;&nbsp;$this->zlibCheckIcon +mod_gzip <small><i>($lang[AVAILABLE]: ".$this->zlib.") </i></small></li>
437  <li>&nbsp;&nbsp;&nbsp;&nbsp;$this->modRewriteCheckIcon +mod_rewrite <small><i>($lang[AVAILABLE]: ".$this->modRewriteStatus.") </i></small></li>
438  </ul>
439  </ul><br>";
440 
441  if ($this->phpVersionStatus == "true")
442  { // server requirements met
443  echo "<h4 class=\"text-success\" id=\"ajaxMessage\">$lang[SERVER_REQ_TRUE]</h4>";
444 
445  if (is_writable('.htaccess')){
446  echo "<span class=\"text-success\"><i class=\"fa fa-check\"></i> &nbsp;$lang[HTACCESS_ROOT_WRITABLE]</span><br>";
447  }
448  else {
449  echo "<span class=\"text-danger text-bold\"><i class=\"fa fa-exclamation-circle\"></i> &nbsp;$lang[HTACCESS_ROOT_NOT_WRITABLE] <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_HTACCESS_RIGHTS]\"></i></small></span><br>";
450  }
451  if (is_writable('admin/.htaccess')){
452  echo "<span class=\"text-success\"><i class=\"fa fa-check\"></i> &nbsp; $lang[HTACCESS_ADMIN_WRITABLE]</span><br>";
453  }
454  else {
455  echo "<span class=\"text-danger text-bold\"><i class=\"fa fa-exclamation-triangle\"></i> &nbsp; $lang[HTACCESS_ADMIN_NOT_WRITABLE]</span><br>";
456  }
457  }
458  else
459  { // server does not fulfill requirements, draw error
460  \YAWK\alert::draw("warning", "$lang[SYS_REQ]", "$lang[SERVER_REQ_FALSE]", '', '');
461  }
462  echo"<br><h4>$lang[DATA_PACKAGES] <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_PACKAGES]\"></i></small></h4>
463  <input required type=\"checkbox\" id=\"installCoreData\" name=\"installCoreData\" checked disabled>
464  <label for=\"installCoreData\" style=\"font-weight: normal;\">$lang[YAWK_INSTALLATION_FILES] <small>($setup[VERSION])</small></label>
465  <br>
466  <input type=\"checkbox\" id=\"installSampleData\" name=\"installSampleData\" disabled>
467  <label for=\"installSampleData\" style=\"font-weight: normal;\">$lang[YAWK_EXAMPLE_FILES] <small><small><i>$lang[USERS_PAGES_MENUS]</i></small></small>
468  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_PACKAGES_EXAMPLE]\"></i></small>
469  </label>
470  <br><br><b>$lang[DB_CHECK]</b><br><br><br><br><br><br></div> <!-- end col -->
471  </div> <!-- end row -->
472  ";
473  }
474 
475  /** @brief step 3 - write db-config, check + import db connection If all went good, a form with project settings gets drawn.
476  * @param array $setup installation settings
477  * @param object $language language object
478  * @param array $lang language data array
479  * @throws \Exception
480  * @license https://opensource.org/licenses/MIT
481  * @author Daniel Retzl <[email protected]>
482  */
483  public function step3(array $setup, $language, array $lang) // STEP 3 - WRITE DB CONFIG FILE + ADD GLOBAL SITE DATA
484  {
485  // server-side check if user has filled out all required fields of step 2
486  if (empty($_POST['DB_HOST'])
487  || (empty($_POST['DB_USER'])
488  || (empty($_POST['DB_NAME'])
489  || (empty($_POST['DB_PREFIX'])
490  || (empty($_POST['DB_PORT'])
491  )))))
492  { // kick user back to step 2, due missing or empty settings
493  if (isset($_POST['step']) && (!empty($_POST['step']))) { $_POST['step']--; }
494  $this->step2($setup, $language, $lang);
495  \YAWK\alert::draw("danger", "$lang[DB_ERROR]", "$lang[DB_ERROR_MISSING_FIELDS]", "", 5000);
496  exit;
497  }
498  else
499  { // data from step 2 seem to be OK...
500  $this->step = 3;
501  // get root base path
502  $this->rootPath = \YAWK\sys::getBaseDir();
503 
504  // write DB connection into db-config.php
505  $data = "
506 <?php
507  \$this->config['server'] = \"".$_POST['DB_HOST']."\";
508  \$this->config['username'] = \"".$_POST['DB_USER']."\";
509  \$this->config['password'] = \"".$_POST['DB_PASS']."\";
510  \$this->config['dbname'] = \"".$_POST['DB_NAME']."\";
511  \$this->config['prefix'] = \"".$_POST['DB_PREFIX']."\";
512  \$this->config['port'] = \"".$_POST['DB_PORT']."\";
513 ?>";
514  // check if dbconfig file was successfully written...
515  if (file_put_contents($this->dbConfigPhp, $data))
516  {
517  // include database and settings class
518  if (!isset($db)) {
519  require_once('system/classes/db.php');
520  $db = new \YAWK\db();
521  }
522 
523  // ok, lets test the database connection...
524  if ($db->connect())
525  {
526  // import .sql data
527  if ($status = $db->import($this->sqlFile, $lang))
528  { // delete filepointer, because it is not needed anymore
529  unlink($this->filePointer);
530 
531  // write current version into db
532  if (!empty($this->yawkVersion)){
533  \YAWK\settings::setSetting($db, "yawkversion", $this->yawkVersion, $lang);
534  }
535 
536  \YAWK\alert::draw("success", "$lang[DB_IMPORT]", "$lang[DB_IMPORT_OK]", "", 2000);
537 
538  // setup indicator will be used to check if setup was already done until this step
539  touch($this->setupIndicator);
540  }
541  else
542  { // delete filepointer, start again at next try
543  unlink($this->filePointer);
544  $this->step2($setup, $language, $lang);
545  \YAWK\alert::draw("danger", "$lang[DB_IMPORT]", "$lang[DB_IMPORT_FAILED]", "setup.php", 6000);
546  }
547  }
548  else
549  { // kick user back to step 2, due missing or empty settings
550  if (isset($_POST['step']) && (!empty($_POST['step']))) { $_POST['step']--; }
551  $this->step2($setup, $language, $lang);
552  exit;
553  }
554 
555  echo"
556  <div class=\"row\">
557  <div class=\"col-md-7 text-justify\">
558  <h1>YaWK <small>$lang[INSTALLATION]</small></h1>
559  <h4><i class=\"fa fa-pencil\"></i> &nbsp; $lang[STEP] $_POST[step]/5 <small>$lang[PROJECT_SETTINGS]</small></h4>
560  <hr><h4>$lang[COMMON_PROJECT_SETTINGS]</h4>
561  <label for=\"URL\">$lang[URL] <small><i>$lang[URL_SUBTEXT]</i></small>
562  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[HOST_LABEL]\"></i></small>
563  </label>
564  <input required type=\"text\" class=\"form-control\" name=\"URL\" id=\"URL\" placeholder=\"$setup[URL]\">
565  <label for=\"TITLE\">$lang[TITLE] <small><i>$lang[INSTALLER_TITLE_SUBTEXT]</i></small>
566  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[TITLE_LABEL]\"></i></small>
567  </label>
568  <input required type=\"text\" class=\"form-control\" name=\"TITLE\" id=\"TITLE\" placeholder=\"$lang[INSTALLER_TITLE]\">
569  <label for=\"DESC\">$lang[INSTALLER_DESC] <small><i>$lang[INSTALLER_DESC_SUBTEXT]</i></small>
570  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[SHORT_DESCRIPTION_PH]\"></i></small>
571  </label>
572  <input required type=\"text\" class=\"form-control\" name=\"DESC\" id=\"DESC\" placeholder=\"$lang[INSTALLER_DESC_PLACEHOLDER]\">
573  <br>
574  <input type=\"hidden\" name=\"step\" value=\"4\">
575  <input type=\"hidden\" name=\"currentLanguage\" value=\"$language->currentLanguage\">
576  <button type=\"submit\" class=\"btn btn-success pull-right\"><small>$_POST[step]/5</small> &nbsp;$lang[NEXT_STEP] &nbsp;<i class=\"fa fa-arrow-right\"></i></button>
577  <br><br><br>
578  <label for=\"ROOT_PATH\">$lang[ROOT_PATH] <small><i>$lang[ROOT_PATH_SUBTEXT]</i></small>
579  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_ROOT_PATH]\"></i></small>
580  </label>
581  <input type=\"text\" class=\"form-control\" name=\"ROOT_PATH\" id=\"ROOT_PATH\" value=\"$this->rootPath\" placeholder=\"$setup[ROOT_PATH]\">
582  </div>
583  <div class=\"col-md-5 text-justify\">
584  <br><br>
585  <br><br>
586  <h4>$lang[BASE_INFO]</h4>
587  $lang[INSTALL_NOTICE_BASE_INFO]
588  <br><br><br>
589  <b>$lang[STEP4]</b><br>
590  </div>
591  </div>";
592  }
593  else
594  { // if not - draw error
595  \YAWK\alert::draw("danger", "$lang[DBCONFIG_WRITE_FAILED]", "$lang[DBCONFIG_WRITE_FAILED]", "","");
596  $this->step2($setup, $language, $lang);
597  exit;
598  }
599  }
600  }
601 
602  /** @brief step 4 - save project settings and draw a form to enter user data (email, name, password...)
603  * @param array $setup installation settings
604  * @param object $language language object
605  * @param array $lang language data array
606  * @author Daniel Retzl <[email protected]>
607  * @license https://opensource.org/licenses/MIT
608  */
609  public function step4(array $setup, $language, array $lang) // STEP 4 - ADMIN USER DATA
610  {
611  echo '
612  <!-- YaWK Setup Helper -->
613  <script src="system/setup/validationHelper.js"></script>';
614  $this->step = 4;
615  // include database and settings class
616  if (!isset($db))
617  { // include database class
618  require_once('system/classes/db.php');
619  $db = new \YAWK\db();
620  }
621 
622  if (isset($_POST['ROOT_PATH']) && (!empty($_POST['ROOT_PATH'])))
623  {
624  // set dirprefix from form POST
625  $this->rootPath = trim($_POST['ROOT_PATH']);
626  // save dirprefix to db
627  \YAWK\settings::setSetting($db, "dirprefix", $this->rootPath, $lang);
628  }
629  else
630  {
631  $this->rootPath = \YAWK\sys::getBaseDir();
632  }
633 
634  if (isset($_POST['URL']) && (!empty($_POST['URL'])))
635  {
636  // check if user sent a proper URL
637  if(filter_var($_POST['URL'], FILTER_VALIDATE_URL))
638  { // remove spaces around the string
639  $this->url = trim($_POST['URL']);
640  // ensure that there is no trailing slash at the end
641  $this->url = rtrim($this->url, '/') . '';
642  // save website host (URL) setting to database
643  \YAWK\settings::setSetting($db, "host", $this->url, $lang);
644  \YAWK\settings::setSetting($db, "backendLogoText", $this->url, $lang);
645  }
646  else
647  { // FILTER FAILED - process anway, but throw warning afterwards.
648  // remove spaces around the string
649  $this->url = trim($_POST['URL']);
650  // ensure that there is no trailing slash at the end
651  $this->url = rtrim($this->url, '/') . '';
652  \YAWK\settings::setSetting($db, "host", $this->url, $lang);
653  \YAWK\settings::setSetting($db, "backendLogoText", $this->url, $lang);
654  \YAWK\alert::draw("warning", "$lang[FAULTY_URL]", "$lang[FAULTY_URL_SUBTEXT]", "", 5000);
655  }
656  }
657 
658  if (isset($_POST['TITLE']) && (!empty($_POST['TITLE'])))
659  {
660  \YAWK\settings::setSetting($db, "title", $_POST['TITLE'], $lang);
661  }
662 
663  if (isset($_POST['DESC']) && (!empty($_POST['DESC'])))
664  {
665  \YAWK\settings::setSetting($db, "globalmetatext", $_POST['DESC'], $lang);
666  }
667 
668  if (isset($language->currentLanguage))
669  {
670  \YAWK\settings::setSetting($db, "backendLanguage", $language->currentLanguage, $lang);
671  }
672 
673  echo"
674  <div class=\"row\">
675  <div class=\"col-md-7 text-justify\">
676  <h1>YaWK <small>$lang[INSTALLATION]</small></h1>
677  <h4><i class=\"fa fa-user-circle-o\"></i> &nbsp; $lang[STEP] $_POST[step]/5 <small>$lang[ACCOUNT_SETTINGS]</small></h4>
678  <hr><h4>$lang[USER] $lang[SETTINGS]</h4>
679  <label for=\"EMAIL\">$lang[EMAIL] <small><i>$lang[EMAIL_SUBTEXT]</i></small>
680  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_EMAIL]\"></i></small>
681  </label>
682  <input required type=\"text\" class=\"form-control\" name=\"EMAIL\" id=\"EMAIL\" placeholder=\"$setup[ADMIN_EMAIL]\">
683  <label for=\"USERNAME\">$lang[USERNAME] <small><i>$lang[USERNAME]</i></small>
684  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_ADMINUSER]\"></i></small>
685  </label>
686  <input required type=\"text\" class=\"form-control\" name=\"USERNAME\" id=\"USERNAME\" placeholder=\"$setup[ADMIN_USER]\" value=\"admin\">
687  <label for=\"PASSWORD\">$lang[PASSWORD] <small><i>$lang[PASSWORD]</i></small>
688  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_ADMINPASS]\"></i></small>
689  </label>
690  <input required type=\"password\" class=\"form-control\" name=\"PASSWORD\" id=\"PASSWORD\" placeholder=\"$setup[ADMIN_PASS]\">
691  <label for=\"PASSWORD2\">$lang[PASSWORD] <small><i>($lang[REPEAT])</i></small>
692  <small><i class=\"fa fa-question-circle-o text-info\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"$lang[I_ADMINPASS_CONFIRM]\"></i></small>
693  </label>
694  <input required type=\"password\" class=\"form-control\" name=\"PASSWORD2\" id=\"PASSWORD2\" placeholder=\"$setup[ADMIN_PASS]\">
695  <br>
696  <input type=\"hidden\" name=\"url\" value=\"$this->url\">
697  <input type=\"hidden\" name=\"rootPath\" value=\"$this->rootPath\">
698  <input type=\"hidden\" name=\"step\" value=\"5\">
699  <input type=\"hidden\" name=\"currentLanguage\" value=\"$language->currentLanguage\">
700  <button type=\"submit\" class=\"btn btn-success pull-right\"><small>$_POST[step]/5</small> &nbsp;$lang[NEXT_STEP] &nbsp;<i class=\"fa fa-arrow-right\"></i></button>
701  </div>
702  <div class=\"col-md-5 text-justify\">
703  <br><br>
704  <br><br>
705  <h4>$lang[ACCOUNT_NOTICE]</h4>
706  $lang[ACCOUNT_NOTICE_INFO]
707  <br><br><br>
708  <b>$lang[STEP5]</b><br>
709  </div>
710  </div>";
711  }
712 
713  /** @brief step 5 - save data, write .htaccess files and redirect to backend login - FIN
714  * @param array $setup installation settings
715  * @param object $language language object
716  * @param array $lang array language data array
717  * @author Daniel Retzl <[email protected]>
718  * @license https://opensource.org/licenses/MIT
719  */
720  public function step5(array $setup, $language, array $lang) // STEP 5 - save data, write .htaccess files and redirect to backend login - FIN
721  {
722  $this->step = 5;
723  // include database and settings class
724  if (!isset($db))
725  {
726  require_once('system/classes/db.php');
727  $db = new \YAWK\db();
728  }
729  if (isset($_POST['url']) && (!empty($_POST['url'])))
730  {
731  $this->url = $_POST['url'];
732  }
733  if (isset($_POST['rootPath']) && (!empty($_POST['rootPath'])))
734  {
735  $this->rootPath = $_POST['rootPath'];
736  }
737 
738  if (isset($_POST['EMAIL']) && (!empty($_POST['EMAIL'])))
739  {
740  \YAWK\settings::setSetting($db, "admin_email", $_POST['EMAIL'], $lang);
741  }
742  if (isset($_POST['USERNAME']) && (!empty($_POST['USERNAME'])))
743  {
744  if (\YAWK\user::create($db, $_POST['USERNAME'], $_POST['PASSWORD'], $_POST['PASSWORD2'], $_POST['EMAIL'], "", "", "", "", "", "", "", "", "", 0, 1, "Administrator", 5) === true)
745  {
746  // user successfully created
747  // final step: create .htaccess files
748  // write .htaccess file to /admin folder
749  if ($this->writeHtaccessFileToAdminFolder() === false)
750  {
751  $htaccessAdminStatus = 0;
752  // failed to write /admin/.htaccess - throw warning
753  \YAWK\alert::draw("warning", "$lang[HTACCESS_WRITE_FAILED_ADMIN]", "$lang[HTACCESS_WRITE_FAILED_ADMIN_SUBTEXT]", "", "");
754  }
755  else { $htaccessAdminStatus = 1; }
756 
757  // write .htaccess file to / root folder
758  if ($this->writeHtaccessFileToRootFolder() === false)
759  { $htaccessRootStatus = 0;
760  // failed to write .htaccess - throw warning
761  \YAWK\alert::draw("warning", "$lang[HTACCESS_WRITE_FAILED_ROOT]", "$lang[HTACCESS_WRITE_FAILED_ROOT_SUBTEXT]", "", "");
762  }
763  else { $htaccessRootStatus = 1; }
764 
765  $htStatus = $htaccessAdminStatus+$htaccessRootStatus;
766  if ($htStatus === 2)
767  {
768  if (unlink('setup.php'))
769  {
770  \YAWK\alert::draw("success", "$lang[INSTALL_COMPLETE]", "$lang[INSTALL_COMPLETE_SUBTEXT]", "", 3000);
771  \YAWK\sys::setTimeout("admin/index.php", 3000);
772  exit;
773  }
774  else
775  {
776  \YAWK\alert::draw("warning", "$lang[INSTALL_COMPLETE]", "$lang[SETUP_UNLINK_FAILED]", "", 5000);
777  \YAWK\sys::setTimeout("admin/index.php", 5000);
778  exit;
779  }
780  }
781  else
782  { // check which .htaccess file could not be written
783  if ($htaccessAdminStatus === 0)
784  { // admin file could not be written, throw error
785  \YAWK\alert::draw("warning", "$lang[HTACCESS_WRITE_FAILED_ADMIN]", "$lang[HTACCESS_WRITE_FAILED_ADMIN_SUBTEXT]", "", "");
786  exit;
787  }
788  if ($htaccessRootStatus === 0)
789  {
790  \YAWK\alert::draw("warning", "$lang[HTACCESS_WRITE_FAILED_ROOT]", "$lang[HTACCESS_WRITE_FAILED_ROOT_SUBTEXT]", "", "");
791  exit;
792  }
793  }
794 
795  // setup seems to be complete, remove setup indicator silently
796  @unlink($this->setupIndicator);
797  }
798  else
799  {
800  if (isset($_POST['step']) && (!empty($_POST['step']))) { $_POST['step']--; }
801  \YAWK\alert::draw("warning", "$lang[INSTALL_USERNAME_FAILED]", "$lang[INSTALL_USERNAME_FAILED_SUBTEXT]", "", 5000);
802  $this->step4($setup, $language, $lang);
803  exit;
804  }
805  }
806  }
807 
808 
809  /* GET + CHECK functions */
810 
811  /** @brief this function writes the .htaccess file to the admin/ folder
812  * @author Daniel Retzl <[email protected]>
813  * @license https://opensource.org/licenses/MIT
814  */
815  public function writeHtaccessFileToAdminFolder(): bool
816  {
817  $file = 'admin/.htaccess';
818  $host = $this->url;
819  $data = "
820 #Options +FollowSymlinks
821 Order allow,deny
822 Allow from all
823 Require all granted
824 
825 # custom error page
826 ErrorDocument 404 $host/content/errors/404.html
827 
828 RewriteEngine on
829 RewriteCond %{REQUEST_URI} /(.*).html
830 RewriteRule ^(.*).html$ \\index.php?include=$1
831 # Rewrite .html - no extension needed e.g. you can use http://www.yoursite/gallery instead of /gallery.html
832 RewriteRule ^([^\\.]+)$ \\index.php?page=$1 [NC,L]
833 
834 # off for tinymce
835 #RewriteRule ^(.*).htm$ \\index.php?include=$1
836 ";
837  if (is_writable($file))
838  { // folder is writeable, try to write file
839  if (file_put_contents($file, $data, LOCK_EX))
840  { // admin/.htaccess file successfully written
841  return true;
842  }
843  else
844  { // folder is writeable, but file could not be written
845  return false;
846  }
847  }
848  else
849  { // folder is not writeable, try to chmod it
850  if (chmod($file, 0664))
851  { // try again to write file
852  if (file_put_contents($file, $data, LOCK_EX))
853  { // file successfully written
854  return true;
855  }
856  else
857  { // unable to write file
858  return false;
859  }
860  }
861  else {
862  // unable to chmod folder
863  return false;
864  }
865  }
866  }
867 
868  /**
869  * @return bool
870  */
872  {
873  $host = $this->url;
874  // filename
875  $file = '.htaccess';
876  $data = '
877 # SEO settings
878 # to work correctly, you need +FollowSymLinks or at least +SymLinksIfOwnerMatch enabled.
879 # if you get an ERROR 500, try ifownermatch (slower) and/or ask you webhoster to enable mod_rewrite + symlinks
880 
881 #Options +FollowSymlinks
882 #Options +SymlinksIfOwnerMatch
883 DirectoryIndex index.php
884 Order allow,deny
885 Allow from all
886 
887 # custom error page
888 ErrorDocument 404 '.$host.'/content/errors/404.html
889 
890 # SEO settings
891 RewriteEngine On
892 RewriteBase '.$this->rootPath.'
893 RewriteCond %{REQUEST_URI} /(.*).html
894 # rewrite all .html files to index.php?include={filename}
895 RewriteRule ^(.*).html$ \index.php?include=$1 [NC,L]
896 # rewrite all .htm files to index.php?include={filename}
897 # if you wish to use tinymce, you need put a # in front of the next line
898 RewriteRule ^(.*).htm$ \index.php?include=$1 [NC,L]
899 # Allow Robots.txt to pass through
900 RewriteRule ^robots.txt - [L]
901 # Userpage Rewrite Rule
902 RewriteRule ^welcome/([^/]*)$ \index.php?signup=1 [NC,L]
903 RewriteRule ^users/([^/]*)$ \index.php?user=$1 [NC,L]
904 RewriteRule ^users([^/]*)$ \index.php?user=$1 [NC,L]
905 # Rewrite .html - no extension needed e.g. you can use http://www.yoursite/gallery instead of /gallery.html
906 RewriteRule ^([^\.]+)$ $1.html [NC,L]
907 # any other plugin...
908 # RewriteRule ^plugin([^/]*)$ \index.php?plugin=$1 [L]
909 
910 # CACHE + THREAD SETTINGS
911  <ifModule mod_headers.c>
912  Header set Connection keep-alive
913  Header set Access-Control-Allow-Origin "*"
914  </ifModule>
915 
916 # CACHE - STATIC CONTENT CACHING starts here
917 # required modules:
918 # mod_expires.so
919 # mod.gzip.c
920 # mod.deflate.c
921 # if caching does not work, or you get 500 - server error, check if the required module are loaded.
922 # in your httpd.conf look for the following line:
923 # #LoadModule expires_module modules/mod_expires.so -- uncomment it & restart server.
924 # if you cannot load the modules, comment out all lines til #END CACHING -- and it will work (w/o caching)
925  <IfModule mod_expires.c>
926  # Add correct content-type for fonts
927  AddType application/vnd.ms-fontobject .eot
928  AddType application/x-font-ttf .ttf
929  AddType application/x-font-opentype .otf
930  AddType application/x-font-woff .woff
931  AddType image/svg+xml .svg
932 
933  # enable cache
934  ExpiresActive On
935 
936  # default expire: 1 day
937  ExpiresDefault A86400
938 
939  # set cacheable items
940  ExpiresByType image/x-icon A2592000
941  ExpiresByType application/x-javascript A1209600
942  ExpiresByType text/css A1209600
943  ExpiresByType image/gif A1209600
944  ExpiresByType image/png A1209600
945  ExpiresByType image/jpeg A1209600
946  ExpiresByType text/plain A86400
947  ExpiresByType application/x-shockwave-flash A2592000
948  ExpiresByType video/x-flv A2592000
949  ExpiresByType application/pdf A2592000
950  ExpiresByType text/html A86400
951  # Add a far future Expires header for fonts
952  ExpiresByType application/vnd.ms-fontobject "access plus 1 year"
953  ExpiresByType application/x-font-ttf "access plus 1 year"
954  ExpiresByType application/x-font-opentype "access plus 1 year"
955  ExpiresByType application/x-font-woff "access plus 1 year"
956  ExpiresByType image/svg+xml "access plus 1 year"
957 
958 ## Set up caching on media files for 1 month
959 <FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav|swf)$">
960  ExpiresDefault A2592000
961  Header append Cache-Control "public"
962 </FilesMatch>
963 
964 ## Set up caching on images css and js files for 2 weeks
965 <FilesMatch "\.(gif|jpg|jpeg|png|js|css)$">
966  ExpiresDefault A1209600
967  Header append Cache-Control "public"
968 </FilesMatch>
969 
970 ## Set up 1 day caching on commonly updated files
971 <FilesMatch "\.(xml|txt|htm|html)$">
972  ExpiresDefault A86400
973  Header append Cache-Control "private, must-revalidate"
974 </FilesMatch>
975 
976 ## Force no caching for dynamic files
977 <FilesMatch "\.(php|cgi|pl)$">
978  ExpiresDefault A0
979  Header set Cache-Control "no-store, no-cache, must-revalidate, max-age=0"
980  Header set Pragma "no-cache"
981 </FilesMatch>
982 </IfModule>
983 
984 # BEGIN GZIP
985 # compress the output of html, xml, txt, css and js files
986 # mod_gzip compression (legacy, Apache 1.3)
987 <IfModule mod_gzip.c>
988  mod_gzip_on Yes
989  mod_gzip_dechunk Yes
990  mod_gzip_item_include file \.(html?|xml|txt|css|js)$
991  mod_gzip_item_include handler ^cgi-script$
992  mod_gzip_item_include mime ^text/.*
993  mod_gzip_item_include mime ^application/x-javascript.*
994  mod_gzip_item_exclude mime ^image/.*
995  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
996 </IfModule>
997  # END GZIP
998 
999  # DEFLATE compression
1000  # this deflates all zipped files
1001  <IfModule mod_deflate.so>
1002  # Set compression for: html,txt,xml,js,css,svg and otf, ttf and woff fonts
1003  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/xml application/xhtml+xml application/x-javascript application/x-font-ttf application/x-font-opentype image/svg+xml
1004  # Deactivate compression for buggy browsers
1005  BrowserMatch ^Mozilla/4 gzip-only-text/html
1006  BrowserMatch ^Mozilla/4.0[678] no-gzip
1007  BrowserMatch bMSIE !no-gzip !gzip-only-text/html
1008  # Set header information for proxies
1009  Header append Vary User-Agent
1010 </IfModule>
1011  # END DEFLATE
1012 # END CACHING ############################################
1013 
1014 # override max post size
1015 # php_value post_max_size 32M
1016 
1017 # override max upload file size
1018 # php_value upload_max_filesize 32M
1019 
1020  ';
1021  // write to file
1022  // using the flag LOCK_EX, to ensure safe writing on file
1023  if (is_writable($file))
1024  { // folder is writeable, try to write file
1025  if (file_put_contents($file, $data, LOCK_EX))
1026  { // admin/.htaccess file successfully written
1027  return true;
1028  }
1029  else
1030  { // folder is writeable, but file could not be written
1031  return false;
1032  }
1033  }
1034  else
1035  { // folder is not writeable, try to chmod it
1036  if (chmod($file, 0664))
1037  { // try again to write file
1038  if (file_put_contents($file, $data, LOCK_EX))
1039  { // file successfully written
1040  return true;
1041  }
1042  else
1043  { // unable to write file
1044  return false;
1045  }
1046  }
1047  else
1048  { // unable to chmod folder
1049  return false;
1050  }
1051  }
1052  }
1053 
1054  /** @brief check server requirements and set object params
1055  * @author Daniel Retzl <[email protected]>
1056  * @license https://opensource.org/licenses/MIT
1057  */
1058  public function checkServerRequirements()
1059  {
1060  $i = 0;
1062  //self::checkApacheVersion();
1063  self::checkZlib();
1065 
1066  // check PHP status
1067  if ($this->phpVersionStatus === "true")
1068  { // ok
1069  $this->serverRequirementCount++;
1070  $this->phpCheckIcon = "<i class=\"fa fa-check text-success\"></i>";
1071  }
1072  else
1073  { // PHP failed
1074  $this->phpCheckIcon = "<i class=\"fa fa-times text-danger\"></i>";
1075  $this->serverRequirementCount = 0;
1076  }
1077 
1078  // check zlib status
1079  if ($this->zlib === "true")
1080  { // ok
1081  $this->zlibCheckIcon = "<i class=\"fa fa-check text-success\"></i>";
1082  $this->serverRequirementCount++;
1083  }
1084  else
1085  { // zlib failed
1086  $this->zlibCheckIcon = "<i class=\"fa fa-times text-danger\"></i>";
1087  }
1088 
1089  // check modRewrite status
1090  if ($this->modRewriteStatus === "true")
1091  { // ok
1092  $this->modRewriteCheckIcon = "<i class=\"fa fa-check text-success\"></i>";
1093  $this->serverRequirementCount++;
1094  }
1095  else
1096  { // failed
1097  $this->modRewriteCheckIcon = "<i class=\"fa fa-times text-danger\"></i>";
1098  }
1099 
1100  // check if
1101  if ($this->serverRequirementCount == 0)
1102  { // PHP failed
1103  $this->serverRequirements = false;
1104  }
1105  else
1106  { // Installation possible
1107  $this->serverRequirements = true;
1108  }
1109  }
1110 
1111  /** Check supported languages and build options for select field
1112  * @author Daniel Retzl <[email protected]>
1113  * @license https://opensource.org/licenses/MIT
1114  */
1115  public function getLanguageSelectOptions($language, $lang): string
1116  {
1117  $selectOptions = '';
1118 
1119  $selectOptions .= "<option value=\"\">$lang[SELECT_LANGUAGE]</option>";
1120  foreach ($language->supportedLanguages AS $supported)
1121  {
1122  $supportedLanguage = substr($supported, 0, 2);
1123  if ($language->currentLanguage === "$supportedLanguage")
1124  {
1125  // $selectOptions .= "<option value=\"$supportedLanguage\" selected>$supported</option>
1126  $selectOptions .= "<option value=\"$supported\" selected>$supported</option>
1127  ";
1128  }
1129  else
1130  {
1131  // $selectOptions .= "<option value=\"$supportedLanguage\">$supported</option>
1132  $selectOptions .= "<option value=\"$supported\">$supported</option>
1133  ";
1134  }
1135  }
1136  return $selectOptions;
1137  }
1138 
1139  /** @brief Check if php version is bigger than required
1140  * @author Daniel Retzl <[email protected]>
1141  * @license https://opensource.org/licenses/MIT
1142  * @return bool
1143  */
1144  public function checkPhpVersion(): bool
1145  { // check if php version is high enough
1146  if (version_compare(phpversion(), $this->phpVersionRequired, '<')) {
1147  // php version isn't high enough
1148  $this->phpVersionStatus = "false";
1149  return false;
1150  }
1151  else
1152  { // ok, PHP fits.
1153  $this->phpVersionStatus = "true";
1154  return true;
1155  }
1156  }
1157 
1158  /**
1159  * @brief Check if zlib is available
1160  * @return bool
1161  */
1162  public function checkZlib(): bool
1163  { // check if zlib is installed
1164  if(extension_loaded('zlib'))
1165  { // zlin loaded
1166  $this->zlib = "true";
1167  return true;
1168  }
1169  else
1170  { // zlib not loaded
1171  $this->zlib = "false";
1172  return false;
1173  }
1174  }
1175 
1176  /**
1177  * @brief Check if mod_rewrite is available
1178  * @details <p>Note: this does not work on some restricted configured shared hosting providers.</p>
1179  * @return bool
1180  */
1181  public function checkModRewrite(): bool
1182  { // check if mod_rewrite is in module list
1183  // note: this does not work on some restricted configured shared hosting providers.
1184  // even when mod_rewrite works, sometimes the identification fails due configuration restrictions.
1185  if(function_exists('apache_get_modules') && in_array('mod_rewrite',apache_get_modules()))
1186  { // apache!
1187  $this->modRewriteStatus = "true";
1188  return true;
1189  }
1190  // IIS ?
1191  else if (isset($_SERVER['IIS_UrlRewriteModule']))
1192  { // IIS. meh.
1193  $this->modRewriteStatus = "true";
1194  return true;
1195  }
1196  else
1197  { // anyway - check if mod_rewrite is loaded
1198  if (extension_loaded('mod_rewrite'))
1199  { // mod_rewrite loaded
1200  $this->modRewriteStatus = "true";
1201  return true;
1202  }
1203  else
1204  { // mod_rewrite not loaded
1205  $this->modRewriteStatus = "false";
1206  return false;
1207  }
1208  }
1209  }
1210 
1211  /**
1212  * @brief Draw the installer's footer with links to yawk.io and github
1213  */
1214  public function footer()
1215  {
1216  echo "<footer class=\"animated fadeIn\" style=\"position: relative; bottom: -8em; width: 100%; height: auto; background-color: #ebebeb;\">
1217  <div class=\"container-fluid\">
1218  <div class=\"row\">
1219  <div class=\"col-md-12 text-center small\">
1220  <h5 class=\"text-muted\"><small><a href=\"http://yawk.io\" title=\"Official YaWK Website\" target=\"_blank\"><b>Y</b>et <b>a</b>nother <b>W</b>eb<b>K</b>it</a> on <b>
1221  <a href=\"https://github.com/YaWK/yawk.io\" title=\"visit, fork or star YaWK on GitHub\" target=\"_blank\">GitHub</a></b></small>
1222  - <small>v $this->yawkVersion
1223  </h5>
1224  </div>
1225  </div>
1226  </div>
1227  </footer>";
1228  }
1229 
1230  /**
1231  * @brief Call the footer and end the html body and file
1232  */
1233  function __destruct()
1234  {
1235  $this->footer();
1236  echo '
1237 
1238 </div>
1239  </form>
1240  <script>
1241  $(document).ready(function() {
1242  $(function () {
1243  $("[data-toggle=\'tooltip\']").tooltip();
1244  });
1245  });
1246  </script>
1247  </body>
1248 </html>';
1249  }
1250  } // end class installer
1251 } // end namespace
print $lang['FILEMAN_UPLOAD']
$data
Definition: stats.php:78
die
Definition: block-user.php:27
static draw($type, $title, $text, $redirect, $delay)
Definition: alert.php:30
This class handles the setup / installation process.
Definition: installer.php:9
__construct()
installer constructor. build and return the html head
Definition: installer.php:59
checkZlib()
Check if zlib is available.
Definition: installer.php:1162
step4(array $setup, $language, array $lang)
step 4 - save project settings and draw a form to enter user data (email, name, password....
Definition: installer.php:609
__destruct()
Call the footer and end the html body and file.
Definition: installer.php:1233
getLanguageSelectOptions($language, $lang)
Definition: installer.php:1115
step2(array $setup, $language, array $lang)
step 2 - DB DATA + SERVER REQUIREMENTS
Definition: installer.php:356
step3(array $setup, $language, array $lang)
step 3 - write db-config, check + import db connection If all went good, a form with project settings...
Definition: installer.php:483
resetInstallation($language, $lang)
RESET - RESET DATABASE xor CORRUPT INSTALLATION.
Definition: installer.php:278
init()
Initialize the installer.
Definition: installer.php:109
writeHtaccessFileToRootFolder()
Definition: installer.php:871
checkServerRequirements()
check server requirements and set object params
Definition: installer.php:1058
step1($language, array $lang)
step 1 - SELECT LANGUAGE
Definition: installer.php:321
footer()
Draw the installer's footer with links to yawk.io and github.
Definition: installer.php:1214
checkPhpVersion()
Check if php version is bigger than required.
Definition: installer.php:1144
checkModRewrite()
Check if mod_rewrite is available.
Definition: installer.php:1181
writeHtaccessFileToAdminFolder()
this function writes the .htaccess file to the admin/ folder
Definition: installer.php:815
setup($language, $lang)
Start the setup process.
Definition: installer.php:200
step5(array $setup, $language, array $lang)
step 5 - save data, write .htaccess files and redirect to backend login - FIN
Definition: installer.php:720
The language class - support multilingual backend.
Definition: language.php:17
static setSetting($db, $property, $value, $lang)
Set value for property into settings database.
Definition: settings.php:502
static setTimeout($location, $wait)
set a timeout and force page reload via JS
Definition: sys.php:864
static getBaseDir()
Return current base directory.
Definition: sys.php:304
$result
Definition: email-send.php:137
exit
$sql
Definition: message-new.php:32
This class serves methods to create backup from files.
Definition: AdminLTE.php:2
$host
Definition: page-edit.php:65
$i