├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── LICENSE ├── README.md ├── language └── en_us │ └── virtualmin_blesta.php ├── lib ├── virtualmin_api.php └── virtualmin_lib_helper.php ├── views └── default │ ├── add_row.pdt │ ├── client_tab_database.pdt │ ├── client_tab_dns.pdt │ ├── client_tab_mail.pdt │ ├── client_tab_scripts.pdt │ ├── client_tab_status.pdt │ ├── edit_row.pdt │ ├── images │ └── logo.png │ ├── js │ ├── client_tab_dns.js │ ├── client_tab_mail.js │ ├── client_tab_scripts.js │ ├── client_tab_status.js │ └── pagehelper.js │ └── manage.pdt └── virtualmin_blesta.php /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear description of what the bug is. 12 | 13 | **To Reproduce** 14 | Please provide Steps to reproduce the issue: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If possible provide screenshot to help explain your problem. 25 | 26 | **Browser 27 | What browser are you using, chrome,ie,firefox,edge etc 28 | 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #idea 2 | *.iml 3 | .idea/ 4 | ## File-based project format: 5 | *.ipr 6 | *.iws 7 | 8 | # IntelliJ 9 | /out/ 10 | 11 | # mpeltonen/sbt-idea plugin 12 | .idea_modules/ 13 | 14 | # JIRA plugin 15 | atlassian-ide-plugin.xml 16 | 17 | # Crashlytics plugin (for Android Studio and IntelliJ) 18 | com_crashlytics_export_strings.xml 19 | crashlytics.properties 20 | crashlytics-build.properties 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Webkits 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitHub last commit](https://img.shields.io/github/last-commit/lukesubuntu/virtualmin_blesta) 2 | ![GitHub issues](https://img.shields.io/github/issues/lukesubuntu/virtualmin_blesta) 3 | ![GitHub issues by-label](https://img.shields.io/github/issues/lukesubuntu/virtualmin_blesta/bug?color=orange) 4 | ![GitHub closed issues](https://img.shields.io/github/issues-closed/lukesubuntu/virtualmin_blesta?color=red) 5 | 6 | 7 | Plugin in BETA so please check [Todo Status](https://github.com/lukesUbuntu/virtualmin_blesta/issues/11) or [Current Project Status](https://github.com/lukesUbuntu/virtualmin_blesta/projects/2) before installing. 8 | 9 | # Virtualmin Module for Blesta v4.0+ 10 | 11 | 12 | I myself have now got into webhosting with Virtualmin and updating this plugin for my own needs as i want all my clients hosting automated, from billing to the client controlling everything within blesta. 13 | 14 | If you have any suggestion's feel free to create an issue, aim is to allow client to login to blesta to manage there hosting. 15 | 16 | [Todo Status](https://github.com/lukesUbuntu/virtualmin_blesta/issues/11) or [Current Project Status](https://github.com/lukesUbuntu/virtualmin_blesta/projects/2) 17 | 18 | Module currently works with blesta 3.5+ (php 5.6 & 7.0+) project is still in beta i wouldn't install till [Todo Status](https://github.com/lukesUbuntu/virtualmin_blesta/issues/11) or [Current Project Status](https://github.com/lukesUbuntu/virtualmin_blesta/projects/2) has been completed. But if you want to have a play and provide issues or feedback feel free to install & help make this module. 19 | 20 | Ahh yeah so When will it be ready? 21 | Once completed above and redone a few security issues i have found that, i am hoping for August 2020 for first release 22 | 23 | ## 24 | 25 | **Virtualmin Blesta Module version 0.1.3** 26 | 27 | ### Current available client options for VirtualMin 28 | - server status 29 | - mail accounts 30 | - install script 31 | - databases 32 | 33 | 34 | [**Blesta**](http://www.blesta.com) is a professional web based billing and support application focusing on productivity and usability. 35 | 36 | [**Virtualmin**](https://www.virtualmin.com/) is a powerful and flexible web hosting control panel for Linux it allows full server management. 37 | 38 | Virtualmin Blesta module uses [**Virtualmin's Api**](https://www.virtualmin.com/documentation/developer/http) to allow clients to take full control of there hosting within blesta. It also can auto provision across multiple server groups or pop locations. 39 | 40 | 41 | ## Module Screen shots 42 | please note not all tabs are active in this repo module version 43 | 44 | ### Client Panel - Overview 45 | 46 | ![Overview](http://i.imgur.com/PLtkNdA.png) 47 | 48 | ### Client Panel - Mail Accounts 49 | 50 | ![Mail Accounts](http://i.imgur.com/Bqs81OT.png) 51 | 52 | ### Client Panel - Databases 53 | 54 | ![Databases](http://i.imgur.com/7i5DLMa.png) 55 | 56 | ####### NOTES ####### 57 | Plugin in BETA so please check [Todo Status](https://github.com/lukesUbuntu/virtualmin_blesta/issues/11) or [Current Project Status](https://github.com/lukesUbuntu/virtualmin_blesta/projects/2) before installing. 58 | 59 | ## Installation instructions 60 | ### Via Git 61 | 1. clone repo into your blesta modules folder eg `cd /home/blesta_install/public_html/components/modules` 62 | 2. run `$ git clone https://github.com/lukesUbuntu/virtualmin_blesta.git` 63 | 3. Go to Blesta Admin, and click on Settings->Modules and it will list the Virtualmin module, Click on "INSTALL" 64 | 4. Go to Virtualmin module and add your Virtualmin Server Details. 65 | 66 | #### Via FTP 67 | 1. [Download](https://github.com/lukesUbuntu/virtualmin_blesta/archive/master.zip) this module 68 | 2. Uncompress file,and rename folder to *virtualmin_blesta* 69 | 3. Upload *virtualmin_blesta* folder to your blesta root dir to */components/modules/* directory. 70 | 3. Go to Blesta Admin, and click on Settings->Modules and it will list the Virtualmin module, Click on "INSTALL" 71 | 4. Go to Virtualmin module and add your Virtualmin Server Details. 72 | 73 | -------------------------------------------------------------------------------- /language/en_us/virtualmin_blesta.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lib/virtualmin_api.php: -------------------------------------------------------------------------------- 1 | 6 | */ 7 | class VirtualMinApi 8 | { 9 | 10 | private $username; 11 | private $password; 12 | private $host; 13 | private $port; 14 | private $protocol; 15 | private $cache; 16 | private $running = false; 17 | private $response = false; 18 | 19 | public function __construct($host, $username, $password, $port = "10000", $use_ssl = true) 20 | { 21 | 22 | $this->host = $host; 23 | $this->port = $port; 24 | $this->protocol = "http" . ($use_ssl ? "s" : "") . "://"; 25 | $this->username = $username; 26 | $this->password = $password; 27 | $this->cache = new stdClass(); 28 | 29 | } 30 | 31 | public function get_domains($user = false) 32 | { 33 | if ($user === false) { 34 | $params = array( 35 | 'program' => 'list-domains', 36 | 'json' => 1, 37 | 'multiline', 38 | ); 39 | $response = json_decode($this->callServer($params)); 40 | $this->cacheDomain($response->data); 41 | return $response->data; 42 | } else { 43 | 44 | } 45 | return false; 46 | } 47 | 48 | function validate_email($email) { 49 | return (preg_match("/(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/", $email) || !preg_match("/^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/", $email)) ? false : true; 50 | } 51 | public function add_email_forward(array $params = array()){ 52 | $required = array( 53 | 'domain', 54 | 'user', 55 | 'email' 56 | ); 57 | if (!$this->checkIfAllParamsGood($params, $required)) { 58 | return false; 59 | } 60 | 61 | $mail_accounts = $this->list_users(['domain' => $params['domain']]); 62 | $foundAccount = null; 63 | $emailOrNameCheck = $this->validate_email($params['user']); 64 | 65 | foreach ($mail_accounts->data as $account) { 66 | 67 | // check against email or name account 68 | if ($emailOrNameCheck){ 69 | if ($account->values->email_address[0] == $params['user']){ 70 | $foundAccount = $account->values; 71 | break; 72 | } 73 | }else{ 74 | if ($account->name == $params['user']){ 75 | $foundAccount = $account->values; 76 | break; 77 | } 78 | } 79 | 80 | } 81 | if ($foundAccount == null) 82 | return "Failed to find account"; 83 | 84 | 85 | $prams = [ 86 | 'user' => $foundAccount->unix_username[0], 87 | 'domain' => $params['domain'], 88 | 'add-forward' => $params['email'] 89 | ]; 90 | 91 | $response = $this->modify_user($prams); 92 | return $response; 93 | } 94 | /** 95 | * required params['domain','user'] 96 | * optional ['email'] if not supplied will remove all email forwarders 97 | */ 98 | public function remove_email_forward(array $params = array()){ 99 | $required = array( 100 | 'domain', 101 | 'user' 102 | ); 103 | if (!$this->checkIfAllParamsGood($params, $required)) { 104 | return false; 105 | } 106 | 107 | $mail_accounts = $this->list_users(['domain' => $params['domain']]); 108 | $foundAccount = null; 109 | 110 | foreach ($mail_accounts->data as $account) { 111 | // print_r($account->values->email_address);exit; 112 | if ($account->values->email_address[0] == $params['user']){ 113 | $foundAccount = $account->values; 114 | break; 115 | } 116 | } 117 | 118 | if ($foundAccount == null) 119 | return "Failed to find account"; 120 | 121 | $forwardAddress = $foundAccount->forward_mail_to; 122 | $response = []; 123 | foreach ($forwardAddress as $email) { 124 | 125 | $prams = [ 126 | 'user' => $foundAccount->unix_username[0], 127 | 'domain' => $params['domain'], 128 | 'del-forward' => $email 129 | ]; 130 | if (isset($params['email'])){ 131 | if ($params['email'] == $email){ 132 | $this->modify_user($prams); 133 | } 134 | }else{ 135 | $response[] = $this->modify_user($prams); 136 | } 137 | 138 | } 139 | // print_r($forwardAddress);exit; 140 | // $params['program'] = 'modify-user'; 141 | // $params['json'] = 1; 142 | // $params[] = 'multiline'; 143 | // get a list of forwarders on current account 144 | return $response; 145 | } 146 | public function get_domain_info(array $params = array()) 147 | { 148 | $required = array( 149 | 'domain' 150 | ); 151 | if (!$this->checkIfAllParamsGood($params, $required)) { 152 | return false; 153 | } 154 | $params['program'] = 'list-domains'; 155 | $params['json'] = 1; 156 | $params[] = 'multiline'; 157 | return json_decode($this->callServer($params)); 158 | } 159 | 160 | /** 161 | * example of basic @param usage 162 | * @param array $params required keys: domain, pass, and at least one option: unix, dir, webmin, web, dns, mail, limits-from-plan 163 | * @return mixed 164 | */ 165 | public function add_domain(array $params = array()) 166 | { 167 | $required = array( 168 | 'domain', 169 | 'pass', 170 | ); 171 | if (!$this->checkIfAllParamsGood($params, $required)) { 172 | return false; 173 | } 174 | $params['program'] = 'create-domain'; 175 | $params['json'] = 1; 176 | $params[] = 'multiline'; 177 | return json_decode($this->callServer($params)); 178 | } 179 | 180 | public function delete_domain(array $params = array()) 181 | { 182 | $required = array( 183 | 'domain', 184 | ); 185 | if (!$this->checkIfAllParamsGood($params, $required)) { 186 | return false; 187 | } 188 | $params['program'] = 'delete-domain'; 189 | $params['json'] = 1; 190 | $params[] = 'multiline'; 191 | return json_decode($this->callServer($params)); 192 | } 193 | 194 | public function suspend_domain(array $params = array()) 195 | { 196 | $required = array( 197 | 'domain', 198 | ); 199 | if (!$this->checkIfAllParamsGood($params, $required)) { 200 | return false; 201 | } 202 | $params['program'] = 'disable-domain'; 203 | $params['json'] = 1; 204 | $params[] = 'multiline'; 205 | return json_decode($this->callServer($params)); 206 | } 207 | 208 | public function unsuspend_domain(array $params = array()) 209 | { 210 | $required = array( 211 | 'domain', 212 | ); 213 | if (!$this->checkIfAllParamsGood($params, $required)) { 214 | return false; 215 | } 216 | $params['program'] = 'enable-domain'; 217 | $params['json'] = 1; 218 | $params[] = 'multiline'; 219 | return json_decode($this->callServer($params)); 220 | } 221 | 222 | //https://www.virtualmin.com/documentation/developer/cli/modify_domain 223 | public function modify_domain(array $params = array()) 224 | { 225 | $required = array( 226 | 'domain', 227 | ); 228 | if (!$this->checkIfAllParamsGood($params, $required)) { 229 | return false; 230 | } 231 | $params['program'] = 'modify-domain'; 232 | $params['json'] = 1; 233 | $params[] = 'multiline'; 234 | return json_decode($this->callServer($params)); 235 | } 236 | 237 | public function create_database(array $params = array()) 238 | { 239 | $required = array( 240 | 'domain', 241 | 'name', 242 | 'type' => 'mysql|postgres', 243 | ); 244 | if (!$this->checkIfAllParamsGood($params, $required)) { 245 | return false; 246 | } 247 | $params['program'] = 'create-database'; 248 | $params['json'] = 1; 249 | $params[] = 'multiline'; 250 | return json_decode($this->callServer($params)); 251 | } 252 | 253 | public function delete_database(array $params = array()) 254 | { 255 | $required = array( 256 | 'domain', 257 | 'name', 258 | 'type' => 'mysql|postgres', 259 | ); 260 | if (!$this->checkIfAllParamsGood($params, $required)) { 261 | return false; 262 | } 263 | $params['program'] = 'delete-database'; 264 | $params['json'] = 1; 265 | $params[] = 'multiline'; 266 | return json_decode($this->callServer($params)); 267 | } 268 | 269 | public function list_databases(array $params = array()) 270 | { 271 | $required = array( 272 | 'domain', 273 | ); 274 | if (!$this->checkIfAllParamsGood($params, $required)) { 275 | return false; 276 | } 277 | $params['program'] = 'list-databases'; 278 | $params['json'] = 1; 279 | $params[] = 'multiline'; 280 | return json_decode($this->callServer($params)); 281 | } 282 | 283 | public function disconnect_database(array $params = array()) 284 | { 285 | $required = array( 286 | 'domain', 287 | 'name', 288 | 'type' => 'mysql|postgres', 289 | ); 290 | if (!$this->checkIfAllParamsGood($params, $required)) { 291 | return false; 292 | } 293 | $params['program'] = 'disconnect-database'; 294 | $params['json'] = 1; 295 | $params[] = 'multiline'; 296 | return json_decode($this->callServer($params)); 297 | } 298 | 299 | public function modify_database_hosts(array $params = array()) 300 | { 301 | $required = array( 302 | 'domain|all-domain', 303 | 'type' => 'mysql|postgres', 304 | ); 305 | if (!$this->checkIfAllParamsGood($params, $required)) { 306 | return false; 307 | } 308 | $params['program'] = 'modify-database-hosts'; 309 | $params['json'] = 1; 310 | $params[] = 'multiline'; 311 | return json_decode($this->callServer($params)); 312 | } 313 | 314 | public function import_database(array $params = array()) 315 | { 316 | $required = array( 317 | 'domain', 318 | 'name', 319 | 'type' => 'mysql|postgres', 320 | ); 321 | if (!$this->checkIfAllParamsGood($params, $required)) { 322 | return false; 323 | } 324 | $params['program'] = 'import-database'; 325 | $params['json'] = 1; 326 | $params[] = 'multiline'; 327 | return json_decode($this->callServer($params)); 328 | } 329 | 330 | public function create_reseller(array $params = array()) 331 | { 332 | $required = array( 333 | 'name', 334 | 'pass', 335 | ); 336 | if (!$this->checkIfAllParamsGood($params, $required)) { 337 | return false; 338 | } 339 | $params['program'] = 'create-reseller'; 340 | $params['json'] = 1; 341 | $params[] = 'multiline'; 342 | return json_decode($this->callServer($params)); 343 | } 344 | 345 | public function delete_reseller(array $params = array()) 346 | { 347 | $required = array( 348 | 'name', 349 | ); 350 | if (!$this->checkIfAllParamsGood($params, $required)) { 351 | return false; 352 | } 353 | $params['program'] = 'delete-reseller'; 354 | $params['json'] = 1; 355 | $params[] = 'multiline'; 356 | return json_decode($this->callServer($params)); 357 | } 358 | 359 | public function list_resellers(array $params = array()) 360 | { 361 | $params['program'] = 'list-resellers'; 362 | $params['json'] = 1; 363 | $params[] = 'multiline'; 364 | return json_decode($this->callServer($params)); 365 | } 366 | 367 | public function modify_reseller(array $params = array()) 368 | { 369 | $required = array( 370 | 'name', 371 | ); 372 | if (!$this->checkIfAllParamsGood($params, $required)) { 373 | return false; 374 | } 375 | $params['program'] = 'modify-reseller'; 376 | $params['json'] = 1; 377 | $params[] = 'multiline'; 378 | return json_decode($this->callServer($params)); 379 | } 380 | 381 | public function create_user(array $params = array()) 382 | { 383 | $required = array( 384 | 'domain', 385 | 'user', 386 | 'pass', 387 | ); 388 | if (!$this->checkIfAllParamsGood($params, $required)) { 389 | return false; 390 | } 391 | $params['program'] = 'create-user'; 392 | $params['json'] = 1; 393 | $params[] = 'multiline'; 394 | //clear the list users session 395 | $this->clearSession($params['domain'], "list-users"); 396 | return json_decode($this->callServer($params)); 397 | } 398 | 399 | public function delete_user(array $params = array()) 400 | { 401 | $required = array( 402 | 'domain', 403 | 'user', 404 | ); 405 | if (!$this->checkIfAllParamsGood($params, $required)) { 406 | return false; 407 | } 408 | $params['program'] = 'delete-user'; 409 | $params['json'] = 1; 410 | $params[] = 'multiline'; 411 | //clear the list users session 412 | $this->clearSession($params['domain'], "list-users"); 413 | return json_decode($this->callServer($params)); 414 | } 415 | 416 | public function modify_user(array $params = array()) 417 | { 418 | $required = array( 419 | 'domain', 420 | 'user', 421 | ); 422 | if (!$this->checkIfAllParamsGood($params, $required)) { 423 | return false; 424 | } 425 | $params['program'] = 'modify-user'; 426 | $params['json'] = 1; 427 | $params[] = 'multiline'; 428 | return json_decode($this->callServer($params)); 429 | } 430 | 431 | public function list_mailbox(array $params = array()) 432 | { 433 | $required = array( 434 | 'domain', 435 | 'user', 436 | ); 437 | if (!$this->checkIfAllParamsGood($params, $required)) { 438 | return false; 439 | } 440 | $params['program'] = 'list-mailbox'; 441 | $params['json'] = 1; 442 | $params[] = 'multiline'; 443 | return json_decode($this->callServer($params)); 444 | } 445 | 446 | public function list_users(array $params = array()) 447 | { 448 | $required = array( 449 | 'domain', 450 | ); 451 | if (!$this->checkIfAllParamsGood($params, $required)) { 452 | return false; 453 | } 454 | $params['program'] = 'list-users'; 455 | $params['json'] = 1; 456 | $params[] = 'multiline'; 457 | return json_decode($this->callServer($params)); 458 | } 459 | 460 | public function modify_database_user(array $params = array()) 461 | { 462 | $required = array( 463 | 'domain', 464 | 'type' => 'mysql|postgres', 465 | 'user', 466 | ); 467 | if (!$this->checkIfAllParamsGood($params, $required)) { 468 | return false; 469 | } 470 | $params['program'] = 'modify-database-user'; 471 | $params['json'] = 1; 472 | $params[] = 'multiline'; 473 | return json_decode($this->callServer($params)); 474 | } 475 | 476 | public function modify_resources(array $params = array()) 477 | { 478 | $required = array( 479 | 'domain|all-domains', 480 | ); 481 | if (!$this->checkIfAllParamsGood($params, $required)) { 482 | return false; 483 | } 484 | $params['program'] = 'modify-resources'; 485 | $params['json'] = 1; 486 | $params[] = 'multiline'; 487 | return json_decode($this->callServer($params)); 488 | } 489 | 490 | public function modify_limits(array $params = array()) 491 | { 492 | $required = array( 493 | 'domain|user', 494 | ); 495 | if (!$this->checkIfAllParamsGood($params, $required)) { 496 | return false; 497 | } 498 | $params['program'] = 'modify-limits'; 499 | $params['json'] = 1; 500 | $params[] = 'multiline'; 501 | return json_decode($this->callServer($params)); 502 | } 503 | 504 | public function enable_limit(array $params = array()) 505 | { 506 | $required = array( 507 | 'domain|all-domains', 508 | ); 509 | if (!$this->checkIfAllParamsGood($params, $required)) { 510 | return false; 511 | } 512 | $params['program'] = 'enable-limit'; 513 | $params['json'] = 1; 514 | $params[] = 'multiline'; 515 | return json_decode($this->callServer($params)); 516 | } 517 | 518 | public function disable_limit(array $params = array()) 519 | { 520 | $required = array( 521 | 'domain|all-domains', 522 | ); 523 | if (!$this->checkIfAllParamsGood($params, $required)) { 524 | return false; 525 | } 526 | $params['program'] = 'disable-limit'; 527 | $params['json'] = 1; 528 | $params[] = 'multiline'; 529 | return json_decode($this->callServer($params)); 530 | } 531 | 532 | public function restore_domain(array $params = array()) 533 | { 534 | $required = array( 535 | 'source', 536 | ); 537 | if (!$this->checkIfAllParamsGood($params, $required)) { 538 | return false; 539 | } 540 | $params['program'] = 'restore-domain'; 541 | $params['json'] = 1; 542 | $params[] = 'multiline'; 543 | return json_decode($this->callServer($params)); 544 | } 545 | 546 | //https://www.virtualmin.com/documentation/developer/cli/list_scheduled_backups 547 | public function list_scheduled_backups(array $params = array()) 548 | { 549 | $required = array( 550 | 'domain|user|reseller', 551 | ); 552 | if (!$this->checkIfAllParamsGood($params, $required)) { 553 | return false; 554 | } 555 | $params['program'] = 'list-scheduled-backups'; 556 | $params['json'] = 1; 557 | $params[] = 'multiline'; 558 | return json_decode($this->callServer($params)); 559 | } 560 | 561 | //https://www.virtualmin.com/documentation/developer/cli/backup_domain 562 | public function backup_domain(array $params = array()) 563 | { 564 | $required = array( 565 | 'dest', 566 | ); 567 | if (!$this->checkIfAllParamsGood($params, $required)) { 568 | return false; 569 | } 570 | $params['program'] = 'backup-domain'; 571 | $params['json'] = 1; 572 | $params[] = 'multiline'; 573 | return json_decode($this->callServer($params)); 574 | } 575 | 576 | public function create_admin(array $params = array()) 577 | { 578 | $required = array( 579 | 'domain', 580 | 'name', 581 | 'pass', 582 | ); 583 | if (!$this->checkIfAllParamsGood($params, $required)) { 584 | return false; 585 | } 586 | $params['program'] = 'create-admin'; 587 | $params['json'] = 1; 588 | $params[] = 'multiline'; 589 | return json_decode($this->callServer($params)); 590 | } 591 | 592 | public function delete_admin(array $params = array()) 593 | { 594 | $required = array( 595 | 'domain', 596 | 'name', 597 | ); 598 | if (!$this->checkIfAllParamsGood($params, $required)) { 599 | return false; 600 | } 601 | $params['program'] = 'delete-admin'; 602 | $params['json'] = 1; 603 | $params[] = 'multiline'; 604 | return json_decode($this->callServer($params)); 605 | } 606 | 607 | public function list_admins(array $params = array()) 608 | { 609 | $required = array( 610 | 'domain', 611 | ); 612 | if (!$this->checkIfAllParamsGood($params, $required)) { 613 | return false; 614 | } 615 | $params['program'] = 'list-admins'; 616 | $params['json'] = 1; 617 | $params[] = 'multiline'; 618 | return json_decode($this->callServer($params)); 619 | } 620 | 621 | public function modify_admin(array $params = array()) 622 | { 623 | $required = array( 624 | 'domain', 625 | 'name', 626 | ); 627 | if (!$this->checkIfAllParamsGood($params, $required)) { 628 | return false; 629 | } 630 | $params['program'] = 'modify-admin'; 631 | $params['json'] = 1; 632 | $params[] = 'multiline'; 633 | return json_decode($this->callServer($params)); 634 | } 635 | 636 | //https://www.virtualmin.com/documentation/developer/cli/list_scripts 637 | public function list_scripts(array $params = array()) 638 | { 639 | $required = array( 640 | 'all-domains|domain|user', 641 | ); 642 | if (!$this->checkIfAllParamsGood($params, $required)) { 643 | return false; 644 | } 645 | $params['program'] = 'list-scripts'; 646 | $params['json'] = 1; 647 | $params[] = 'multiline'; 648 | return json_decode($this->callServer($params)); 649 | } 650 | 651 | //https://www.virtualmin.com/documentation/developer/cli/list_available_scripts 652 | public function list_available_scripts(array $params = array()) 653 | { 654 | $params['program'] = 'list-available-scripts'; 655 | $params['json'] = 1; 656 | $params[] = 'multiline'; 657 | return json_decode($this->callServer($params)); 658 | } 659 | 660 | public function install_script(array $params = array()) 661 | { 662 | $required = array( 663 | 'domain', 664 | 'type', 665 | 'version', 666 | ); 667 | if (!$this->checkIfAllParamsGood($params, $required)) { 668 | return false; 669 | } 670 | $params['program'] = 'install-script'; 671 | $params['json'] = 1; 672 | $params[] = 'multiline'; 673 | return json_decode($this->callServer($params)); 674 | } 675 | 676 | public function delete_script(array $params = array()) 677 | { 678 | $required = array( 679 | 'domain', 680 | ); 681 | if (!$this->checkIfAllParamsGood($params, $required)) { 682 | return false; 683 | } 684 | $params['program'] = 'delete-script'; 685 | $params['json'] = 1; 686 | $params[] = 'multiline'; 687 | return json_decode($this->callServer($params)); 688 | } 689 | 690 | public function create_svn_repository(array $params = array()) 691 | { 692 | $required = array( 693 | 'domain', 694 | 'name', 695 | ); 696 | if (!$this->checkIfAllParamsGood($params, $required)) { 697 | return false; 698 | } 699 | $params['program'] = 'create-svn-repository'; 700 | $params['json'] = 1; 701 | $params[] = 'multiline'; 702 | return json_decode($this->callServer($params)); 703 | } 704 | 705 | public function delete_svn_repository(array $params = array()) 706 | { 707 | $required = array( 708 | 'domain', 709 | 'name', 710 | ); 711 | if (!$this->checkIfAllParamsGood($params, $required)) { 712 | return false; 713 | } 714 | $params['program'] = 'delete-svn-repository'; 715 | $params['json'] = 1; 716 | $params[] = 'multiline'; 717 | return json_decode($this->callServer($params)); 718 | } 719 | 720 | public function list_svn_repositories(array $params = array()) 721 | { 722 | $params['program'] = 'list-svn-repositories'; 723 | $params['json'] = 1; 724 | $params[] = 'multiline'; 725 | return json_decode($this->callServer($params)); 726 | } 727 | 728 | public function modify_plan(array $params = array()) 729 | { 730 | $required = array( 731 | 'name|id', 732 | ); 733 | if (!$this->checkIfAllParamsGood($params, $required)) { 734 | return false; 735 | } 736 | $params['program'] = 'delete-svn-repository'; 737 | $params['json'] = 1; 738 | $params[] = 'multiline'; 739 | return json_decode($this->callServer($params)); 740 | } 741 | 742 | /* 743 | * List the plans on the virtualmin server and 744 | */ 745 | public function list_plans(array $params = array()) 746 | { 747 | 748 | $params['program'] = 'list-plans'; 749 | $params['json'] = 1; 750 | $params[] = 'multiline'; 751 | 752 | //requesting plans from session 753 | if (isset($params['cache'])) { 754 | 755 | //we have it in session 756 | if ($response = $this->readSession("default", "list-plans")) { 757 | 758 | //if we have passed a plan name with the session we will unset the other results 759 | if (!empty($params['cache']) && $response != false) { 760 | $data = $response->data; 761 | foreach ($data as $plan => $value) { 762 | if ($params['cache'] != $plan) 763 | unset($response->data[$plan]); 764 | } 765 | 766 | } 767 | 768 | return $response; 769 | } 770 | 771 | } 772 | 773 | //clear the list-plans as we only want to store after we have setup selected plan 774 | $this->clearSession("default", "list-plans"); 775 | 776 | //lets store the plans into there own array 777 | $response = $this->callServer($params); 778 | 779 | if ($this->isJson($response) == false) return $response; 780 | 781 | $response = json_decode($response); 782 | 783 | if ($response->status == "success") { 784 | $plans = $response->data; 785 | $thePlans = array(); 786 | //print_r($plans); 787 | foreach ($plans as $plan) { 788 | //$plan->values->name[0] 789 | $thePlans[$plan->values->name[0]] = $plan->values; 790 | } 791 | 792 | $response->data = $thePlans; 793 | 794 | $this->writeSession($response, "default", "list-plans"); 795 | } 796 | 797 | 798 | return $response; 799 | } 800 | 801 | public function delete_plan(array $params = array()) 802 | { 803 | $required = array( 804 | 'name|id', 805 | ); 806 | if (!$this->checkIfAllParamsGood($params, $required)) { 807 | return false; 808 | } 809 | $params['program'] = 'delete-plan'; 810 | $params['json'] = 1; 811 | $params[] = 'multiline'; 812 | return json_decode($this->callServer($params)); 813 | } 814 | 815 | public function create_plan(array $params = array()) 816 | { 817 | $required = array( 818 | 'name', 819 | ); 820 | if (!$this->checkIfAllParamsGood($params, $required)) { 821 | return false; 822 | } 823 | $params['program'] = 'create-plan'; 824 | $params['json'] = 1; 825 | $params[] = 'multiline'; 826 | return json_decode($this->callServer($params)); 827 | } 828 | 829 | public function modify_template(array $params = array()) 830 | { 831 | $required = array( 832 | 'name|id', 833 | ); 834 | if (!$this->checkIfAllParamsGood($params, $required)) { 835 | return false; 836 | } 837 | $params['program'] = 'modify-template'; 838 | $params['json'] = 1; 839 | $params[] = 'multiline'; 840 | return json_decode($this->callServer($params)); 841 | } 842 | 843 | public function list_templates(array $params = array()) 844 | { 845 | $params['program'] = 'list-templates'; 846 | $params['json'] = 1; 847 | $params[] = 'multiline'; 848 | return json_decode($this->callServer($params)); 849 | } 850 | 851 | public function get_template(array $params = array()) 852 | { 853 | $required = array( 854 | 'name|id', 855 | ); 856 | if (!$this->checkIfAllParamsGood($params, $required)) { 857 | return false; 858 | } 859 | $params['program'] = 'get-template'; 860 | $params['json'] = 1; 861 | $params[] = 'multiline'; 862 | return json_decode($this->callServer($params)); 863 | } 864 | 865 | public function delete_template(array $params = array()) 866 | { 867 | $required = array( 868 | 'name|id', 869 | ); 870 | if (!$this->checkIfAllParamsGood($params, $required)) { 871 | return false; 872 | } 873 | $params['program'] = 'delete-template'; 874 | $params['json'] = 1; 875 | $params[] = 'multiline'; 876 | return json_decode($this->callServer($params)); 877 | } 878 | 879 | public function create_template(array $params = array()) 880 | { 881 | $required = array( 882 | 'name', 883 | 'empty|clone' 884 | ); 885 | if (!$this->checkIfAllParamsGood($params, $required)) { 886 | return false; 887 | } 888 | $params['program'] = 'create-template'; 889 | $params['json'] = 1; 890 | $params[] = 'multiline'; 891 | return json_decode($this->callServer($params)); 892 | } 893 | 894 | public function list_certs(array $params = array()) 895 | { 896 | $required = array( 897 | 'all-domains|domain|user', 898 | ); 899 | if (!$this->checkIfAllParamsGood($params, $required)) { 900 | return false; 901 | } 902 | $params['program'] = 'list-certs'; 903 | $params['json'] = 1; 904 | $params[] = 'multiline'; 905 | return json_decode($this->callServer($params)); 906 | } 907 | 908 | public function install_cert(array $params = array()) 909 | { 910 | $required = array( 911 | 'domain', 912 | ); 913 | if (!$this->checkIfAllParamsGood($params, $required)) { 914 | return false; 915 | } 916 | $params['program'] = 'install-cert'; 917 | $params['json'] = 1; 918 | $params[] = 'multiline'; 919 | return json_decode($this->callServer($params)); 920 | } 921 | 922 | public function generate_cert(array $params = array()) 923 | { 924 | $required = array( 925 | 'domain', 926 | 'self|csr', 927 | ); 928 | if (!$this->checkIfAllParamsGood($params, $required)) { 929 | return false; 930 | } 931 | $params['program'] = 'generate-cert'; 932 | $params['json'] = 1; 933 | $params[] = 'multiline'; 934 | return json_decode($this->callServer($params)); 935 | } 936 | 937 | public function list_proxies(array $params = array()) 938 | { 939 | $required = array( 940 | 'domain', 941 | ); 942 | if (!$this->checkIfAllParamsGood($params, $required)) { 943 | return false; 944 | } 945 | $params['program'] = 'list-proxies'; 946 | $params['json'] = 1; 947 | $params[] = 'multiline'; 948 | return json_decode($this->callServer($params)); 949 | } 950 | 951 | public function delete_proxy(array $params = array()) 952 | { 953 | $required = array( 954 | 'domain', 955 | 'path', 956 | ); 957 | if (!$this->checkIfAllParamsGood($params, $required)) { 958 | return false; 959 | } 960 | $params['program'] = 'delete-proxy'; 961 | $params['json'] = 1; 962 | $params[] = 'multiline'; 963 | return json_decode($this->callServer($params)); 964 | } 965 | 966 | public function create_proxy(array $params = array()) 967 | { 968 | $required = array( 969 | 'domain', 970 | 'path', 971 | 'url|no-proxy', 972 | ); 973 | if (!$this->checkIfAllParamsGood($params, $required)) { 974 | return false; 975 | } 976 | $params['program'] = 'crate-proxy'; 977 | $params['json'] = 1; 978 | $params[] = 'multiline'; 979 | return json_decode($this->callServer($params)); 980 | } 981 | 982 | public function change_license(array $params = array()) 983 | { 984 | $required = array( 985 | 'serial', 986 | 'key', 987 | ); 988 | if (!$this->checkIfAllParamsGood($params, $required)) { 989 | return false; 990 | } 991 | $params['program'] = 'change-license'; 992 | $params['json'] = 1; 993 | $params[] = 'multiline'; 994 | return json_decode($this->callServer($params)); 995 | } 996 | 997 | /* 998 | * this method is currently unclear, because it`s documentation is unclear. 999 | * @TODO clearify it`s documentation 1000 | */ 1001 | 1002 | public function change_password(array $params = array()) 1003 | { 1004 | $required = array( 1005 | 'username', 1006 | ); 1007 | if (!$this->checkIfAllParamsGood($params, $required)) { 1008 | return false; 1009 | } 1010 | $params['program'] = 'change-password'; 1011 | $params['json'] = 1; 1012 | $params[] = 'multiline'; 1013 | return json_decode($this->callServer($params)); 1014 | } 1015 | 1016 | public function check_config(array $params = array()) 1017 | { 1018 | $params['program'] = 'check-config'; 1019 | $params['json'] = 1; 1020 | $params[] = 'multiline'; 1021 | return json_decode($this->callServer($params)); 1022 | } 1023 | 1024 | public function check_connectivity(array $params = array()) 1025 | { 1026 | $required = array( 1027 | 'domain|user', 1028 | ); 1029 | if (!$this->checkIfAllParamsGood($params, $required)) { 1030 | return false; 1031 | } 1032 | $params['program'] = 'crate-proxy'; 1033 | $params['json'] = 1; 1034 | $params[] = 'multiline'; 1035 | return json_decode($this->callServer($params)); 1036 | } 1037 | 1038 | public function copy_mailbox(array $params = array()) 1039 | { 1040 | $required = array( 1041 | 'source', 1042 | 'dest', 1043 | ); 1044 | if (!$this->checkIfAllParamsGood($params, $required)) { 1045 | return false; 1046 | } 1047 | $params['program'] = 'copy-mailbox'; 1048 | $params['json'] = 1; 1049 | $params[] = 'multiline'; 1050 | return json_decode($this->callServer($params)); 1051 | } 1052 | 1053 | public function create_redirect(array $params = array()) 1054 | { 1055 | $required = array( 1056 | 'domain', 1057 | 'path', 1058 | 'alias|redirect' 1059 | ); 1060 | if (!$this->checkIfAllParamsGood($params, $required)) { 1061 | return false; 1062 | } 1063 | $params['program'] = 'create-redirect'; 1064 | $params['json'] = 1; 1065 | $params[] = 'multiline'; 1066 | return json_decode($this->callServer($params)); 1067 | } 1068 | 1069 | public function delete_redirect(array $params = array()) 1070 | { 1071 | $required = array( 1072 | 'domain', 1073 | 'path', 1074 | ); 1075 | if (!$this->checkIfAllParamsGood($params, $required)) { 1076 | return false; 1077 | } 1078 | $params['program'] = 'delete-redirect'; 1079 | $params['json'] = 1; 1080 | $params[] = 'multiline'; 1081 | return json_decode($this->callServer($params)); 1082 | } 1083 | 1084 | public function create_shared_address(array $params = array()) 1085 | { 1086 | $required = array( 1087 | 'ip|allocate-ip', 1088 | ); 1089 | if (!$this->checkIfAllParamsGood($params, $required)) { 1090 | return false; 1091 | } 1092 | $params['program'] = 'create-shared-address'; 1093 | $params['json'] = 1; 1094 | $params[] = 'multiline'; 1095 | return json_decode($this->callServer($params)); 1096 | } 1097 | 1098 | public function delete_shared_address(array $params = array()) 1099 | { 1100 | $required = array( 1101 | 'ip', 1102 | ); 1103 | if (!$this->checkIfAllParamsGood($params, $required)) { 1104 | return false; 1105 | } 1106 | $params['program'] = 'delete-shared-address'; 1107 | $params['json'] = 1; 1108 | $params[] = 'multiline'; 1109 | return json_decode($this->callServer($params)); 1110 | } 1111 | 1112 | public function disable_writelogs(array $params = array()) 1113 | { 1114 | $required = array( 1115 | 'domain|all-domains', 1116 | ); 1117 | if (!$this->checkIfAllParamsGood($params, $required)) { 1118 | return false; 1119 | } 1120 | $params['program'] = 'disable-writelogs'; 1121 | $params['json'] = 1; 1122 | $params[] = 'multiline'; 1123 | return json_decode($this->callServer($params)); 1124 | } 1125 | 1126 | public function enable_writelogs(array $params = array()) 1127 | { 1128 | $required = array( 1129 | 'domain|all-domains', 1130 | ); 1131 | if (!$this->checkIfAllParamsGood($params, $required)) { 1132 | return false; 1133 | } 1134 | $params['program'] = 'enable-writelogs'; 1135 | $params['json'] = 1; 1136 | $params[] = 'multiline'; 1137 | return json_decode($this->callServer($params)); 1138 | } 1139 | 1140 | public function get_command(array $params = array()) 1141 | { 1142 | $required = array( 1143 | 'command', 1144 | ); 1145 | if (!$this->checkIfAllParamsGood($params, $required)) { 1146 | return false; 1147 | } 1148 | $params['program'] = 'get-command'; 1149 | $params['json'] = 1; 1150 | $params[] = 'multiline'; 1151 | return json_decode($this->callServer($params)); 1152 | } 1153 | 1154 | public function get_dns(array $params = array()) 1155 | { 1156 | $required = array( 1157 | 'domain', 1158 | ); 1159 | if (!$this->checkIfAllParamsGood($params, $required)) { 1160 | return false; 1161 | } 1162 | $params['program'] = 'get-dns'; 1163 | $params['json'] = 1; 1164 | $params[] = 'multiline'; 1165 | return json_decode($this->callServer($params)); 1166 | } 1167 | 1168 | public function get_ssl(array $params = array()) 1169 | { 1170 | $required = array( 1171 | 'domain', 1172 | ); 1173 | if (!$this->checkIfAllParamsGood($params, $required)) { 1174 | return false; 1175 | } 1176 | $params['program'] = 'get-ssl'; 1177 | $params['json'] = 1; 1178 | $params[] = 'multiline'; 1179 | return json_decode($this->callServer($params)); 1180 | } 1181 | 1182 | public function info(array $params = array()) 1183 | { 1184 | $params['program'] = 'info'; 1185 | $params['json'] = 1; 1186 | $params[] = 'multiline'; 1187 | return json_decode($this->callServer($params)); 1188 | } 1189 | 1190 | public function list_bandwidth(array $params = array()) 1191 | { 1192 | $required = array( 1193 | 'domain|all-domains', 1194 | ); 1195 | if (!$this->checkIfAllParamsGood($params, $required)) { 1196 | return false; 1197 | } 1198 | $params['program'] = 'list-bandwidth'; 1199 | $params['json'] = 1; 1200 | $params[] = 'multiline'; 1201 | return json_decode($this->callServer($params)); 1202 | } 1203 | 1204 | public function get_commands(array $params = array()) 1205 | { 1206 | $params['program'] = 'list-commands'; 1207 | $params['json'] = 1; 1208 | $params[] = 'multiline'; 1209 | return json_decode($this->callServer($params)); 1210 | } 1211 | 1212 | public function list_features(array $params = array()) 1213 | { 1214 | $params['program'] = 'get-ssl'; 1215 | $params['json'] = 1; 1216 | $params[] = 'multiline'; 1217 | return json_decode($this->callServer($params)); 1218 | } 1219 | 1220 | public function list_php_ini(array $params = array()) 1221 | { 1222 | $required = array( 1223 | 'domain|all-domains|user', 1224 | ); 1225 | if (!$this->checkIfAllParamsGood($params, $required)) { 1226 | return false; 1227 | } 1228 | $params['program'] = 'list-php-ini'; 1229 | $params['json'] = 1; 1230 | $params[] = 'multiline'; 1231 | return json_decode($this->callServer($params)); 1232 | } 1233 | 1234 | public function list_redirects(array $params = array()) 1235 | { 1236 | $required = array( 1237 | 'domain', 1238 | ); 1239 | if (!$this->checkIfAllParamsGood($params, $required)) { 1240 | return false; 1241 | } 1242 | $params['program'] = 'list-redirects'; 1243 | $params['json'] = 1; 1244 | $params[] = 'multiline'; 1245 | return json_decode($this->callServer($params)); 1246 | } 1247 | 1248 | public function list_shared_addresses(array $params = array()) 1249 | { 1250 | $params['program'] = 'list-shared-addresses'; 1251 | $params['json'] = 1; 1252 | $params[] = 'multiline'; 1253 | return json_decode($this->callServer($params)); 1254 | } 1255 | 1256 | public function list_styles(array $params = array()) 1257 | { 1258 | $params['program'] = 'list-styles'; 1259 | $params['json'] = 1; 1260 | $params[] = 'multiline'; 1261 | return json_decode($this->callServer($params)); 1262 | } 1263 | 1264 | public function modify_database_pass(array $params = array()) 1265 | { 1266 | $required = array( 1267 | 'domain', 1268 | 'type', 1269 | 'user', 1270 | ); 1271 | if (!$this->checkIfAllParamsGood($params, $required)) { 1272 | return false; 1273 | } 1274 | $params['program'] = 'modify-database-pass'; 1275 | $params['json'] = 1; 1276 | $params[] = 'multiline'; 1277 | return json_decode($this->callServer($params)); 1278 | } 1279 | 1280 | public function modify_php_ini(array $params = array()) 1281 | { 1282 | $required = array( 1283 | 'domain|all-domains|user', 1284 | ); 1285 | if (!$this->checkIfAllParamsGood($params, $required)) { 1286 | return false; 1287 | } 1288 | $params['program'] = 'modify-php-ini'; 1289 | $params['json'] = 1; 1290 | $params[] = 'multiline'; 1291 | return json_decode($this->callServer($params)); 1292 | } 1293 | 1294 | public function search_maillogs(array $params = array()) 1295 | { 1296 | $params['program'] = 'search-maillogs'; 1297 | $params['json'] = 1; 1298 | $params[] = 'multiline'; 1299 | return json_decode($this->callServer($params)); 1300 | } 1301 | 1302 | public function set_spam(array $params = array()) 1303 | { 1304 | $params['program'] = 'set-spam'; 1305 | $params['json'] = 1; 1306 | $params[] = 'multiline'; 1307 | return json_decode($this->callServer($params)); 1308 | } 1309 | 1310 | public function test_imap(array $params = array()) 1311 | { 1312 | $required = array( 1313 | 'user', 1314 | 'pass', 1315 | 'server', 1316 | 'port', 1317 | ); 1318 | if (!$this->checkIfAllParamsGood($params, $required)) { 1319 | return false; 1320 | } 1321 | $params['program'] = 'test-imap'; 1322 | $params['json'] = 1; 1323 | $params[] = 'multiline'; 1324 | return json_decode($this->callServer($params)); 1325 | } 1326 | 1327 | public function test_pop3(array $params = array()) 1328 | { 1329 | $required = array( 1330 | 'user', 1331 | 'pass', 1332 | 'server', 1333 | 'port', 1334 | ); 1335 | if (!$this->checkIfAllParamsGood($params, $required)) { 1336 | return false; 1337 | } 1338 | $params['program'] = 'test-pop3F'; 1339 | $params['json'] = 1; 1340 | $params[] = 'multiline'; 1341 | return json_decode($this->callServer($params)); 1342 | } 1343 | 1344 | public function test_smtp(array $params = array()) 1345 | { 1346 | $required = array( 1347 | 'to', 1348 | ); 1349 | if (!$this->checkIfAllParamsGood($params, $required)) { 1350 | return false; 1351 | } 1352 | $params['program'] = 'test-smtp'; 1353 | $params['json'] = 1; 1354 | $params[] = 'multiline'; 1355 | return json_decode($this->callServer($params)); 1356 | } 1357 | 1358 | private function buildQueryString(array $query = array(), $questionMark = false) 1359 | { 1360 | if (empty($query)) { 1361 | return ""; 1362 | } 1363 | if (!is_array($query)) { 1364 | return ""; 1365 | } 1366 | if ($questionMark) { 1367 | $querySring = "?"; 1368 | } else { 1369 | $querySring = ""; 1370 | } 1371 | foreach ($query as $key => $value) { 1372 | if ($querySring !== "?" && $querySring !== "") { 1373 | $querySring .= "&"; 1374 | } 1375 | if (is_numeric($key)) { 1376 | $querySring .= $value . "="; 1377 | } else { 1378 | $querySring .= $key . "=" . $value; 1379 | } 1380 | } 1381 | return $querySring; 1382 | } 1383 | 1384 | public function callServer(array $params = array()) 1385 | { 1386 | 1387 | 1388 | //program's not to cache 1389 | 1390 | $no_store = array("create-domain", "create-user", "delete-user", "list-plans"); 1391 | $no_session = true; 1392 | 1393 | //store session under default if no domain provided 1394 | $domain = (isset($params['domain'])) ? $params['domain'] : 'default'; 1395 | $program = $params['program']; 1396 | 1397 | if (isset($params['no_cache'])) 1398 | $no_session = true; 1399 | 1400 | if (in_array($program, $no_store)) 1401 | $no_session = true; 1402 | 1403 | if ($no_session == true || ($response = $this->readSession($domain, $program)) == false) { 1404 | 1405 | $querySring = $this->buildQueryString($params); 1406 | unset($params); 1407 | $params = array( 1408 | 'user' => $this->username, 1409 | 'password' => $this->password, 1410 | ); 1411 | $url = $this->protocol . $this->host . ":" . $this->port . "/virtual-server/remote.cgi?" . $querySring; 1412 | //echo $url;exit; 1413 | //return $this->get($url, true, $params); 1414 | 1415 | $response = $this->get($url, true, $params); 1416 | 1417 | //want to store the plans 1418 | //don't sotre 1419 | if (!$no_session) 1420 | $this->writeSession($response, $domain, $program); 1421 | } 1422 | 1423 | return $response; 1424 | 1425 | 1426 | } 1427 | 1428 | private function get($url = false, $return = true, array $params = array()) 1429 | { 1430 | 1431 | $ch = curl_init($url); 1432 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, $return); 1433 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 1434 | curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 1435 | 1436 | 1437 | curl_setopt($ch, CURLOPT_TIMEOUT, 0); 1438 | 1439 | if (isset($params['user']) && isset($params['password'])) { 1440 | curl_setopt($ch, CURLOPT_USERPWD, $params['user'] . ":" . $params['password']); 1441 | curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY); 1442 | } 1443 | 1444 | $data = curl_exec($ch); 1445 | // https://stackoverflow.com/questions/51760328/catch-curl-error-is-not-working-properly-does-not-give-error-if-data-is-not-rec 1446 | // print_r($data);exit; 1447 | 1448 | if ($data === false) { 1449 | $data = curl_error($ch); 1450 | throw new \Exception(curl_error($ch)); 1451 | } 1452 | 1453 | return $data; 1454 | 1455 | } 1456 | 1457 | /* 1458 | private function decodeResponse($response = false, $format = "json") { 1459 | if ($format == "json") { 1460 | return json_decode($response); 1461 | } elseif ($format == "xml") { 1462 | 1463 | } 1464 | return false; 1465 | } 1466 | 1467 | private function cacheDomain($domains = false) { 1468 | foreach ($domains as $domain) { 1469 | $domainName = $domain->name; 1470 | $this->cache->$domainName = $domain->values; 1471 | } 1472 | return true; 1473 | } 1474 | 1475 | private function getCached($domains = false) { 1476 | if (is_array($domains)) { 1477 | foreach ($domains as $key => $val) { 1478 | if ($this->isCached($val)) { 1479 | $toReturn[$val] = $this->cache->$val; 1480 | } 1481 | } 1482 | return $toReturn; 1483 | } elseif ($domains == "all") { 1484 | return $this->cache; 1485 | } elseif (is_string($domains)) { 1486 | if ($this->isCached($domains)) { 1487 | return $this->cache->$domains; 1488 | } 1489 | } 1490 | return false; 1491 | } 1492 | 1493 | private function isCached($domain = false) { 1494 | if (property_exists($this->cache, $domain)) { 1495 | return true; 1496 | } 1497 | return false; 1498 | } 1499 | 1500 | private function generatePassword() { 1501 | return substr(md5(time() . microtime(true) . mt_rand()), -8); 1502 | } 1503 | */ 1504 | public function checkIfAllParamsGood($params, $required) 1505 | { 1506 | $i = 0; 1507 | foreach ($required as $key => $val) { 1508 | if (is_numeric($key) && !is_string($key) && !is_array(explode("|", $key))) { 1509 | if (array_key_exists($val, $params)) { 1510 | $i++; 1511 | } else { 1512 | foreach ($params as $name => $param) { 1513 | if (is_numeric($name)) { 1514 | $newParams[$name] = $param; 1515 | } 1516 | } 1517 | foreach (array_values($newParams) as $blah => $value) { 1518 | if ($value == $val) { 1519 | $i++; 1520 | } 1521 | } 1522 | } 1523 | } else { 1524 | if (is_array($exploded = explode("|", $val))) { 1525 | foreach ($exploded as $key => $val) { 1526 | if (array_key_exists($val, $params)) { 1527 | $values = explode('|', $val); 1528 | if ($values[0] == 0) { 1529 | $i++; 1530 | } else { 1531 | foreach ($values as $key => $valu) { 1532 | if ($params[$valu] == $val) { 1533 | $i++; 1534 | } 1535 | } 1536 | } 1537 | } 1538 | } 1539 | } 1540 | if (array_key_exists($key, $params)) { 1541 | $values = explode('|', $val); 1542 | foreach ($values as $key => $val) { 1543 | if ($params[$key] == $val) { 1544 | $i++; 1545 | } 1546 | } 1547 | } 1548 | } 1549 | } 1550 | if (count($required) == $i) { 1551 | return true; 1552 | } 1553 | return true; 1554 | } 1555 | 1556 | /** 1557 | * Returns the session key data 1558 | * @param string $key 1559 | * @return bool if key was not found 1560 | */ 1561 | private function readSession($domain = "default", $program = "default") 1562 | { 1563 | //just check we have not already loaded 1564 | return (@$_SESSION["virtualmin_module"][$domain][$program] !== null) ? $_SESSION["virtualmin_module"][$domain][$program] : false; 1565 | 1566 | } 1567 | 1568 | /** 1569 | * Returns the complete session for a domain 1570 | * @param $domain 1571 | * @return bool 1572 | */ 1573 | public function Session($domain = "default") 1574 | { 1575 | //just check we have not already loaded 1576 | return (@$_SESSION["virtualmin_module"][$domain] !== null) ? $_SESSION["virtualmin_module"][$domain] : false; 1577 | } 1578 | 1579 | /** 1580 | * Writes a key & value to Session, if no key will use default 1581 | * @param $value 1582 | * @param string $key 1583 | */ 1584 | private function writeSession($value, $domain = "default", $program = "default") 1585 | { 1586 | //just check we have not already loaded 1587 | $_SESSION["virtualmin_module"][$domain][$program] = $value; 1588 | } 1589 | 1590 | /** 1591 | * Clears our virtualmin_module session or a array off the virtualmin_module session if parsed 1592 | * @param bool $key 1593 | */ 1594 | public function clearSession($domain = false, $key = false) 1595 | { 1596 | //if called with no key we are going to reset all values 1597 | 1598 | if (!$domain) { 1599 | unset($_SESSION["virtualmin_module"]); 1600 | return; 1601 | } 1602 | if (!$key) { 1603 | unset($_SESSION["virtualmin_module"][$domain]); 1604 | return; 1605 | } 1606 | 1607 | unset($_SESSION["virtualmin_module"][$domain][$key]); 1608 | } 1609 | 1610 | private function isJson($string) 1611 | { 1612 | json_decode($string); 1613 | return (json_last_error() == JSON_ERROR_NONE); 1614 | } 1615 | 1616 | } -------------------------------------------------------------------------------- /lib/virtualmin_lib_helper.php: -------------------------------------------------------------------------------- 1 | $data, 23 | "success" => $success 24 | ) 25 | ); 26 | 27 | //$response = json_encode($response); 28 | 29 | echo isset($_GET['callback']) 30 | ? "{$_GET['callback']}($response)" 31 | : $response; 32 | 33 | exit(0); 34 | } 35 | 36 | /** 37 | * This will loop the $get request and check if the $get is a tab that is in theTab array 38 | * 39 | * @param $getRequest 40 | * @param $request 41 | * @return bool 42 | */ 43 | public function isGetRequest($getRequest, $allowedRequests = array()){ 44 | 45 | //only check get request if more than 2 else waist of time checking just throw default tab 46 | if (($counter = count($getRequest)) > 2 && count($allowedRequests) >= 1){ 47 | 48 | foreach($getRequest as $key => $value){ 49 | if (in_array($getRequest[$key], $allowedRequests)) 50 | return $getRequest[$key]; 51 | } 52 | 53 | } 54 | 55 | return false; 56 | } 57 | 58 | /** 59 | * Checks if we have a xml request 60 | * @return bool 61 | */ 62 | public function isAjax(){ 63 | return (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'); 64 | } 65 | 66 | /** 67 | * Process ajax's call's only if the request is allowed calls method on main virtualmin by ref 68 | * 69 | * @param $caller 70 | * @param $getRequest 71 | * @param $postRequest 72 | * @param $allowedRequest 73 | */ 74 | public function processAjax(&$caller,$getRequest,$postRequest,$allowedRequest,$dataRequest = array()){ 75 | //all our ajax calls will be post for data and method calls by get 76 | if ($this->isAjax()){ 77 | //get the request made and can only be request that are in our allowedrequest array 78 | $request = $this->isGetRequest($getRequest,$allowedRequest); 79 | //check that this allowed request is callable 80 | if (method_exists($caller,$request) && is_callable(array($caller, $request))) 81 | $caller->$request($postRequest,$dataRequest); 82 | 83 | //invalid call 84 | $this->sendAjax("Invalid call to $request",false); 85 | 86 | } 87 | } 88 | 89 | /** 90 | * Cleans up the data back from virutlamin server more readable array like maparray 91 | * 92 | * @param $arrayData mixed array|multi array 93 | * @return object| bool Returns a virtualmin clean object with values 94 | */ 95 | public function cleanArray($arrayData, $useResultName = false){ 96 | $cleanArray = []; 97 | if (isset($arrayData->data) && isset($arrayData->data[0]->values)){ 98 | foreach ($arrayData->data as $index => $results) { 99 | 100 | foreach($results->values as $key => $values ){ 101 | // 102 | // print_r($results->values->unix_username[0]);exit; 103 | if (count($values) > 1){ 104 | //remove unwanted forward address 105 | if ($key == 'forward_mail_to'){ 106 | $adminRedirect = str_replace('@','-','\\'.$results->values->unix_username[0]); 107 | $forward_mail_to = []; 108 | foreach($values as $email){ 109 | 110 | if ($email == $adminRedirect) continue; 111 | 112 | $forward_mail_to[] = $email; 113 | } 114 | $cleanArray[$index][$key] = $forward_mail_to; 115 | }else{ 116 | 117 | if (isset($results->name) && !empty($results->name) && $useResultName == true){ 118 | $cleanArray[$results->name][$key] = $values; 119 | }else{ 120 | $cleanArray[$index][$key] = $values; 121 | } 122 | 123 | } 124 | 125 | 126 | } //if there is possible multiple values we will then store them as 127 | 128 | else{ 129 | 130 | 131 | if (isset($results->name) && !empty($results->name) && $useResultName == true){ 132 | $cleanArray[$results->name][$key] = $values[0]; 133 | }else{ 134 | $cleanArray[$index][$key] = $values[0]; 135 | } 136 | 137 | } 138 | 139 | } 140 | 141 | 142 | 143 | } 144 | 145 | } 146 | 147 | unset($data); // or $mainArr = $resultArr; 148 | return (!empty($cleanArray) && count($cleanArray) > 0) ? (array)$cleanArray : false; 149 | } 150 | } -------------------------------------------------------------------------------- /views/default/add_row.pdt: -------------------------------------------------------------------------------- 1 | Widget->clear(); 3 | $this->Widget->setLinkButtons(array()); 4 | $this->Widget->create($this->_("virtualmin.add_row.box_title", true)); 5 | ?> 6 |
7 | Form->create(); 9 | $this->Form->fieldHidden("account_count", $this->Html->ifSet($vars->account_count, 0)); 10 | ?> 11 |
12 |

