Skip to content

Commit 74116cb

Browse files
committed
Refactor webapps structure and implement prestashop installer
1 parent 9d81eab commit 74116cb

File tree

7 files changed

+383
-332
lines changed

7 files changed

+383
-332
lines changed

web/add/webapp/Hestia.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
class HestiaApp {
3+
4+
protected const TMPDIR_DOWNLOADS="/tmp/hestia-webapp";
5+
6+
public function __construct() {
7+
mkdir(self::TMPDIR_DOWNLOADS);
8+
}
9+
10+
public function run(string $cmd, $args, &$cmd_result=null) : bool {
11+
$cli_script = HESTIA_CMD . '/' . basename($cmd);
12+
$cli_arguments = '';
13+
14+
if (!empty($args) && is_array($args)) {
15+
foreach ($args as $arg) {
16+
$cli_arguments .= escapeshellarg($arg) . ' ';
17+
}
18+
} else {
19+
$cli_arguments = escapeshellarg($args);
20+
}
21+
22+
exec ($cli_script . ' ' . $cli_arguments, $output, $exit_code);
23+
24+
$result['code'] = $exit_code;
25+
$result['args'] = $cli_arguments;
26+
$result['raw'] = $output;
27+
$result['text'] = implode( PHP_EOL, $output);
28+
$result['json'] = json_decode($result['text'], true);
29+
$cmd_result = (object)$result;
30+
31+
return ($exit_code === 0);
32+
}
33+
34+
public function runUser(string $cmd, $args, &$cmd_result=null) : bool {
35+
if (!empty($args) && is_array($args)) {
36+
array_unshift($args, $this->user());
37+
}
38+
else {
39+
$args = [$this->user(), $args];
40+
}
41+
return $this->run($cmd, $args, $cmd_result);
42+
}
43+
44+
// Logged in user
45+
public function realuser() : string {
46+
return $_SESSION['user'];
47+
}
48+
49+
// Effective user
50+
public function user() : string {
51+
$user = $this->realuser();
52+
if ($user == 'admin' && !empty($_SESSION['look'])) {
53+
$user = $_SESSION['look'];
54+
}
55+
56+
if(strpos($user, DIRECTORY_SEPARATOR) !== false) {
57+
throw new Exception("illegal characters in username");
58+
}
59+
return $user;
60+
}
61+
62+
public function userOwnsDomain(string $domain) : bool {
63+
return $this->runUser('v-list-web-domain', [$domain, 'json']);
64+
}
65+
66+
public function databaseAdd(string $dbname, string $dbuser, string $dbpass) {
67+
$v_password = tempnam("/tmp","hst");
68+
$fp = fopen($v_password, "w");
69+
fwrite($fp, $dbpass."\n");
70+
fclose($fp);
71+
$status = $this->runUser('v-add-database', [$dbname, $dbuser, $v_password]);
72+
unlink($v_password);
73+
return $status;
74+
}
75+
76+
public function getWebDomainIp(string $domain) {
77+
$this->runUser('v-list-web-domain', [$domain, 'json'], $result);
78+
$ip = $result->json[$domain]['IP'];
79+
return filter_var($ip, FILTER_VALIDATE_IP);
80+
}
81+
82+
public function getWebDomainPath(string $domain) {
83+
return join_paths("/home", $this->user() , "/web", $domain);
84+
}
85+
86+
public function downloadUrl(string $src, $path=null, &$result=null) {
87+
if (strpos($src,'http://') !== 0 &&
88+
strpos($src,'https://')!== 0 ) {
89+
return false;
90+
}
91+
92+
exec("/usr/bin/wget --tries 3 -nv " . escapeshellarg($src). " -P " . escapeshellarg(self::TMPDIR_DOWNLOADS) . ' 2>&1', $output, $return_var);
93+
if ($return_var !== 0) {
94+
return false;
95+
}
96+
97+
if(!preg_match('/URL:\s*(.+?)\s*\[(.+?)\]\s*->\s*"(.+?)"/', implode(PHP_EOL, $output), $matches)) {
98+
return false;
99+
}
100+
101+
if(empty($matches) || count($matches) != 4) {
102+
return false;
103+
}
104+
105+
$status['url'] = $matches[1];
106+
$status['file'] = $matches[3];
107+
$result = (object)$status;
108+
return true;
109+
}
110+
111+
public function archiveExtract(string $src, string $path, $skip_components=null) {
112+
113+
if (empty($path)) {
114+
throw new Exception("Error extracting archive: missing target folder");
115+
}
116+
117+
if (file_exists($src)) {
118+
$archive_file = $src;
119+
} else {
120+
if( !$this->downloadUrl($src, null, $download_result) ) {
121+
throw new Exception("Error downloading archive");
122+
}
123+
$archive_file = $download_result->file;
124+
}
125+
$status = $this->runUser('v-extract-fs-archive', [ $archive_file, $path, null, $skip_components]);
126+
unlink($download_result->file);
127+
return $status;
128+
}
129+
130+
public function saveTempFile(string $data) {
131+
$tmp_file = tempnam("/tmp","hst");
132+
chmod($tmp_file, 0644);
133+
134+
if (file_put_contents($tmp_file, $data) > 0) {
135+
return $tmp_file;
136+
}
137+
return false;
138+
}
139+
}

web/add/webapp/index.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
[ 'name'=>'Drupal', 'group'=>'cms', 'enabled'=>false,'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/drupal-thumb.png' ],
3636
[ 'name'=>'Joomla', 'group'=>'cms', 'enabled'=>false,'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/joomla-thumb.png' ],
3737

38-
[ 'name'=>'Opencart', 'group'=>'ecommerce', 'enabled'=>true, 'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/opencart-thumb.png' ],
39-
[ 'name'=>'Prestashop', 'group'=>'ecommerce', 'enabled'=>false, 'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/prestashop-thumb.png' ],
38+
[ 'name'=>'Opencart', 'group'=>'ecommerce', 'enabled'=>true, 'version'=>'3.0.3.2', 'thumbnail'=>'/images/webapps/opencart-thumb.png' ],
39+
[ 'name'=>'Prestashop', 'group'=>'ecommerce', 'enabled'=>true, 'version'=>'1.7.6.0', 'thumbnail'=>'/images/webapps/prestashop-thumb.png' ],
4040
[ 'name'=>'Magento', 'group'=>'ecommerce', 'enabled'=>false, 'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/magento-thumb.png' ],
4141

4242
[ 'name'=>'Laravel', 'group'=>'starter', 'enabled'=>false, 'version'=>'1.2.3', 'thumbnail'=>'/images/webapps/laravel-thumb.png' ],

0 commit comments

Comments
 (0)