44
55namespace Hestia \System ;
66
7- class HestiaApp {
8-
7+ class HestiaApp
8+ {
99 protected const TMPDIR_DOWNLOADS ="/tmp/hestia-webapp " ;
10+ protected $ phpsupport = false ;
1011
11- public function __construct () {
12+ public function __construct ()
13+ {
1214 @mkdir (self ::TMPDIR_DOWNLOADS );
1315 }
1416
15- public function run (string $ cmd , $ args , &$ cmd_result =null ) : bool
17+ public function run (string $ cmd , $ args , &$ cmd_result =null ): bool
1618 {
1719 $ cli_script = HESTIA_CMD . '/ ' . basename ($ cmd );
1820 $ cli_arguments = '' ;
@@ -25,19 +27,24 @@ public function run(string $cmd, $args, &$cmd_result=null) : bool
2527 $ cli_arguments = escapeshellarg ($ args );
2628 }
2729
28- exec ($ cli_script . ' ' . $ cli_arguments . ' 2>&1 ' , $ output , $ exit_code );
30+ exec ($ cli_script . ' ' . $ cli_arguments . ' 2>&1 ' , $ output , $ exit_code );
2931
3032 $ result ['code ' ] = $ exit_code ;
3133 $ result ['args ' ] = $ cli_arguments ;
3234 $ result ['raw ' ] = $ output ;
33- $ result ['text ' ] = implode ( PHP_EOL , $ output );
35+ $ result ['text ' ] = implode (PHP_EOL , $ output );
3436 $ result ['json ' ] = json_decode ($ result ['text ' ], true );
3537 $ cmd_result = (object )$ result ;
36-
38+ if ($ exit_code > 0 ) {
39+ //log error message in nginx-error.log
40+ trigger_error ($ result ['text ' ]);
41+ //throw exception if command fails
42+ throw new \Exception ($ result ['text ' ]);
43+ }
3744 return ($ exit_code === 0 );
3845 }
3946
40- public function runUser (string $ cmd , $ args , &$ cmd_result =null ) : bool
47+ public function runUser (string $ cmd , $ args , &$ cmd_result =null ): bool
4148 {
4249 if (!empty ($ args ) && is_array ($ args )) {
4350 array_unshift ($ args , $ this ->user ());
@@ -53,13 +60,13 @@ public function installComposer($version)
5360
5461 $ signature = implode (PHP_EOL , $ output );
5562 if (empty ($ signature )) {
56- throw new \Exception ("Error reading composer signature " );
63+ throw new \Exception ("Error reading composer signature " );
5764 }
5865
5966 $ composer_setup = self ::TMPDIR_DOWNLOADS . DIRECTORY_SEPARATOR . 'composer-setup- ' . $ signature . '.php ' ;
6067
6168 exec ("wget https://getcomposer.org/installer --quiet -O " . escapeshellarg ($ composer_setup ), $ output , $ return_code );
62- if ($ return_code !== 0 ) {
69+ if ($ return_code !== 0 ) {
6370 throw new \Exception ("Error downloading composer " );
6471 }
6572
@@ -69,33 +76,34 @@ public function installComposer($version)
6976 }
7077
7178 $ install_folder = $ this ->getUserHomeDir () . DIRECTORY_SEPARATOR . '.composer ' ;
72-
79+
7380 if (!file_exists ($ install_folder )) {
7481 exec (HESTIA_CMD .'v-rebuild-user ' .$ this -> user (), $ output , $ return_code );
75- if ($ return_code !== 0 ){
82+ if ($ return_code !== 0 ) {
7683 throw new \Exception ("Unable to rebuild user " );
7784 }
7885 }
79-
86+
8087 $ this ->runUser ('v-run-cli-cmd ' , ["/usr/bin/php " , $ composer_setup , "--quiet " , "--install-dir= " .$ install_folder , "--filename=composer " , "-- $ version " ], $ status );
8188
8289 unlink ($ composer_setup );
8390
84- if ($ status ->code !== 0 ) {
91+ if ($ status ->code !== 0 ) {
8592 throw new \Exception ("Error installing composer " );
8693 }
8794 }
88-
89- public function updateComposer ($ version ){
95+
96+ public function updateComposer ($ version )
97+ {
9098 $ this ->runUser ('v-run-cli-cmd ' , ["composer " , "selfupdate " ,"-- $ version " ]);
9199 }
92100
93- public function runComposer ($ args , &$ cmd_result =null ,$ version =1 ) : bool
101+ public function runComposer ($ args , &$ cmd_result =null , $ version =1 ): bool
94102 {
95103 $ composer = $ this ->getUserHomeDir () . DIRECTORY_SEPARATOR . '.composer ' . DIRECTORY_SEPARATOR . 'composer ' ;
96- if (!is_file ($ composer )) {
104+ if (!is_file ($ composer )) {
97105 $ this ->installComposer ($ version );
98- }else {
106+ } else {
99107 $ this ->updateComposer ($ version );
100108 }
101109
@@ -108,21 +116,34 @@ public function runComposer($args, &$cmd_result=null,$version=1) : bool
108116 return $ this ->runUser ('v-run-cli-cmd ' , $ args , $ cmd_result );
109117 }
110118
119+ public function runWp ($ args , &$ cmd_result =null ): bool
120+ {
121+ $ wp = $ this ->getUserHomeDir () . DIRECTORY_SEPARATOR . '.wp ' . DIRECTORY_SEPARATOR . 'wp ' ;
122+ if (!is_file ($ wp )) {
123+ $ this -> runUser ('v-add-user-wp-cli ' );
124+ } else {
125+ $ this ->runUser ('v-run-cli-cmd ' , [$ wp , 'cli ' , 'update ' ]);
126+ }
127+ array_unshift ($ args , $ wp );
128+
129+ return $ this ->runUser ('v-run-cli-cmd ' , $ args , $ cmd_result );
130+ }
131+
111132 // Logged in user
112- public function realuser () : string
133+ public function realuser (): string
113134 {
114135 return $ _SESSION ['user ' ];
115136 }
116137
117138 // Effective user
118- public function user () : string
139+ public function user (): string
119140 {
120141 $ user = $ this ->realuser ();
121142 if ($ _SESSION ['userContext ' ] === 'admin ' && !empty ($ _SESSION ['look ' ])) {
122143 $ user = $ _SESSION ['look ' ];
123144 }
124145
125- if (strpos ($ user , DIRECTORY_SEPARATOR ) !== false ) {
146+ if (strpos ($ user , DIRECTORY_SEPARATOR ) !== false ) {
126147 throw new \Exception ("illegal characters in username " );
127148 }
128149 return $ user ;
@@ -134,25 +155,65 @@ public function getUserHomeDir()
134155 return $ info ['dir ' ];
135156 }
136157
137- public function userOwnsDomain (string $ domain ) : bool
158+ public function userOwnsDomain (string $ domain ): bool
138159 {
139160 return $ this ->runUser ('v-list-web-domain ' , [$ domain , 'json ' ]);
140161 }
141162
142- public function databaseAdd (string $ dbname , string $ dbuser , string $ dbpass )
163+ public function databaseAdd (string $ dbname , string $ dbuser , string $ dbpass, string $ charset = ' utf8mb4 ' )
143164 {
144- $ v_password = tempnam ("/tmp " ,"hst " );
165+ $ v_password = tempnam ("/tmp " , "hst " );
145166 $ fp = fopen ($ v_password , "w " );
146167 fwrite ($ fp , $ dbpass ."\n" );
147168 fclose ($ fp );
148- $ status = $ this ->runUser ('v-add-database ' , [$ dbname , $ dbuser , $ v_password ]);
169+ $ status = $ this ->runUser ('v-add-database ' , [$ dbname , $ dbuser , $ v_password, ' mysql ' , ' localhost ' , $ charset ]);
149170 unlink ($ v_password );
150171 return $ status ;
151172 }
152-
153- public function changeWebTemplate (string $ domain , string $ template ){
173+
174+ public function changeWebTemplate (string $ domain , string $ template )
175+ {
154176 $ status = $ this ->runUser ('v-change-web-domain-tpl ' , [$ domain , $ template ]);
155- }
177+ }
178+ public function changeBackendTemplate (string $ domain , string $ template )
179+ {
180+ $ status = $ this ->runUser ('v-change-web-domain-backend-tpl ' , [$ domain , $ template ]);
181+ }
182+
183+ public function listSuportedPHP ()
184+ {
185+ if (!$ this -> phpsupport ) {
186+ $ status = $ this -> run ('v-list-sys-php ' , 'json ' , $ result );
187+ $ this -> phpsupport = $ result -> json ;
188+ }
189+ return $ this -> phpsupport ;
190+ }
191+
192+ /*
193+ Return highest available supported php version
194+ Eg: Package requires: 7.3 or 7.4 and system has 8.0 and 7.4 it will return 7.4
195+ Package requires: 8.0 or 8.1 and system has 8.0 and 7.4 it will return 8.0
196+ Package requires: 7.4 or 8.0 and system has 8.0 and 7.4 it will return 8.0
197+ If package isn't supported by the available php version false will returned
198+ */
199+ public function getSupportedPHP ($ support )
200+ {
201+ $ versions = $ this -> listSuportedPHP ();
202+ $ supported = false ;
203+ $ supported_versions = array ();
204+
205+ foreach ($ versions as $ version ) {
206+ if (in_array ($ version , $ support )) {
207+ $ supported = true ;
208+ $ supported_versions [] = $ version ;
209+ }
210+ }
211+ if ($ supported ) {
212+ return $ supported_versions [count ($ supported_versions ) - 1 ];
213+ } else {
214+ return false ;
215+ }
216+ }
156217
157218 public function getWebDomainIp (string $ domain )
158219 {
@@ -163,13 +224,13 @@ public function getWebDomainIp(string $domain)
163224
164225 public function getWebDomainPath (string $ domain )
165226 {
166- return Util::join_paths ( $ this ->getUserHomeDir () , "web " , $ domain );
227+ return Util::join_paths ($ this ->getUserHomeDir (), "web " , $ domain );
167228 }
168229
169230 public function downloadUrl (string $ src , $ path =null , &$ result =null )
170231 {
171- if (strpos ($ src ,'http:// ' ) !== 0 &&
172- strpos ($ src ,'https:// ' )!== 0 ) {
232+ if (strpos ($ src , 'http:// ' ) !== 0 &&
233+ strpos ($ src , 'https:// ' )!== 0 ) {
173234 return false ;
174235 }
175236
@@ -178,11 +239,11 @@ public function downloadUrl(string $src, $path=null, &$result=null)
178239 return false ;
179240 }
180241
181- if (!preg_match ('/URL:\s*(.+?)\s*\[(.+?)\]\s*->\s*"(.+?)"/ ' , implode (PHP_EOL , $ output ), $ matches )) {
242+ if (!preg_match ('/URL:\s*(.+?)\s*\[(.+?)\]\s*->\s*"(.+?)"/ ' , implode (PHP_EOL , $ output ), $ matches )) {
182243 return false ;
183244 }
184245
185- if (empty ($ matches ) || count ($ matches ) != 4 ) {
246+ if (empty ($ matches ) || count ($ matches ) != 4 ) {
186247 return false ;
187248 }
188249
@@ -200,8 +261,8 @@ public function archiveExtract(string $src, string $path, $skip_components=null)
200261
201262 if (realpath ($ src )) {
202263 $ archive_file = $ src ;
203- } else {
204- if ( !$ this ->downloadUrl ($ src , null , $ download_result ) ) {
264+ } else {
265+ if ( !$ this ->downloadUrl ($ src , null , $ download_result )) {
205266 throw new \Exception ("Error downloading archive " );
206267 }
207268 $ archive_file = $ download_result ->file ;
0 commit comments