Newer
Older
<?php
/**
* Copyright Maarch since 2008 under licence GPLv3.
* See LICENCE.txt file at the root folder for more details.
* This file is part of Maarch software.
*/
/**
* @brief Installer Controller
*
* @author dev@maarch.org
*/
namespace SrcCore\controllers;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\DatabaseModel;
use SrcCore\models\DatabasePDO;
class InstallerController
{
public function getPrerequisites(Request $request, Response $response)
{
$phpVersion = phpversion();
$phpVersionValid = (version_compare(PHP_VERSION, '7.2') >= 0);
exec('whereis unoconv', $output, $return);
$output = explode(':', $output[0]);
$unoconv = !empty($output[1]);
$pdoPgsql = @extension_loaded('pdo_pgsql');
$pgsql = @extension_loaded('pgsql');
$mbstring = @extension_loaded('mbstring');
$fileinfo = @extension_loaded('fileinfo');
$gd = @extension_loaded('gd');
$imagick = @extension_loaded('imagick');
$imap = @extension_loaded('imap');
$xsl = @extension_loaded('xsl');
$gettext = @extension_loaded('gettext');
$xmlrpc = @extension_loaded('xmlrpc');
$curl = @extension_loaded('curl');
$zip = @extension_loaded('zip');
$writable = is_writable('.') && is_readable('.');
$displayErrors = (ini_get('display_errors') == '1');
$errorReporting = (ini_get('error_reporting') >= 22519);
exec('whereis netcat', $outputNetcat, $returnNetcat);
$outputNetcat = explode(':', $outputNetcat[0]);
exec('whereis nmap', $outputNmap, $returnNmap);
$outputNmap = explode(':', $outputNmap[0]);
$netcatOrNmap = !empty($outputNetcat[1]) || !empty($outputNmap[1]);
$prerequisites = [
'phpVersion' => $phpVersion,
'unoconv' => $unoconv,
'pdoPgsql' => $pdoPgsql,
'pgsql' => $pgsql,
'mbstring' => $mbstring,
'fileinfo' => $fileinfo,
'gd' => $gd,
'imagick' => $imagick,
'imap' => $imap,
'xsl' => $xsl,
'gettext' => $gettext,
'xmlrpc' => $xmlrpc,
'curl' => $curl,
'zip' => $zip,
'writable' => $writable,
'displayErrors' => $displayErrors,
'errorReporting' => $errorReporting,
'netcatOrNmap' => $netcatOrNmap
];
return $response->withJson(['prerequisites' => $prerequisites]);
}
public function checkDatabaseConnection(Request $request, Response $response)
{
$queryParams = $request->getQueryParams();
if (!Validator::stringType()->notEmpty()->validate($queryParams['server'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body server is empty or not a string']);
} elseif (!Validator::intVal()->notEmpty()->validate($queryParams['port'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body port is empty or not an integer']);
} elseif (!Validator::stringType()->notEmpty()->validate($queryParams['user'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body user is empty or not a string']);
} elseif (!Validator::stringType()->notEmpty()->validate($queryParams['password'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body password is empty or not a string']);
$connected = false;
$name = 'postgres';
if (!empty($queryParams['name'])) {
$name = $queryParams['name'];
$connection = "host={$queryParams['server']} port={$queryParams['port']} user={$queryParams['user']} password={$queryParams['password']} dbname={$queryParams['name']}";
$connected = @pg_connect($connection);
if (!$connected) {
$name = 'postgres';
$connection = "host={$queryParams['server']} port={$queryParams['port']} user={$queryParams['user']} password={$queryParams['password']} dbname=postgres";
if (!@pg_connect($connection)) {
return $response->withStatus(400)->withJson(['errors' => 'Database connection failed']);
}
$request = "select datname from pg_database where datname = '{$name}'";
$result = @pg_query($request);
return $response->withStatus(400)->withJson(['errors' => 'Database request failed']);
if (!empty($queryParams['name']) && !$connected) {
return $response->withJson(['success' => 'First connection failed']);
return $response->withStatus(204);
}
public function createCustom(Request $request, Response $response)
{
$body = $request->getParsedBody();
if (!Validator::stringType()->notEmpty()->validate($body['customId'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body customId is empty or not a string']);
if (is_dir("custom/{$body['customId']}")) {
return $response->withStatus(400)->withJson(['errors' => 'Custom with this name already exists']);
} elseif (!@mkdir("custom/{$body['customId']}/apps/maarch_entreprise/xml", 0755, true)) {
return $response->withStatus(400)->withJson(['errors' => 'Custom folder creation failed']);
}
if (!is_file("custom/custom.json")) {
$fp = fopen('custom/custom.json', 'w');
fwrite($fp, json_encode([], JSON_PRETTY_PRINT));
fclose($fp);
}
$customFile = CoreConfigModel::getJsonLoaded(['path' => 'custom/custom.json']);
$customFile[] = [
];
$fp = fopen('custom/custom.json', 'w');
fwrite($fp, json_encode($customFile, JSON_PRETTY_PRINT));
fclose($fp);
$jsonFile = [
'config' => [
'lang' => $body['lang'] ?? 'fr',
'applicationName' => $body['applicationName'] ?? $body['customId'],
'cookieTime' => 10080,
'timezone' => 'Europe/Paris'
],
'database' => []
];
$fp = fopen("custom/{$body['customId']}/apps/maarch_entreprise/xml/config.json", 'w');
fwrite($fp, json_encode($jsonFile, JSON_PRETTY_PRINT));
fclose($fp);
$cmd = 'ln -s ' . realpath('.') . "/ {$body['customId']}";
return $response->withStatus(204);
}
public function createDatabase(Request $request, Response $response)
{
$body = $request->getParsedBody();
if (!Validator::stringType()->notEmpty()->validate($body['server'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body server is empty or not a string']);
} elseif (!Validator::intVal()->notEmpty()->validate($body['port'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body port is empty or not an integer']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['user'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body user is empty or not a string']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['password'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body password is empty or not a string']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['name'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body name is empty or not a string']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['customId'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body customId is empty or not a string']);
if (empty($body['alreadyCreated'])) {
$connection = "host={$body['server']} port={$body['port']} user={$body['user']} password={$body['password']} dbname=postgres";
if (!@pg_connect($connection)) {
return $response->withStatus(400)->withJson(['errors' => 'Database connection failed']);
}
$request = "CREATE DATABASE \"{$body['name']}\" WITH TEMPLATE template0 ENCODING = 'UTF8'";
$result = pg_query($request);
if (!$result) {
return $response->withStatus(400)->withJson(['errors' => 'Database creation failed']);
}
@pg_query("ALTER DATABASE '{$body['name']}' SET DateStyle =iso, dmy");
pg_close();
}
$options = [
\PDO::ATTR_PERSISTENT => true,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_CASE => \PDO::CASE_NATURAL
];
$dsn = "pgsql:host={$body['server']};port={$body['port']};dbname={$body['name']}";
$db = new \PDO($dsn, $body['user'], $body['password'], $options);
$fileContent = @file_get_contents('sql/structure.sql');
if (!$fileContent) {
return $response->withStatus(400)->withJson(['errors' => 'Cannot read structure.sql']);
}
$result = $db->exec($fileContent);
if ($result === false) {
return $response->withStatus(400)->withJson(['errors' => 'Request failed : run structure.sql']);
}
if (!empty($body['data'])) {
$fileContent = @file_get_contents("sql/{$body['data']}.sql");
if (!$fileContent) {
return $response->withStatus(400)->withJson(['errors' => "Cannot read {$body['data']}.sql"]);
}
$result = $db->exec($fileContent);
if ($result === false) {
return $response->withStatus(400)->withJson(['errors' => "Request failed : run {$body['data']}.sql"]);
}
}
$configFile = CoreConfigModel::getJsonLoaded(['path' => "custom/{$body['customId']}/apps/maarch_entreprise/xml/config.json"]);
$configFile['database'] = [
[
"server" => $body['server'],
"port" => $body['port'],
"type" => 'POSTGRESQL',
"name" => $body['name'],
"user" => $body['user'],
"password" => $body['password']
]
];
$fp = fopen("custom/{$body['customId']}/apps/maarch_entreprise/xml/config.json", 'w');
fwrite($fp, json_encode($configFile, JSON_PRETTY_PRINT));
fclose($fp);
return $response->withStatus(204);
}
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
public function createDocservers(Request $request, Response $response)
{
$body = $request->getParsedBody();
if (!Validator::stringType()->notEmpty()->validate($body['path'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body path is empty or not a string']);
} elseif (!Validator::stringType()->notEmpty()->validate($body['customId'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body customId is empty or not a string']);
} elseif (!is_dir($body['path'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body path does not exist']);
} elseif (!is_writable($body['path'])) {
return $response->withStatus(400)->withJson(['errors' => 'Body path is not writable']);
}
$body['path'] = rtrim($body['path'], '/');
$docservers = [
'AI' => 'ai',
'RESOURCES' => 'resources',
'ATTACHMENTS' => 'attachments',
'CONVERT_RESOURCES' => 'convert_resources',
'CONVERT_ATTACH' => 'convert_attachments',
'TNL_RESOURCES' => 'thumbnails_resources',
'TNL_ATTACHMENTS' => 'thumbnails_attachments',
'FULLTEXT_RESOURCES' => 'fulltext_resources',
'FULLTEXT_ATTACHMENTS' => 'fulltext_attachments',
'TEMPLATES' => 'templates',
'ARCHIVETRANSFER' => 'archive_transfer',
'ACKNOWLEDGEMENT_RECEIPTS' => 'acknowledgement_receipts'
];
foreach ($docservers as $docserver) {
if (!@mkdir("{$body['path']}/{$body['customId']}/{$docserver}", 0755, true)) {
return $response->withStatus(400)->withJson(['errors' => "Docserver folder creation failed for path : {$body['path']}/{$body['customId']}/{$docserver}"]);
}
}
$templatesPath = "{$body['path']}/{$body['customId']}/templates/0000";
if (!@mkdir($templatesPath, 0755, true)) {
return $response->withJson(['success' => "Docservers created but templates folder creation failed"]);
}
$templatesToCopy = scandir('install/templates/0000');
foreach ($templatesToCopy as $templateToCopy) {
if ($templateToCopy == '.' || $templateToCopy == '..') {
continue;
}
copy("install/templates/0000/{$templateToCopy}", "{$templatesPath}/{$templateToCopy}");
}
DatabasePDO::reset();
new DatabasePDO(['customId' => $body['customId']]);
DatabaseModel::update([
'table' => 'docservers',
'postSet' => ['path_template' => "replace(path_template, '/opt/maarch/docservers', '{$body['path']}/{$body['customId']}')"],
'where' => ['1 = 1']
]);
return $response->withStatus(204);
}