_("virtualmin.add_row.basic_title");?>

13 |
14 |
15 | 65 |
66 | 67 |
68 |

_("virtualmin.add_row.name_servers_title");?>

69 |
70 |
71 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | Html->ifSet($vars->name_servers,[])); 85 | for ($i=0; $i 87 | "> 88 | 89 | 90 | 91 | 92 | 95 | 96 |
Form->label($this->_("virtualmin.add_row.name_server_col", true));?>Form->label($this->_("virtualmin.add_row.name_server_host_col", true));?>
_("virtualmin.row_meta.name_server", false, "" . ($i+1) . "");?>Form->fieldText("name_servers[]", $this->Html->ifSet($vars->name_servers[$i]));?>_("virtualmin.add_row.remove_name_server");?>
97 |
98 |
99 |

_("virtualmin.add_row.additional_settings");?>

100 |
101 |
102 | 103 |
104 |
_("virtualmin.add_row.add_btn");?>
105 | Form->end(); 107 | ?> 108 |
109 | Widget->end(); 111 | ?> 112 | 113 | 118 | 180 | 181 | -------------------------------------------------------------------------------- /views/default/client_tab_database.pdt: -------------------------------------------------------------------------------- 1 |
2 |

_("virtualmin.client.tabs.database.menu");?>

3 | 4 |
5 |
6 | 7 | 10 |
11 |
Username : Html->ifSet($service_fields->virtualmin_username)?>
12 | Html->ifSet($service_fields->virtualmin_password) != ""){?> 15 | 16 |
Password : Html->ifSet($service_fields->virtualmin_password) ?> 18 |
21 | 24 | 25 | Html->ifSet($service_fields->virtualmin_password) != ""){?> 29 |
Password : Html->ifSet($service_fields->virtualmin_password)?>
30 | 33 | 34 |
35 | 36 | 37 | 0) { 38 | ?> 39 |
40 |

_("virtualmin.client.tabs.database.menu");?>

41 | 42 | 43 | 44 | 45 | 46 | 47 | $database ) 49 | { 50 | 51 | ?> 52 | 53 | 54 | 55 | 56 | 61 | 66 | 67 | 72 | 73 | 74 | 77 | 78 | 79 |
_("virtualmin.client.tabs.database.table_db_name");?>_("virtualmin.client.tabs.database.table_db_table");?>_("virtualmin.client.tabs.database.table_db_size");?>
Html->_($database->name);?> 57 | 58 | Html->_($database->values->tables[0]);?> 59 | 60 | 62 | 63 | Html->_($database->values->size[0]);?> 64 | 65 | 68 | 71 |
80 |
81 | 84 | 106 | 107 | 142 |
143 | 144 | 145 | 146 | 230 | 231 | -------------------------------------------------------------------------------- /views/default/client_tab_dns.pdt: -------------------------------------------------------------------------------- 1 | 9 |

DNS Records

10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
TypeValueActions
38 |
39 | 40 | 61 | 62 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /views/default/client_tab_mail.pdt: -------------------------------------------------------------------------------- 1 | 2 |

_("virtualmin.client.tabs.mail.menu");?>

3 | 4 |
5 | 8 |
9 | 10 |
11 |

Create Email

12 |
13 |
14 | Form->fieldHidden( 16 | "action", 17 | array('id' => "add_mail_account") 18 | ); 19 | ?> 20 |
21 | Form->label("Account Username", "login_username"); 23 | ?> 24 |
25 | Form->fieldText( 28 | "add_mail_username", 29 | $this->Html->ifSet($vars->username), 30 | array( 31 | 'id' => "add_mail_username", 32 | 'style' => "display: inline;width:40%", 33 | 'class' => "form-control", 34 | 'placeholder' => "Email Username", true) 35 | ); 36 | ?> 37 | @Html->_($service_fields->virtualmin_domain);?> 38 | 39 |
40 |
41 |
42 | Form->label("Password", ""); 44 | $this->Form->fieldText( 45 | "add_mail_password", 46 | $this->Html->ifSet($vars->username), 47 | array('id' => "add_mail_password", 48 | 'class' => "form-control", 49 | 'placeholder' => "password", 50 | true) 51 | ); 52 | ?> 53 |
54 |
55 | Form->label("Quota", "add_mail_quota"); 57 | $this->Form->fieldText( 58 | "add_mail_quota", 59 | $this->Html->ifSet($vars->username), 60 | array('id' => "add_mail_quota", 61 | 'class' => "form-control", 62 | 'placeholder' => "Quota in MB eg : 10 = 10 MB", 63 | true) 64 | ); 65 | ?> 66 |
67 |
68 | Form->fieldCheckbox( 71 | "enable_mail_forward", 72 | "disabled", 73 | false, 74 | array('id' => "enable_mail_forward", 75 | 'class' => "") 76 | ); 77 | $this->Form->label("Forward Email"); 78 | 79 | 80 | $this->Form->fieldText( 81 | "email_forward_to", 82 | $this->Html->ifSet($vars->username), 83 | array('id' => "email_forward_to", 84 | 'class' => "form-control hide", 85 | 'placeholder' => "forwardaddress@example.com", 86 | true) 87 | ); 88 | ?> 89 |
90 | 93 | 96 | Form->end(); 98 | ?> 99 |
100 |
101 |
102 | Form->end(); 104 | //print_r($mail_accounts);exit; 105 | 106 | if ($this->Html->ifSet($mail_accounts) && count($mail_accounts) > 0) { 107 | ?> 108 |
109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | $email_data) { 125 | $email_accounts[] = $email_data['email_address']; 126 | 127 | $unlimited = empty($email_data['home_quota']); 128 | //print_r($email_data->forward_mail_to); 129 | $percent_used = ($unlimited ? 0 : round(($this->Html->ifSet($email_data['home_byte_quota_used'], 0) / $this->Html->ifSet($email_data['home_byte_quota'])) * 100, 0)); 130 | ?> 131 | 132 | 133 | 134 | 135 | 136 | 151 | 152 | 153 | Html->ifSet($email_data['forward_mail_to']) != ""){ 156 | $email_address = ''; 157 | 158 | if (is_array($email_data['forward_mail_to'])){ 159 | 160 | foreach ($email_data['forward_mail_to'] as $email) { 161 | 162 | $email_address = $email_address . "
  • $email
  • "; 163 | } 164 | 165 | }else{ 166 | $email_address = $email_data['forward_mail_to']; 167 | } 168 | echo ""; 169 | } 170 | 171 | else 172 | echo ""; ?> 173 | 174 | 175 | 176 | 217 | 218 | 219 | 220 | 221 | 224 | 225 | 226 |
    Email AccountQuota
    137 | 138 | Html->_($email_data['home_quota_used']); ?> 139 | / Html->_($email_data['home_quota']); ?> 140 | 141 | 142 |
    143 |
    146 | 147 |
    148 |
    149 | 150 |
    Mail Forwarding to ".$email_address." 177 | 178 | 179 | 215 | 216 |
    227 |
    228 | 231 | 232 | 233 | 271 | 272 | 310 | 311 | 312 | 341 | 342 | 343 | 344 | 367 | 368 | 380 | 381 | 382 | 383 | -------------------------------------------------------------------------------- /views/default/client_tab_scripts.pdt: -------------------------------------------------------------------------------- 1 | 18 |

    Available Scripts

    19 | Html->ifSet($script_list) && (count($script_list)) > 0) { 22 | ?> 23 |
    24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 37 | 38 | 41 | 44 | 45 | 73 | 74 | 77 | 78 |
    Script NameDescription
    39 | Html->_($script['name']); ?> 40 | 42 | Html->_($script['description']); ?> 43 | 46 | 47 |
    48 | 54 | 58 | 59 | 62 | 66 | 67 | 70 | 71 |
    72 |
    79 |
    80 | 83 | 84 | 125 | 126 | 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /views/default/client_tab_status.pdt: -------------------------------------------------------------------------------- 1 | 4 |

    _("virtualmin.client.tabs.status.heading"); ?>

    5 | 6 |
    7 |

    _("virtualmin.client.tabs.status.disk_title"); ?>

    8 | round($this->Html->ifSet($serverDetails->server_quota_used, 0), 2), 11 | 'limit' => round($this->Html->ifSet($serverDetails->server_quota, 0), 2) 12 | ); 13 | // print_r($serverDetails);exit; 14 | $unlimited = empty($serverDetails->server_quota); 15 | 16 | $percent_used = 0; 17 | // ($unlimited ? 0 : round(($this->Html->ifSet($disk['used'], 0) / $this->Html->ifSet($disk['limit'])) * 100, 0)); 18 | ?> 19 | 20 | / 21 | 22 |
    23 |
    25 | 26 |
    27 |
    28 | 29 | 30 | Html->ifSet($serverDetails->bandwidth_limit)){ 33 | ?>

    _("virtualmin.client.tabs.status.bandwidth_title"); ?>

    round($this->Html->ifSet($serverDetails->bandwidth_usage, 0), 2), 36 | 'limit' => round($this->Html->ifSet($serverDetails->bandwidth_limit, 0), 2) 37 | ); 38 | $unlimited = empty($serverDetails->bandwidth_limit); 39 | $percent_used = ($unlimited ? 0 : round(($this->Html->ifSet($bandwidth['used'], 0) / $this->Html->ifSet($bandwidth['limit'])) * 100, 0)); 40 | ?> 41 | 42 | _("virtualmin.client.tabs.status.disk_usage_unlimited", true, $this->Html->safe($bandwidth['used'])) : $this->_("virtualmin.client.tabs.status.disk_usage", true, $this->Html->safe($bandwidth['used']), $this->Html->safe($bandwidth['limit']))); ?> 43 | 44 |
    45 |
    48 | _("virtualmin.client.tabs.status.disk_usage_unlimited", true, $this->Html->safe($bandwidth['used'])) : $this->_("virtualmin.client.tabs.status.disk_usage", true, $this->Html->safe($bandwidth['used']), $this->Html->safe($bandwidth['limit']))); ?> 50 |
    51 |
    52 | 55 |

    _("virtualmin.client.tabs.status.server_details"); ?>

    56 | 57 | html_directory)) { 59 | 60 | ?> 61 | 62 | 63 |
    64 | Domain : 65 | Html->ifSet($hostname) ?> 66 | 67 |
    68 |
    69 | Username : 70 | Html->ifSet($serverDetails->username) ?> 71 | 72 |
    73 |
    74 | Password : 75 | 76 | Html->ifSet($serverDetails->password) ?> 77 | 78 | 81 |
    82 | 83 | ip_address; 86 | if (preg_match('#(?:[0-9]{1,3}\.){3}[0-9]{1,3}#', $serverDetails->ip_address, $serverIp)) { 87 | $server_ip = $serverIp[0]; 88 | } 89 | 90 | } 91 | ?> 92 | 93 |
    94 |
    95 | 96 | 97 | 100 | 103 | 104 | 105 | 106 | 109 | 112 | 113 | url)) { 115 | ?> 116 | 117 | 118 | 119 | 120 | 123 | 124 | 125 | 126 | 129 | 130 | 131 | 132 | 135 | 136 | 137 | 138 | 139 | 140 | 143 | 144 | 145 |
    98 | _("virtualmin.client.tabs.status.web_folder"); ?> 99 | 101 | Html->_($serverDetails->html_directory); ?> 102 |
    107 | _("virtualmin.client.tabs.status.php_version"); ?> 108 | 110 | Html->_($serverDetails->php_version); ?> 111 |
    _("virtualmin.client.tabs.status.web_address"); ?>Html->_($serverDetails->url); ?>
    IP AddressHtml->_($server_ip); ?> 128 |
    _("virtualmin.client.tabs.status.name_servers"); ?>Html->_($server); ?>
    146 |
    147 | password_storage == "Plain text" && $webmin_access == true) { 150 | echo sprintf('
    ' . 151 | '' . 152 | '' . 153 | '' . 154 | '' . '
    ', 155 | $webmin_url, 156 | $serverDetails->username, 157 | $serverDetails->password, 158 | $this->_("virtualmin.client.tabs.status.login_webmin", true) 159 | ); 160 | } 161 | ?> 162 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /views/default/edit_row.pdt: -------------------------------------------------------------------------------- 1 | 2 | Widget->clear(); 4 | $this->Widget->setLinkButtons(array()); 5 | $this->Widget->create($this->_("virtualmin.edit_row.box_title", true)); 6 | ?> 7 |
    8 | Form->create(); 10 | $this->Form->fieldHidden("account_count", $this->Html->ifSet($vars->account_count, 0)); 11 | ?> 12 |
    13 |

    _("virtualmin.edit_row.basic_title");?>

    14 |
    15 |
    16 | 64 |
    65 | 66 |
    67 |

    _("virtualmin.edit_row.name_servers_title");?>

    68 |
    69 |
    70 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Html->ifSet($vars->name_servers)); 84 | for ($i=0; $i 86 | "> 87 | 88 | 89 | 90 | 91 | 94 | 95 |
    Form->label($this->_("virtualmin.edit_row.name_server_col", true));?>Form->label($this->_("virtualmin.edit_row.name_server_host_col", true));?>
    _("virtualmin.row_meta.name_server", false, "" . ($i+1) . "");?>Form->fieldText("name_servers[]", $this->Html->ifSet($vars->name_servers[$i]));?>_("virtualmin.add_row.remove_name_server");?>
    96 |
    97 | 98 |
    _("virtualmin.edit_row.save_btn");?>
    99 | Form->end(); 101 | ?> 102 |
    103 | Widget->end(); 105 | ?> 106 | 107 | 112 | 173 | -------------------------------------------------------------------------------- /views/default/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lukesUbuntu/virtualmin_blesta/9479c83f406bd3d984ed19becffd41ea7bea3831/views/default/images/logo.png -------------------------------------------------------------------------------- /views/default/js/client_tab_dns.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function () { 3 | renderDnsRecords(); 4 | }) 5 | 6 | function renderDnsRecords(){ 7 | var dns_records_table = $("#dns_records_table > tbody:last-child"); 8 | var row_template = $('.dns_row').html() 9 | for(var dns_index in dnsRecords){ 10 | var record = dnsRecords[dns_index]; 11 | var row = row_template; 12 | if (record.type.toLowerCase() == "soa"){ 13 | continue; 14 | } 15 | row = $('' + row + ''); 16 | $('.type', row).text(record.type) 17 | var value = record.value.toString(); 18 | if (value.length > 50){ 19 | value = value.substr(0,80) + '...' 20 | } 21 | $('.value', row).text(value) 22 | 23 | 24 | $(dns_records_table).append(row) 25 | // > tbody:last-child 26 | } 27 | } -------------------------------------------------------------------------------- /views/default/js/client_tab_mail.js: -------------------------------------------------------------------------------- 1 | function generateActionMenu(email){ 2 | 3 | console.log("TCL: generateActionMenu -> $email_address", $mail_accounts) 4 | $actionMenu = $("#action_menu"); 5 | } 6 | 7 | function updateCurrentEmailAddress(email_address, id) { 8 | 9 | currentEmail = { 10 | email_address: email_address, 11 | id: id 12 | } 13 | 14 | } 15 | 16 | $(document).ready(function() { 17 | 18 | generateActionMenu('wassup@myexample.com'); 19 | if (typeof sendRequest != "function") throw new Error("pagehelper.js has not loaded"); 20 | 21 | /** 22 | * Change password 23 | */ 24 | $('#changePassword', $CurrentPage).on('show.bs.modal', function(e) { 25 | 26 | //$(this).find('.danger').attr('href', $(e.relatedTarget).data('href')) 27 | var email_id = $(e.relatedTarget).parent().data("email_id"); 28 | 29 | //not correct way should be binding data to the element but its just for basic display for now 30 | var email_address = $("#email_" + email_id + ' > .email_address', MailAccountsDiv).text(); 31 | 32 | console.log("email_address", email_address); 33 | $("#email_address", this).text(email_address); 34 | 35 | $(this).find('.change_password').click(function(e) { 36 | //doesn't matter if code gets injected as all code gets passed via blesta users domain 37 | new_password = $('#changePassword #change_password', $CurrentPage).val(); 38 | 39 | var $postVars = { 40 | 'email_address': email_address, 41 | 'new_password': new_password, 42 | 'action': "mail_change_password" 43 | }; 44 | errorLocation = $("#changePassword .modal-body"); 45 | sendRequest($postVars, function(response) { 46 | if (response.success == false) 47 | return processErrors(response, errorLocation); 48 | 49 | console.log("database changepassword response", response) 50 | $('#changePassword #change_password', $CurrentPage).val('') 51 | 52 | attachSuccess(response.data); 53 | return $('#changePassword').modal('toggle'); 54 | 55 | }, errorLocation); 56 | //$('#confirm-delete').hide.bs.modal 57 | return e.preventDefault(); 58 | }) 59 | }); 60 | 61 | /** 62 | * Confirm Deletion 63 | */ 64 | $('#ConfirmEmailDelete', $CurrentPage).on('show.bs.modal', function(e) { 65 | 66 | //$(this).find('.danger').attr('href', $(e.relatedTarget).data('href')) 67 | var email_id = currentEmail.id 68 | //$(e.relatedTarget).parent().data("email_id"); 69 | 70 | //not correct way should be binding data to the element but its just for basic display for now 71 | var email_address = currentEmail.email_address 72 | // $("#email_" + email_id + ' > .email_address', MailAccountsDiv).text(); 73 | 74 | $("#email_address", this).text(email_address); 75 | 76 | $(this).find('.danger').click(function(e) { 77 | 78 | var $postVars = { 79 | 'email_id': email_id, 80 | 'email_address': email_address, 81 | 'action': "mail_delete_user" 82 | }; 83 | 84 | sendRequest($postVars, function(response) { 85 | console.log("delete email response", response) 86 | 87 | if (response.success == true){ 88 | $(".email_address").each(function(a,b){ 89 | console.log("b",b) 90 | if ($(b).text() == email_address){ 91 | $(b).parent().remove() 92 | } 93 | }) 94 | $(".close").click() 95 | } 96 | 97 | 98 | }); 99 | //$('#confirm-delete').hide.bs.modal 100 | return e.preventDefault(); 101 | }) 102 | }); 103 | // save_email_forward 104 | $("#addEmailForward", $CurrentPage).click(function(e) { 105 | var add_email_forward = $("#add_email_forward").val(); 106 | if (/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/.test( 107 | add_email_forward) == false) { 108 | alert("Invalid email forwarding address") 109 | return; 110 | } 111 | 112 | var $postVars = { 113 | 'email_id': currentEmail.id, 114 | 'email_address': currentEmail.email_address, 115 | 'forward_email': add_email_forward, 116 | 'action': "mail_add_forward" 117 | }; 118 | console.log("postVars", $postVars) 119 | sendRequest($postVars, function(response) { 120 | console.log("delete email response", response) 121 | $('#addMailForward', $CurrentPage).modal('hide'); 122 | 123 | 124 | }); 125 | //$('#confirm-delete').hide.bs.modal 126 | 127 | 128 | }); 129 | $("#disable_forward", $CurrentPage).click(function(e) { 130 | var email_id = $(this).parent().data("email_id"); 131 | var email_address = $("#email_" + email_id + ' > .email_address', MailAccountsDiv).text(); 132 | var $postVars = { 133 | 'email_id': email_id, 134 | 'email_address': email_address, 135 | 'action': "mail_disable_forward" 136 | }; 137 | sendRequest($postVars, function(response) { 138 | console.log("disabling forwarder", response) 139 | 140 | 141 | }); 142 | 143 | }) 144 | /* 145 | * Create Email Account 146 | */ 147 | $("#create_account", $CurrentPage).click(function(e) { 148 | 149 | e.preventDefault(); 150 | //get our filled out form data 151 | var formData = $("#createEmailAccount", $CurrentPage).serializeFormToObject(); 152 | 153 | sendRequest(formData, function(response) { 154 | 155 | if (response && response.success == false) { 156 | processErrors(response) 157 | } else { 158 | addEmailToList(formData); 159 | attachSuccess(response.data); 160 | toggleAddMail(); 161 | } 162 | 163 | 164 | }); 165 | }); 166 | 167 | //toggle add mail div to show form 168 | $(".add_mail", $CurrentPage).click(toggleAddMail); 169 | 170 | //enable_mail_forward display textbox 171 | $('#enable_mail_forward', $CurrentPage).change(function() { 172 | if ($(this).is(":checked")) { 173 | $(this).val("enabled"); 174 | $("#email_forward_to").removeClass("hide") 175 | } else { 176 | $(this).val(""); 177 | $("#email_forward_to").addClass("hide"); 178 | } 179 | }); 180 | 181 | 182 | }); 183 | 184 | /** 185 | * Adds an email to our email list table 186 | */ 187 | function addEmailToList(emailForm) { 188 | var template_action_menu = $("#template_action_menu").html(); 189 | var email_address = emailForm.add_mail_username + '@' + $Domain 190 | template_action_menu = template_action_menu.replace(/%email%/gm,email_address) 191 | $('tr:last', MailAccountsDiv).after('' + email_address + 192 | ' edit options have not been loaded ' + template_action_menu + ' ') 193 | 194 | } 195 | /* 196 | * Toggles between adding a mail address form 197 | */ 198 | function toggleAddMail() { 199 | $("#createEmailAccount", $CurrentPage).toggleClass("hide"); 200 | $("#mail_accounts", $CurrentPage).toggleClass("hide"); 201 | 202 | //modify form 203 | if ($(".add_mail", $CurrentPage).hasClass("btn-warning")) { 204 | $(".add_mail", $CurrentPage).toggleClass("btn-warning", "btn-success"); 205 | $("span", ".add_mail", $CurrentPage).text("Add Mail Account"); 206 | 207 | } else { 208 | $(".add_mail", $CurrentPage).toggleClass("btn-warning"); 209 | $("span", ".add_mail", $CurrentPage).text("Cancel"); 210 | } 211 | } -------------------------------------------------------------------------------- /views/default/js/client_tab_scripts.js: -------------------------------------------------------------------------------- 1 | 2 | var script_name = '' 3 | $(".install").click(function(e){ 4 | script_name = $(this).data('script_name'); 5 | var script = $scriptInstall[script_name]; 6 | var $script_versions_select = $("#script_version") 7 | var $database_select = $("#database") 8 | var available_versions = script['available_versions'].split(" ") 9 | 10 | 11 | $(".script_name").text(script_name); 12 | $(".script_description").text(script['description']); 13 | for (var version_index in available_versions) { 14 | var version = available_versions[version_index]; 15 | var option = new Option(version, version); 16 | $script_versions_select.append(option) 17 | 18 | } 19 | var db_name = dbName(script_name); 20 | var option = new Option(db_name, db_name); 21 | $database_select.append(option) 22 | for (var database_index in available_databases) { 23 | var database = available_databases[database_index]; 24 | var option = new Option(database, database); 25 | $database_select.append(option) 26 | 27 | } 28 | $("#install_path").val(cleanScriptName(script_name)) 29 | $(".install_path").text(cleanScriptName(script_name)) 30 | 31 | // $(".script_name").text(script_name) 32 | }) 33 | 34 | 35 | $("#install_path").keyup(function(){ 36 | $(".install_path").text(cleanScriptName($("#install_path").val())) 37 | }); 38 | 39 | $(".removeScript").click(function(){ 40 | script_name = $(this).data('script_name'); 41 | 42 | var formData = { 43 | 44 | action : 'remove_script', 45 | script_name : script_name 46 | } 47 | sendRequest(formData, function(response) { 48 | 49 | $(this).removeClass('installed').addClass('not_installed') 50 | 51 | }); 52 | }) 53 | $("#installScript").click(function(){ 54 | var $this = $(this); 55 | var formData = { 56 | action : 'script_install', 57 | script_name : script_name 58 | } 59 | 60 | $(".form-control").each(function(a,b){ 61 | formData[$(b).attr('id')] = $(b).val(); 62 | }) 63 | 64 | 65 | 66 | sendRequest(formData, function(response) { 67 | //mysql database (.*) already exists 68 | console.log("TCL: response", response.success) 69 | if (response.success == false){ 70 | $("#install_error").text(response.data); 71 | }else{ 72 | $this.removeClass('not_installed').addClass('installed') 73 | } 74 | 75 | 76 | }); 77 | 78 | 79 | }) 80 | 81 | //https://www.virtualmin.com/documentation/install-scripts 82 | function dbName(script_name){ 83 | return available_databases[0] + "_" + cleanScriptName(script_name); 84 | } 85 | function cleanScriptName(script_name){ 86 | return script_name.replace(/\s|-|\.|:/g, '_').replace('__','_').toLowerCase(); 87 | } -------------------------------------------------------------------------------- /views/default/js/client_tab_status.js: -------------------------------------------------------------------------------- 1 | 2 | console.log("client_tab_status") 3 | $(document).ready(function () { 4 | 5 | if (typeof VirtualMinModuleServerDetails == 'undefined') 6 | throw Error("can't load VirtualMinModuleServerDetails") 7 | 8 | processDiskUsage() 9 | }) 10 | 11 | 12 | 13 | function processDiskUsage() { 14 | var disk_progress = $("#disk_progress"); 15 | 16 | var server_quota_used = VirtualMinModuleServerDetails['server_quota_used']; 17 | $(".server_quota_used").text(server_quota_used); 18 | 19 | 20 | var server_quota = VirtualMinModuleServerDetails['server_quota']; 21 | $(".server_quota").text(server_quota); 22 | 23 | console.log("TCL: processDiskUsage -> server_quota", server_quota) 24 | console.log("TCL: processDiskUsage -> VirtualMinModuleServerDetails", VirtualMinModuleServerDetails) 25 | } -------------------------------------------------------------------------------- /views/default/js/pagehelper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Luke Hardiman on 2/09/2015. 3 | * 4 | * Moved general functions that are been used by most views to this file will tidy up and create proper helper js file 5 | * 6 | * this javascript file has been thrown together as im concentrating on smashing out the php code then will define javascript structure better 7 | * 8 | */ 9 | 10 | /** 11 | * Send ajax request 12 | */ 13 | 14 | //$CurrentPage will be the bpdy of our plugin 15 | 16 | if (typeof $CsrfToken !== "string" || typeof $action_url !== "string" || typeof $CurrentPage == "undefined") 17 | throw new Error("pagehelper.js could not load properly 17"); 18 | /* 19 | if ($ instanceof jQuery) 20 | console.log("pagehelper.js loaded okay") 21 | else 22 | throw new Error("pagehelper.js could not load properly 22"); 23 | */ 24 | 25 | 26 | 27 | function sendRequest($postVars,successCallback,loadingElement){ 28 | 29 | 30 | //pass the token 31 | $postVars['_csrf_token'] = $CsrfToken; //add token 32 | 33 | //allow a loading div to be defined and append blesta ajax waiting..... 34 | loadingDiv = (loadingElement instanceof jQuery)? loadingElement : $CurrentPage; 35 | 36 | //remove any errors 37 | $(".error_section").remove(); 38 | $.ajax({ 39 | method: 'POST', 40 | url: actionUrl($postVars.action), //render url 41 | data : $postVars, 42 | success: successCallback, 43 | //console.log(response); 44 | error : function(httpObj, textStatus) { 45 | 46 | //401 (Unauthorized) need to refresh page session died 47 | if (httpObj.status == 401){ 48 | attachError("Session timed out refreshing possibley logged out reloading page..."); 49 | setTimeout(function(){ 50 | location.reload(); 51 | },4000); 52 | return; 53 | } 54 | 55 | try{ 56 | successCallback(httpObj.responseText); 57 | }catch(e){ 58 | //if not dump the works 59 | // responseText 60 | console.log("ajaxError httpObj->",httpObj); 61 | console.log("ajaxError textStatus->",textStatus); 62 | console.log("ajaxError $postVars ->",$postVars); 63 | } 64 | 65 | 66 | 67 | }, 68 | beforeSend: function() { 69 | if (typeof $(this).blestaLoadingDialog == 'function'){ 70 | loadingDiv.append($(this).blestaLoadingDialog()); 71 | } 72 | 73 | }, 74 | complete: function() { 75 | $(".loading_container",loadingDiv).remove(); 76 | }, 77 | dataType: 'json' 78 | }) 79 | } 80 | 81 | /* 82 | * Create URL & Get Request based on action url 83 | */ 84 | function actionUrl(action){ 85 | var url = ($action_url.length < 1) ? "/" : $action_url; 86 | return ((url.substr(-1) != '/') ? url + "/" + action : url + action); 87 | } 88 | /** 89 | * Attaches error message to the 90 | */ 91 | function attachError($message,toElement){ 92 | error_holder = (typeof toElement != "undefined") ? toElement : $(".container #client_services_manage").parent(); 93 | error_holder.prepend( 94 | '
    '+ 95 | '
    '+ 96 | ''+ 97 | // '
    '+ 100 | '
    ' 101 | ); 102 | } 103 | //attach success 104 | function attachSuccess($message,toElement){ 105 | error_holder = (typeof toElement != "undefined") ? toElement : $(".container #client_services_manage").parent(); 106 | error_holder.prepend( 107 | '
    '+ 108 | '
    '+ 109 | ''+ 110 | // '
    '+ 113 | '
    ' 114 | ); 115 | } 116 | 117 | /** 118 | * process errors received from ajax 119 | * Will render to toElement if set otherwise $ErrorHolder will be used 120 | * @param errors 121 | */ 122 | function processErrors(response,toElement){ 123 | console.log("response.data ",response.data ); 124 | //check what type of error 125 | if (typeof response.data == "undefined"){ 126 | console.log("Error checking response",response); 127 | return; 128 | } 129 | 130 | //3 types of errors that could be returned 131 | //****Single errors***/ 132 | if (typeof response.data.errors == "string"){ 133 | attachError(response.data.errors,toElement); 134 | return; 135 | } 136 | if (typeof response.data == "string"){ 137 | attachError( response.data,toElement); 138 | return; 139 | } 140 | //****Multiple errors***/ 141 | var our_errors = response.data.errors; 142 | 143 | if (typeof our_errors == "object"){ 144 | $.each(our_errors,function(key,value){ 145 | var error_message = false; 146 | if (typeof value.format == "string") 147 | error_message = value.format; 148 | 149 | if (typeof value.empty == "string") 150 | error_message = value.empty; 151 | 152 | attachError(error_message,toElement); 153 | 154 | }) 155 | } 156 | 157 | } 158 | /** 159 | * Takes all inputs from element and renders to object 160 | * 161 | * @returns {{}} Object of form 162 | */ 163 | $.fn.serializeFormToObject = function() 164 | { 165 | //get inputs from element 166 | var $inputs = $(":input",this); 167 | 168 | // get an associative array of just the values. 169 | var values = {}; 170 | $inputs.each(function() { 171 | if (this.name.length > 1) 172 | values[this.name] = $(this).val(); 173 | }); 174 | 175 | return values; 176 | }; 177 | /** 178 | * Document Ready 179 | */ 180 | $(document).ready(function () { 181 | /** 182 | * Show the main database password 183 | * $CurrentPage 184 | */ 185 | $(".show_password").click(function () { 186 | $(this).hide(); 187 | $('#password').removeClass('hide'); 188 | }); 189 | 190 | }) 191 | -------------------------------------------------------------------------------- /views/default/manage.pdt: -------------------------------------------------------------------------------- 1 | 2 | $this->_("virtualmin.add_module_row", true), 'attributes'=>array('href'=>$this->base_uri . "settings/company/modules/addrow/" . $module->id)), 5 | array('name'=>$this->_("virtualmin.add_module_group", true), 'attributes'=>array('href'=>$this->base_uri . "settings/company/modules/addgroup/" . $module->id)) 6 | ); 7 | $this->Widget->clear(); 8 | $this->Widget->setLinkButtons($link_buttons); 9 | 10 | $this->Widget->create($this->_("AdminCompanyModules.manage.boxtitle_manage", true, $this->Html->_($module->name, true)), array('id'=>"manage_virtualmin")); 11 | ?> 12 | 13 |
    14 |

    _("virtualmin.manage.module_rows_title");?>

    15 |
    16 | Html->ifSet($module->rows)); 18 | if ($num_rows > 0) { 19 | ?> 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | rows[$i]);exit; 30 | ?> 31 | > 32 | 33 | 34 | 36 | 48 | 49 | 52 |
    _("virtualmin.manage.module_rows_heading.name");?>_("virtualmin.manage.module_rows_heading.host_name");?>_("virtualmin.manage.module_rows_heading.accounts");?>_("virtualmin.manage.module_rows_heading.options");?>
    Html->_($module->rows[$i]->meta->server_name);?>Html->_($module->rows[$i]->meta->host_name);?>_("virtualmin.manage.module_rows.count", false, $this->Html->ifSet($module->rows[$i]->meta->account_count, 0), ($this->Html->ifSet($module->rows[$i]->meta->account_limit) == "" ? "∞" : $module->rows[$i]->meta->account_limit));?> 37 | Html->ifSet($module->id) . "/" . $this->Html->ifSet($module->rows[$i]->id) . "/");?>">_("virtualmin.manage.module_rows.edit");?> 38 | Form->create($this->base_uri . "settings/company/modules/deleterow/"); 40 | $this->Form->fieldHidden("id", $this->Html->ifSet($module->id)); 41 | $this->Form->fieldHidden("row_id", $this->Html->ifSet($module->rows[$i]->id)); 42 | ?> 43 | Html->ifSet($module->id) . "/" . $this->Html->ifSet($module->rows[$i]->id) . "/");?>" class="manage" rel="Html->safe($this->_("virtualmin.manage.module_rows.confirm_delete", true));?>">_("virtualmin.manage.module_rows.delete");?> 44 | Form->end(); 46 | ?> 47 |
    53 | 57 |
    58 |
    59 | _("virtualmin.manage.servers.no_results");?> 60 |
    61 |
    62 | 65 | 66 |
    67 |

    _("virtualmin.manage.module_groups_title");?>

    68 |
    69 | Html->ifSet($module->groups)); 71 | if ($num_rows > 0) { 72 | ?> 73 | 74 | 75 | 76 | 77 | 78 | 79 | 83 | > 84 | 85 | 86 | 98 | 99 | 102 |
    _("virtualmin.manage.module_groups_heading.name");?>_("virtualmin.manage.module_groups_heading.servers");?>_("virtualmin.manage.module_groups_heading.options");?>
    Html->_($module->groups[$i]->name);?>Html->ifSet($module->groups[$i]->rows));?> 87 | Html->ifSet($module->id) . "/" . $this->Html->ifSet($module->groups[$i]->id) . "/");?>">_("virtualmin.manage.module_groups.edit");?> 88 | Form->create($this->base_uri . "settings/company/modules/deletegroup/"); 90 | $this->Form->fieldHidden("id", $this->Html->ifSet($module->id)); 91 | $this->Form->fieldHidden("group_id", $this->Html->ifSet($module->groups[$i]->id)); 92 | ?> 93 | Html->ifSet($module->id) . "/" . $this->Html->ifSet($module->groups[$i]->id) . "/");?>" class="manage" rel="Html->safe($this->_("virtualmin.manage.module_groups.confirm_delete", true));?>">_("virtualmin.manage.module_groups.delete");?> 94 | Form->end(); 96 | ?> 97 |
    103 | 107 |
    108 |
    109 | _("virtualmin.manage.servers.groups.no_results");?> 110 |
    111 |
    112 | Widget->end(); 116 | ?> 117 | 118 | --------------------------------------------------------------------------------