From a00ca50ac9093b4b76f70e6288e4b7ab0d31e4d6 Mon Sep 17 00:00:00 2001 From: doudoudzj Date: Wed, 5 Jun 2019 11:59:53 +0800 Subject: [PATCH] Added Management Module --- admin.php | 224 +++++++++++++ assets/css/admin.css | 32 ++ controllers/admin.php | 276 +++++++++++++++++ data/config.php | 23 ++ data/installed | 0 data/member.php | 23 ++ include/admin_footer.php | 66 ++++ include/admin_header.php | 76 +++++ include/captcha.php | 40 +++ include/common.php | 21 ++ include/fonts/elephant.ttf | Bin 0 -> 51652 bytes install.php | 0 lib/api.php | 621 +++++++++++++++++++++++++++++++++++++ 13 files changed, 1402 insertions(+) create mode 100644 admin.php create mode 100644 assets/css/admin.css create mode 100644 controllers/admin.php create mode 100644 data/config.php create mode 100644 data/installed create mode 100644 data/member.php create mode 100644 include/admin_footer.php create mode 100644 include/admin_header.php create mode 100644 include/captcha.php create mode 100644 include/common.php create mode 100644 include/fonts/elephant.ttf create mode 100644 install.php create mode 100644 lib/api.php diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..aa7e683 --- /dev/null +++ b/admin.php @@ -0,0 +1,224 @@ + + + + + +
+
Please delete the install.php file.
+
+ + +
+ + + +
+
+ +

Hosting Account Management System

+

This is a simple script for WHM myownfreehost made to manage hosting accounts through the api assigned to users with free reseller accounts.

+ Available Functions: +
    +
  1. Verify if a domain is available.
  2. +
  3. Creation of account hosting from the panel.
  4. +
  5. Change password to hosting account.
  6. +
  7. Deactivate or disable a hosting account.
  8. +
  9. Activate or enable hosting account.
  10. +
  11. Verify how many domain and state of the hosting account.
  12. +
+ +

+ +
+

Verify the domain is available for registration

+ + +
+ +
+ + + + + + + + + + + + + + + + + $value) { ?> + + + + + + + + + + + + + + +
#BranchAccountUsernameEmailDomainPlanPasswordNameserverOperate
+ Login + + + +
+
+ +
+ + + + + + +
+ +
+ + + + +
+ +
+ + + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + + + +
+ +
已经登录
+ + +
+
+

+ response data:

";
+                            print_r($message[2]);
+                            echo "
"; + } ?> +
+ +
+
+
+ + \ No newline at end of file diff --git a/assets/css/admin.css b/assets/css/admin.css new file mode 100644 index 0000000..79ef638 --- /dev/null +++ b/assets/css/admin.css @@ -0,0 +1,32 @@ + +#section { + float: right; + display: block; + font-size: 14px; + margin: 8px 0; + color: #FFFFFF; +} + +.clear { + clear: both; + width: 100%; +} + +label { + display: block; + margin-bottom: 8px; + font-weight: bold; +} + +label input, +label select { + margin-top: 6px; +} + +input[name="captcha"] { + background: url(/include/captcha.php) no-repeat; + background-size: 160px 30px; + background-position-x: right; + background-position-y: center; + padding-right: 170px; +} diff --git a/controllers/admin.php b/controllers/admin.php new file mode 100644 index 0000000..a724647 --- /dev/null +++ b/controllers/admin.php @@ -0,0 +1,276 @@ + $val) { + $key = strtoupper($key); + if (strpos($key, $session_name)) { + session_id($_COOKIE[$key]); + } + } +} +session_start(); + +$is_admin = isset($_SESSION["is_login"]) && $_SESSION["is_login"] == true; +$section = !$is_admin ? "login" : (empty($_GET["s"]) ? "main" : $_GET["s"]); + +// print(session_id()); +// echo $_COOKIE["session_id"]; +// print($_COOKIE(["session_id"])); +// print($is_admin); + +$message = []; +$section_title = "Main"; + +switch ($section) { + case "main": + $section_title = "Main"; + break; + case "check_domain": + $section_title = "Check domain"; + if (isset($_POST["do_check_domain"])) { + $tsData = array( + "domain" => setProtect(strtolower($_POST["domain"])), + ); + if (!isset($tsData["domain"]) || empty($tsData["domain"])) { + $message = [0, "The domain is required."]; + } elseif (strlen($tsData["domain"]) < 4) { + $message = [0, "Enter a domain name or sub-domain."]; + } elseif (strlen($tsData["domain"]) > 50) { + $message = [0, "The domain can not exceed 50 characters."]; + } elseif (!mb_ereg("^([a-zA-Z0-9]+).([a-zA-Z0-9-]+).([a-zA-Z]{2,4})$", $tsData["domain"])) { + $message = [0, "The domain does not have a valid extension. Check it."]; + } elseif (preg_match("/(^.*)\.(tk)$/i", $tsData["domain"])) { + // To not allow domains.tk + $message = [0, "The domain extension is not allowed on this server."]; + } else { + $client = Api::init($config); + $client->availability(["domain" => $tsData["domain"]]); + $message = $client->message; + } + } + break; + case "account_add": + $section_title = "Account Add"; + if (isset($_POST["do_reg_account"])) { + $tsData = [ + "username" => setProtect(strtolower($_POST["username"])), + "password" => setProtect($_POST["password"]), + "domain" => setProtect(strtolower($_POST["domain"])), + "email" => setProtect(strtolower($_POST["email"])), + "plan" => setProtect($_POST["plan"]), + ]; + + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The Username is required"]; + } elseif (strlen($tsData["username"]) < 8 || strlen($tsData["username"]) > 12) { + $message = [0, "The username must be 8 characters."]; + } elseif (!preg_match("/^[a-zA-Z0-9]{4,16}$/", $tsData["username"])) { + $message = [0, "The username does not allow strange characters."]; + } elseif (strlen($tsData["password"]) < 6 || strlen($tsData["password"]) > 35) { + $message = [0, "Enter a minimum password of 6 to 35 characters."]; + } elseif (strlen($tsData["domain"]) < 4) { + $message = [0, "Enter a domain name or sub-domain."]; + } elseif (strlen($tsData["domain"]) > 35) { + $message = [0, "The domain can not exceed 35 characters."]; + } elseif (!mb_ereg("^([a-zA-Z0-9]+).([a-zA-Z0-9-]+).([a-zA-Z]{2,4})$", $tsData["domain"])) { + $message = [0, "The domain does not have a valid extension. Check it."]; + } elseif (preg_match("/(^.*)\.(tk)$/i", $tsData["domain"])) { + // To not allow domains.tk + $message = [0, "Domain extension is not allowed on this server."]; + } elseif (!mb_ereg("^[_a-z0-9-]+(.[_a-z0-9-]+)*@[a-z0-9-]+(.[a-z0-9-]+)*(.[a-z]{2,3})$", $tsData["email"])) { + $message = [0, "The email does not have a valid format, check it."]; + } elseif (strlen($tsData["email"]) > 35) { + $message = [0, "The email can not exceed 35 characters."]; + } elseif (empty($tsData["plan"])) { + $message = [0, "You must select a hosting plan."]; + } else { + $client = Api::init($config); + $client->createAccount([ + "username" => $tsData["username"], // A unique, 8 character identifier of the account. + "password" => $tsData["password"], // A password to login to the control panel, FTP MySQL and cPanel. + "domain" => $tsData["domain"], // Can be a subdomain or a custom domain. + "email" => $tsData["email"], // The email address of the user. + "plan" => $tsData["plan"], // A hosting plan for the account. + ]); + $message = $client->message; + } + } + break; + case "account_password": + $section_title = "Account Password"; + if (isset($_POST["do_set_password"])) { + $tsData = array( + "username" => setProtect(strtolower($_POST["username"])), + "password" => setProtect($_POST["password"]), + ); + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The username is required"]; + } elseif (strlen($tsData["username"]) < 4 || strlen($tsData["username"]) > 8) { + $message = [0, "The username must be 8 characters."]; + } elseif (!preg_match("/^[a-zA-Z0-9]{4,16}$/", $tsData["username"])) { + $message = [0, "The username does not allow strange characters."]; + } elseif (strlen($tsData["password"]) < 6 || strlen($tsData["password"]) > 35) { + $message = [0, "Enter a minimum password of 6 to 35 characters."]; + } else { + $client = Api::init($config); + $client->password([ + "username" => $tsData["username"], + "password" => $tsData["password"], + "enabledigest" => 1, // [enabledigest] Change the password in cPanel - FTP - MySQL + ]); + $message = $client->message; + } + } + break; + case "account_disable": + $section_title = "Account Suspend"; + if (isset($_POST["do_disable_account"])) { + $tsData = array( + "username" => setProtect(strtolower($_POST["username"])), + "reason" => setProtect($_POST["reason"]), + ); + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The username is required."]; + } elseif (strlen($tsData["username"]) < 4 || strlen($tsData["username"]) > 8) { + $message = [0, "The Username must be 8 characters"]; + } elseif (!preg_match("/^[a-zA-Z0-9]{4,16}$/", $tsData["username"])) { + $message = [0, "The Username does not allow strange characters"]; + } elseif (strlen($tsData["reason"]) < 10 || strlen($tsData["reason"]) > 60) { + $message = [0, "You must enter a reason with a maximum of 60 characters"]; + } else { + $client = Api::init($config); + $client->suspend([ + "username" => setProtect(strtolower($tsData["username"])), + "reason" => setProtect($tsData["reason"]), + ]); + $message = $client->message; + } + } + break; + case "account_active": + $section_title = "Account Activate"; + if (isset($_POST["do_activate_account"])) { + $tsData = array( + "username" => setProtect(strtolower($_POST["username"])), + ); + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The username is required."]; + } elseif (strlen($tsData["username"]) < 4 || strlen($tsData["username"]) > 8) { + $message = [0, "The username is invalid (8 characters maximum)."]; + } elseif (!preg_match("/^[a-zA-Z0-9]{4,16}$/", $tsData["username"])) { + $message = [0, "The username does not allow strange characters.."]; + } else { + $client = Api::init($config); + $client->unsuspend(["username" => setProtect(strtolower($tsData["username"]))]); + $message = $client->message; + } + } + break; + case "account_status": + $section_title = "Account Status"; + if (isset($_POST["do_check_status"])) { + $tsData = array( + "username" => setProtect(strtolower($_POST["username"])), + ); + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The username is required."]; + } elseif (strlen($tsData["username"]) < 4 || strlen($tsData["username"]) > 18) { + $message = [0, "Enter a username that is valid."]; + } elseif (!preg_match("/^[a-zA-Z0-9-_]{4,16}$/", $tsData["username"])) { + $message = [0, "The username does not allow strange characters."]; + } else { + $client = Api::init($config); + $client->getUserDomains(["username" => $tsData["username"]]); + + // if ($this->data != "null" && strpos($this->response, '[[') === 0) { + // $statuses = array_unique(array_map(function ($item) { + // return strtolower($item["status"]); + // }, $this->domain)); + // // print_r($statuses); + // if (count($statuses) == 1) { + // return $statuses[0]; + // } elseif (count($statuses) > 1) { + // return "The account domains have different statuses " . $this->getUserName() . "." . $this->data; + // } else { + // return null; + // } + // } else { + // return null; + // } + if ($client->getStatus() === "active") { + $message = [1, "The account " . $tsData["username"] . " is Actived"]; + } elseif ($client->getStatus() === "suspend") { + $message = [1, "The account " . $tsData["username"] . " is Suspend"]; + } else { + "Cannot find the specified associated account"; + $message = [0, "The account " . $tsData["username"] . " does not have associated accounts."]; + } + } + } + break; + case "account_domain": + $section_title = "Account Domains"; + if (isset($_POST["do_get_domains"])) { + $tsData = array( + "username" => setProtect(strtolower($_POST["username"])), + ); + if (!isset($tsData["username"]) || empty($tsData["username"])) { + $message = [0, "The username is required."]; + } elseif (strlen($tsData["username"]) < 4 || strlen($tsData["username"]) > 18) { + $message = [0, "Enter a username that is valid."]; + } elseif (!preg_match("/^[a-zA-Z0-9-_]{4,16}$/", $tsData["username"])) { + $message = [0, "The username does not allow strange characters."]; + } else { + $client = Api::init($config); + $client->getUserDomains(["username" => $tsData["username"]]); + $message = $client->message; + } + } + break; + case "account_list": + $section_title = "Account List"; + include_once $ROOT . "/data/member.php"; + break; + case "login": + $section_title = "Admin Login"; + if (isset($_POST["do_login"])) { + $username = setProtect(strtolower(trim($_POST["username"]))); + $password = setProtect(strtolower(trim($_POST["password"]))); + $captcha = setProtect(strtolower($_POST["captcha"])); + if (!isset($username) || empty($username)) { + $message = [0, "The username is required."]; + } elseif (!isset($password) || empty($password)) { + $message = [0, "The password is required."]; + } elseif (!isset($captcha) || empty($captcha)) { + $message = [0, "The captcha code is required."]; + } else { + if (!isset($_SESSION["admincaptchacode"]) || $captcha != strtolower($_SESSION["admincaptchacode"])) { + $message = [0, "The captcha code is invalid."]; + } elseif ($username == $admin["username"] && $password == $admin["password"]) { + $_SESSION["is_login"] = true; + $is_admin = true; + $message = [1, "Login successfully. 2 seconds later redirect to the main page"]; + header("refresh:2;url=admin.php"); + } else { + $is_admin = false; + $message = [0, "Login failed.Please check if the account or password is correct."]; + } + } + } + break; + case "logout": + $section_title = "Admin Logout"; + unset($_SESSION); + session_destroy(); + $message = [1, "Logout successfully. 2 seconds later redirect to the login page"]; + header("refresh:2;url=admin.php"); + break; + default: + $section_title = "Main"; +} diff --git a/data/config.php b/data/config.php new file mode 100644 index 0000000..dfacd19 --- /dev/null +++ b/data/config.php @@ -0,0 +1,23 @@ + "admin", + "password" => "admin", +]; + +$config = [ + "apiUsername" => "1", + "apiPassword" => "1", + "apiUrl" => "https://panel.myownfreehost.net:2087/xml-api/", + "plan" => [ + "test_whm_api" => "test", + "ccc" => "test2", + ], +]; diff --git a/data/installed b/data/installed new file mode 100644 index 0000000..e69de29 diff --git a/data/member.php b/data/member.php new file mode 100644 index 0000000..7f32423 --- /dev/null +++ b/data/member.php @@ -0,0 +1,23 @@ + "uiisc", + "account" => "testapi", + "username" => "uii_12345678", + "email" => "usitetest@uiisc.com", + "plan" => "test_whm_api", + "domain" => ["test1.uiisc.com", "testapi.uiisc.com"], + "password" => "abcAbc123", + "nameserver" => [ + "ns1.byet.org", + "ns2.byet.org" + ] + ] +]; diff --git a/include/admin_footer.php b/include/admin_footer.php new file mode 100644 index 0000000..598cdbb --- /dev/null +++ b/include/admin_footer.php @@ -0,0 +1,66 @@ + + + + + + + + + + \ No newline at end of file diff --git a/include/admin_header.php b/include/admin_header.php new file mode 100644 index 0000000..9f7564d --- /dev/null +++ b/include/admin_header.php @@ -0,0 +1,76 @@ + + + + + + + + + + + <?php echo $title; ?> - Hosting Account Management System - <?php echo $section_title; ?> + + + + + + + + + + +
+ +
diff --git a/include/captcha.php b/include/captcha.php new file mode 100644 index 0000000..2b235b3 --- /dev/null +++ b/include/captcha.php @@ -0,0 +1,40 @@ +

Oops! There was a problem. Apparently
You are using the php version ' . phpversion() . ' a lower version than the one indicated

Anake script requires the php version

5.5.+

'); + } +} + +// Protect the entered data function +function setProtect($var) +{ + return htmlentities(htmlspecialchars($var)); +} diff --git a/include/fonts/elephant.ttf b/include/fonts/elephant.ttf new file mode 100644 index 0000000000000000000000000000000000000000..024b076e5f0efdaa91bfc54ea520e928aee9c52d GIT binary patch literal 51652 zcmbTfcYq{inLqx%Roz`()m_y&r|O(@nx0s*ld5KRc6T-}uq?Z5VqpV$$x(7rQBV$0 zi6TlcfQp9!M34m(#5027t9Rb1XE;5T?fE@#Rrl=d-rYaH+3A_?u6L^6=XpO*e%^Nx zMhIEZm54@%Cf6x5fB5*xPayQUR}pgl_v&@!+Nq(#H^Yec;IZ-a{o4k3q-G}zc74Z7U@H(+~|9OYopY{F}p%1`I`tCD#opa#6KRrw>4xYY!-I3b)2tBwG=J4A7?S~K17g9qAJsgBT5D#qMzw76}{qg~LJ&cg)?}rYa zd){MHkLnS6dH}}%>Cid54t@OYPb~s{1sH!X!uVhD9Y~Li^tJfw@D9>`!+R%T7(r32 zj@9cankJXX_5RmHYC=R368}NbU+?}EE`A@^MEHpQbwu@^JK^u(UF?Sk@TEThle7%JdsSLGud3eP%M=z)mpvLY_$hE zgG0k3qhr$eiiydo=^0s>om)A-YW13hwd>Yz*tlu)mXl6CW$UTiPTP)loW66{?mc_Y z*mvex`wtvEboM#to_GEQ7aqRo;!7^Q?D8wFyz1&}u6^Hi*WYmCO*h|i>uu=vJJ9

Y8CgV+bD#gh&!2hri(mTk zb6@#q^!!)9_VsVP@ZvXL`qs;@eEZcSuf6`pcfR}PTi<°9vO4*wDEwgPyk2l_8Z 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 z zR8SBo@lc-6Srn^9H7YP$BT9yhumm|{#f9ahi_e8+<1r7NnA@J~N)W3Woa3S=;-(7} zfD?2XXeb9s)Pd%L;KzGhy!7S+XXb)~8z;xtfa3BLa>h(}q$4=2&RI6xy$Kku_5@WHx6zjZcUiDcBWSlY25u=&S#9;k5JM@^JZEc5Ok40O z0g8=6VN!>00X2xQs@~{QCWa^@5;_uX4VZ&}kcv#g zLO|mJ(5ct5=XEW;d|bZ4X`mZqjJk53Iw?VT+@4ko9}??MCmRiUe7I<t zcuhXj&q_v7Y@x|%kpPG3%>Lm`uuZ*B&)pk(Ojfrbu!iWk=0)OFZwoE?Ljn+u9W7DOg&esPff;Z%i25_qI~srvFumhCvSkn}B}#TC|*#8zEJ4md6)N;7K^pVw=oDC>{ZyJE!M zi?<7+fS=!b9wgox^XuzV1I3`*>9<+Ul`V~h?HKsKliKAz~$1$L4MFR z=pOP6c?W&XYO~g?Hyh2S$z(Pp6NOaTT#hQ?0w<-Tka_ep0<7%1zT|nmr)VkoJ8n8AwD6auK~$Afzy~)HjLZNmK|C zqMH8KQTIQxW8SbihrjhJ)bL!%2*1vuF z75i&Lc(?1c_ib(@^0jiSRJ?4*4S~UGqWf3d+TF!UB2^EUM$QL*KtDPiRBe4-3S&gk zp|Dr6+F4K{tkH=N zic`dT7&Bs}`~BKY`!7Eg-_*0IV06Lt?;bSAW~MeANSAS}5{+pV1TX$ObUb^3x&)e% zvevkdNht9c!~!->KuR2OaY(B$Myo9rcO_6r7F@gx^>a1+AxcXljI4u7C)gH32KWif z;vGn$x;4xC5cV!MN=AiV+^OKn6DYqw_~!q()YW z0UF{OosRR{H{bh_Q(xZV_Bn}<2!6qTExxDwHq3koT_jC=Q<$mPGvP`)Q>_eTluC^& zN0d;I(?^J(2rHC<1bm1GE!x2xlrkBetUiL(ISDEC`Kg>Zkr`piL(OCbM z_Yn>CntmbJUs5%FcB(!pU18jlJZFmr^N04p&1T6|41#hTBe zrH*wt_l;;qjNn&uF1wLmA0EioJsd{KcwuB^V)F3Hq!{hia!JPpo!L}XbFuB~fB$YvDP)9-#y?bg~;ow&kE1ZIXtdq1o1ow8U0L@6L#97WfKrpJz!?KyHti#SAD5#+c2?mI^N?a=c^- z5YM2Oql9O`7J@vLBU}5;M5;Dx9>*X65|JuMGt^xSxB?6X!IUeX;JZFmy?rH?7K8ZB z2Jl2YITu@#E@Xb^kCkd$@>d+E>Ar*;%@|20khsg_YJXtG(2a^Gpr_y+|NK4kpaWr- zgc^mp&`DC=z(C5$TY5$AB4T!@oRPG07E`a;72 z&;`<^#bHEms5k*d0-g`(JvCt*ZDQzCCdMf0!nloqf^Q>}WhJeIbp%^&!iKAlO& z%@?I>n~kd{Dzlu9)BENdGuJ08mrXZUUKVrd7z1zfLq8#XvS6_XY`os+iw(6W9Pjz8*v{&WqI6&c(23_O=GG>YP7+fBzY?}Y0}1b z{%gS>1i^Q%qUOt+ivH|Zo=r}h{T`3Asg zrW3TK3ck+Pvo#q|omF)m`VRl7uBkTEkoD+yn!p0NU1agn&2+Eq*rM!ShcH%4=O-BJ z+_1E!);O!~#!k^0$hSvh^_x#yxWS-*m1e6Bli+iNYD3x01C~NEo1Gr5jR+iXv7eld z*#%QH8mS~Bqq7s!|4+2pL(gNg%h?GRTVbdp{vLR=1y(Tx;mjdvg@H*x8J~t}c@qj< zh6H{>^@%(I287>8o1B6Kjin}w08`E8yn(PcC%c`TJ0}Z}*9sHGK)9jRX;ox)@-{6! z4XObQiKa8)C(#dT*qVlBUM3Ez!UkLc-3PWo6+(t=#?e9|V2lb~=rW?V+12ZJdWJ2Ky1>#|II`kas5dwyYde5h1RkGZ}0t%5Wc zKl%Eprt!|}4<5R~5go}Ui|u%zX0tj0!DLqF!Rj~x!@H!RP%w~8WK%VoR}$c_Le*1A z@GM%lv832!9AQfx$QvlK-+qh*}Jj)2(x6D-SV zhYz1NT{7Vh`TRq3BmSb})ZwP*{Lm@6y;qi^ZZJ|uKcp>A&6&CG+=JJpTs^v3SPd8K zz3fO)mtAz56*kD(X~pd3S%x-=JlU`yyGbuBaq~35sYVFg6|zbIuVvG8MKwp9w2Nz9 zd<;Xe!AsX)aQD3j&b_#M#1!e|M`j!!!#JEIQNxGlHe7SwSvOyOYGQ6WKh?Oz6!wga zjf_cv71&iv(Xi{Rh_*=0ydfA?oNiWeI#@HOBn?~=hYe06XMo-;KH^9^on{&O6oV17 ziIyWAFVh*AFKIo~xSFPxLNP3)RLteqP?_;_2D>;o&uFX5)o|$chat^9{bjVu_s;q*>U6 z2SqF>=YhE0$|~CF^SEf5)PVMyO3`>u^n0TYBQJ7x z=Xt9tC0EKK*uS@S$3q8CzA+og6jzjz*>e|8UeNixuz$J~wBwtVWTBW)lz6d_c+MA2 zM7(0aFZc{Pm&?(Ktla9L>`s9(o;tH>ZK3Ut7(AV9ZJO~;73X22FJAl;;OqvF{w6vg zjU!*Orc^6jomS#W7D77KM=QLARd_R7MR6l$TrDK$LOd! z+6Mr1cfZXCKsyJ6u@H+*LB9Kn2LRdA)%cD~VQ%PWrGy8H&sOYBm0r!}5(Up9Dy2P3 zxcr@_6@D8ng1muufmc%RsQqkvB-sLj718z@ADP@`Z5Gj0*O!>C>mQ6Y*x!Vu|=vN|V@1UDfLbJ9>+|s++sM)=5+g@jw=8eDcs4c!NfC55bQEf(M~$ zaxyA#u&uJtQ3l$ak}I%EF3T#u0Gm@-BS$KP>;TFcA!ucNM%I8jRU;ebOmhQFp~)_f9`1t-+hAG-Rg#H?-TZzPT^Un`6&$j;K2y;j6pL9;dhaX{SFh z;CBGz9o-j>LH_O5ff@i3Qx*$m_>?HDd1%J2g5S!OHfNmj{{sB(81V0?iu)e`?u$|Y zP`@1MumuTl4lpM`CQ?lZRE_yD?Dki*huvj(jX{4X;I(H2ey6S2(FawS!iTEy;b*`O z%%WSQ%@8pSj7AhR%POrVN0JK=2*dLT*SCD8aUy)<%n$>ej7F!COpP&E0suBB;Q0fw zb~+Pi$K`UIzeB)sKmfBn1 zdcs>LJ6*t6S+3XU&vf66Lw?2;uxBBa9q;}!CXiP#pZe;1?w(|Ox@>b{V4YK+-#NJx zo5FUhJ6n1sn@>e6e}a55MA^O91y6TTdqcIXJ<*>FcFJY@%9X?Klu}L|gg~&f55)f# z;B6Ul4DA4vs_B09Q1L^5D73Mu?RtKi%Niq$ANGM50w!}VUq%5&b}+n*V!%3;am!UW zVN@>`#A(&&sj8Z^<`J*qcviTUlsn-az6H1ApsFp&?#q3R=INR`YiIUq>Kw9>SjnzZ zm2}qK^Bs;+xTe)t=blWd=fCBFLKBK>d%VI>#jf`@*->tXq+jr|N`-Jtz*0fT0v_)YP)0$SD zdeE`|wdkWxfqA%~ZhM9_eo^7(0(GJ3!u*8=IuVa0t30i^2Z%9+HWMhc#d(e{nKF=F zc0*fX$>AKRc1k59ErPK zPOL4$lDS;wqoh5(f(K@GNlzqVq-jQsI-$5ob$=fZ0q1QY5kt@Lk}plN#+50be^?%f zj)%sE;y&+u>OiUcc`HRbLRtL(vO!2ETZcR)&7&ULR*I445_M&K)Is1#7`zHVpDk1k zqom@5)?`2Q+w}Tu{EX9NgbgGVW;t6#bmnDGo|kc$ld%;VYoMkBUnHq=Jp6zGzy{!f z>LY;Lq&AoU@|OAGo;K6$IpE9I7bGLx;Pt>_fDw|iAxSK()+0*R zn-H!B`|5JnkCUyare^x)wcTn%Fa@ixg-wP)PowxT&6L(wCdNvsHp_94>P=%I7(UKp zSZ|jnN~Muz%m;ZnW;F2Yn!2PwPhs)*_*?jQ(1pH78mXZghHwPe{62dCXM*59a8l4M zC?!2B)v(ZHOC}#SpNBLJDGW!71=YZ?TpR#(kA_ zD+=eY%V#rb-bo3sFRV-jypeD`pKZiu7X+I%=6TsWI3xy~9)GA<7|+eGvO8TlXf(u& z-NnD)k5M0o{W1em#OX5Gye7nYO{@X7$(X&8(;EVhJFNY?CDU87L{m zo1|IN)r+aLN}?LLub7O@P87|-YlQQuR4APgR_q5~_HzNYIzH-qDb@YYdcH888Q36? z!%Y4ParrH;S??{PMHZ${6OSslbUE%9V-SLt9Z#k zx+n$==7>(ea>guJ#7B}=e{dmZp0U+d26?|*4;u_$!Frd;YJTO}xKrRjiCJ}YWahgE zqWNpSLAKNN>O}M$%y5F|!4sFpqSMMK;u8vO4s_>@6sfG`2l0K&-O_~+6#i;=|cI=$4r1k2rL^C$iLv>n)@j;J2$5IOk+ zXuKBiX9(R5wIPqS<@FSOEw!;S2@RG>Xyt&;WS=qJAcZti8)`r)4Pt5oO6v_3sHNrH z9!JFM3#aOhwA`xj1#<+tuN^+#YP96iX0uisQls|%9)4mBfNz9#{a<}>tLV@muJI1G zH}yHEWu-N&#EB0Mtb$&pW4&#p9Kw*G-2-Qxz#fB_FLZfbLA(%vo_4k-*?gXdO-#ri z+H}3!<8pOBAMlyR*V%l5ry~$DNH4w|gYGVHyRpHf=dGL8`gjMnSaf`J-_H}oMuO6{ zaqdHB`ph=fA=f!GYX}d22A+dg#n@hH*xQr+ zl!5U;ONQT3Xv(QFo6^Y+Ki@Q|p~(_(GOxP)+s(>;N#x$xvdM6nTb{|UrDi?J1g4VOX@6d3eIy-_Fd2539wEe4&$LrUCw1blkUg!H2l6&GsCm(+v6 zF~F*=fLt%exypG_zN^QjR`vWCkAKyD(|Ob6&sqE&b@k*A*zP3QJaKUtp9}pdX|y2K zl`yDSh!&w@gpf-J+e{9OTrqC|$^IBCC;gl^nbgS!fip-pogleL-2}4oV79g5l(qsO z?=O9EZ z#xtu|Q-6HV3u8H;bgN3~7OAa-L!2}1Kne@}&nV4@ZLA~VbVU6=4^)g~UzGKE5(yd# z-JEO%gKwpKRU*wvQ4^t>Fxmlf@aBs^GN`RSNyo@+H`QIC8tH^u!VbI@2>rw^Lg*k6 zKRvzYV*{1-m@4MQORKwwfI{bP=V}?YSpg6B3hRdKoxO!CBgG=naWQ(E`X>G|*y^<8 z2_Tz5OPoz$yb|pdU{jYs_NT)!51LxFzCgT2tr!4`fe1jHfIX}u2AcZj#x>z;U^S4Q zFDaW=2U?L8fuubT&AlgIZg)U8<*K3e*E(GlyM2BH!D)Ny-YEKEss%O;VGo>icPaWi z5JL=9y(PQaf1GaRa?^zfi|f(D633Y@AvFqrL<8n}l%&bSn_ReU_qD z#`>Rl;)sdfi18Cfd}HYzZ}dh?oG{|?r4hHm2#woto>rgRS~ZS(ZfVqadiQ}YvmW)@ zTz;}N;(JT?*|6+B7FZ3a)WE1|m8Q3S$FBvcnXoF&vPLshD+$fTrO!EW#KfF70z97H zOtcY%X6+tt^zM;3VFaOB8*v+q&}hyrn=8p%u2bjox;B?5$tPia?2`aUkl7?Fq>Y&9 zjqogel9u}X|may3qgxE z>N_XiNAtne*>2Wm3;Tu%ZyWtj`X3`EdLyzYj3Bes?(s%%ME-;kWVYIf+hByo+bS7D zW((RbzF5a!rv8lP;moat)^KZtY6k~0d)#nwJjkG=x=@0Z|yG$~P|DFX`1ljQm zcmOJIWDk8nvRaU2a0v*?Np{#TP0C4dVh`EK?l?B_mWR}kReM%zJv6*&#LqqG=4G*usJ=K7OZ?grT;$J+S3R9;;?y8D5N+knptwwnzoa0=)BN}EL zkkv|aY}H0vJ>EdI9JfN7CU2#AR!-AUQy_5!S%xJ~7*+wyFD#E1BdIBp{#guZs7#T_ zj#Q7+aQ2~UhDoXt_TKbLfTS_XgP$&sl!~Dyzt=XJXsvfz#-C^xH`>=vZMg5eM8iMt z_&Aj8!wIKJz%K`ea>-)M|5B8Lq z9S{q-X1+X|LaQu>W~bxId%dy<{e+ejYms>*O&J7PMg^_(1Y98@7J;XR+a7$0Gfbl4 z9@o^XS{y;Zt2IvdAWQf9TGVud`n=c5Lp(GH=^=8^xCv*vXk+><7vM~Iz`c&Qf7g~v zq5Np3ydtDCKXb*VOWLXYa6M$Hius||1Khn_D>2Xro+;y`x@8Ha(k#HvG}2G&e)XpMCZ zwWcZOn{1wzlS5pRm6ZrMYO%!ZQ*JelLRVTtwXYev|~QxS0=~amI(p10T?SlXGKAi*0H>c-Rf-D9hM95h%Nr zAef1;9+R(td`3NJqF^E}_+$?pK41(AQk=M|&~L4xlE9TnvRXkREiBNJ-rF7B!yIAo zF_i-i6y!2=E0OvVoJoLR^{yC<4Xv9T$TgDTNWx*ziP@>z!V3P&udKOf|JwV^;vn<~ zpSE}3n0I=lK3#$%&Ef&GNb9R&d3@()W&d^8&R#lZfsOH@7#w8`{RrUk>;w4v z=&og=;^=_2ZG+uvVvJR)&?W-?eT+D2s^XkMG}^3@_JB@~q&XQ%R{@>uZm@1Ra>q)` zrXgPKY9a~@EC_*>nnlxWjJE#>E)rZ3>J)hZB-Rz&xZGS-BXzTP)Upe)Z6;fw+MZ1UO04 z8NjiS0}Q{wMhan1E@cupcX_}Oi^N1{@oq6@qHMb1WO%@Yza@P5t+zgW_gkbD7wuep zjXvD7_$}yzm`x;esd~DS3|pg^?47W}VF9@?Z_Qzpv*yH{l)Ex_N6sL5D}n`Vl?&D@ zm2A}O>E4ElBCG}R7Sy#+4U&4`0Vy?Zg=Q4ej-sxJ>Nzbdn?q@8$&FZk90EyM^*S$m zhTK3O{?&sI{F?Am{O;X%fA_n0-}PqqfkU_4a>`HO|?P1l=m;%^c@i9bnw z5r2_-1;0YQO~0)Zhdmg>4tS`udAvfQR20gk@u`ZSbOt%4RN*GWN**@xhr*C+F>{X6 zu%TlpK@mkXgbaegWB|oOC5#S}Il;jHArK0WO~C;OxqO0YHpYjBr^Xu6cte=-NeQ3e zlpJunw`QYA8om!_^;!RwnjIs`Rr?}}r>}jMGOi>mON0d^;OwnrUn4L+4rd{&slgf) znuwDc*Q){n$--qtPY)!WAd5)K`P%4KyV+*InayHoZ_YVPw9WM?FBI+_S>6QyIe^=> z*9oa9+Q{)&wwu>L{SG_qAGg^l%DlqAmiocD{`v1aDQq@lm+hsw;3+o9GMY>jY)ZMu z#+oo?{=f&!n08w4w>roLOgV3^CB96;GxQ|%wLSoSt!C2KN@L=;nzg=GhguW_D*|TX z$<+BlXUG&dZH-7dlXsg0ujtRj;0$gwO{MT>sK-?wI4QX;v;zBupaI5gS9cH@6a;%t z;n;0(hRefw>+ta=arptB({R{ODiIE5ex3;g)2UD(L+$ftQo(R46NHm20`MDb3mjgh zs{`%~5O4ody19ZYRE4hSDti4GwESfC2GnGxhhkANo-36T)zx;%U9XX7>j4VszA-ZBAFp)mC$QY}7k7 zt(TjloIKrRr%|;mmCB^V<23Vn8Ray$5(M{{k;A-&jX z`JZU961G9{oS|WZf||3}>gR1o&$_86YaDmb1Z-J6w&l2qA2jIopED&DKj#Ri*zTVy znbFMOJhn8{b^UPG#?H2@f6_*BVLLgG;~(1b6Zk?rV`RHua!uS&kDB3_A+m8vryH4r zjiL^V(Fipgas&s)-Op+#Q;hF6P~A@-cUs3UKx0-Ge*rs4{|q(nC@MjXx2CtcO94el z!7;!A2$UFFfX$?gF>kUvkm!lIOL@0g$z$0BHC_=;(iF+z<)8-D0xz&fHB7)mje~@z zL;#6uTo$lEyaJA7k|vcxbq@oW7_B$fL-wCuafW0al^6cwk&E_?+D2wKcmM4@IQ?rb zIRLv*^#<(;tt0zU$Jg>}8XrCN(Kp6cn^)EEo$Nj&#?MfsZYui86rnlp>=SI z*S)ZtDFadf4!ZzH@Jd)Ga3(l|*CZj67C6I>A5im0@(>m#n^2kog-uSkRFlw$|N7U3 zzy9^FN5A&q%M0(kv+y!Bo3gX4zgZWB;+>E0~rM(bI)+}{PL&rb~c64xLB(2mMtWvA8QZ6n0f8D(acvMB! zKV0|r-ko%J_C2}jB;DyOo$hR%&f3{X8nTg%T?r&W1QJLBh$}EIC?cqgE6yyi0eed&sK0=?au3NY2)TvWdr%s(Z zCC^;WEG68@SIOH~;Z?!C8E+Lc=HvXh8fQ%6;`2ij5~D5op=pWHR$G2(W@2jeoH|hx_-;tX~`sNcJ@qPpe2xNebag>$^6OW_dxDHlW zaD1VGV+sTsM4Sq`BW+VX;bZZyXnz7OBl@v8T7DEyZQ5EVLCByLd|jr51CBa_5hnp*bLV9W zqoj#9L}_(Q$c0}H$z)86fkT=kcZotP z@&-6tR-9#dUXobE?Od)*94(ejUeq9`+pQWVwRn%a7AL!HswAT>A}6y92|k=2@O#gs%kl2WRuz>HvE zUM-jw<|E8vwn!GQrOh(evdpr^ve~lDvcqz~a?}!PsVFTdjLoiXNXe|PuFk8-mQS!` z$C_e=iN{#vbslaW;o~}iu~wxP4LH`I@qrH)Bpaix`G`W^bI`101QN*`G0-szE0ykm zF*e^a8($cob+Sd1s!5H(M|dmBXv%k_THPvBX@R>ot9Xh%3QmCG;lbi4NX!{-t68B` zKCDn@hv*DZ=BVEaHTu#0dJctqvXg5v4Jo*`s=$$vV^r#OVHG&>U{J@$MW-jkINXH= z55QM;>{SAeuw}%iSflnP&Q3&YxY%6bYrdvP!W@~w&hwV1BulCA9bqw=Go%b>hQgbg zY-FkCR8hxL1ugj}_bKAwSUfZ;g@vR>snb{pOoO26;+AZI9ssJz>o@LJIY6$!R2k4* zX#zH3w82dir6Nd(udkZZvt~`t++RJQP$$I3$0`(1f<`CCsKqxX)LC@2&!6AkK7U?& zZnW3p%xrEgw&1Rv(Ko4LnESDVqDaG-sK*U7?d)oAhs)p$afUjLMJ5%~8{+FC3Jn$6 z`lh-FUz@KqTOW~R(EIB2p+2u#-)8V?N;Qb6vt<^#1Xr}Vxz@)T9d5nD+!$R4*}x3T z!&+#ZNQMe<%N!EN&+Pf~bQ7F;xT8R52>24oBnFQ*6=5wJ^udVZP(g*%xCUk1S~GZX zLryLZ3xX;Z4t-VPetkitAt50>4Ts|$rm2&fr{RE9VRUp#WRiS7YIbh76y>w593DLy zDwSlH*2I_+R(1K739&fLQB_e{UZdkDp)yLGIM3`@mQz$;MF*#h#_*ZejEGQunj{~b ziinGdTQfJcxgpzIqM6cJ2uhp$FN@hChzdC?o1fq_M5mgRX}%P=$H-FZvUDjL0oM}6 zMJ1-eb3|ieR48lI+el^wfw)M85fYS>6-%;AC2KD+rMNZjz;aV<633LnvW&$Qn?mn( zs+82!bcL{aLz*QuO(9IKFqh@K?_Azi=Lsuuxwj3p2~`K&Fo#R1ifDT}U$%>Tr6sf} zt+(=mjrPeQK1*-KVu&qti_({38uXF|=)^AaHtX^*3*;AsN`=lsZ(&>E+`=`5+X@d9 zY72FFK0C}L!}3DCp#{dg(5g^Tr?A5}2`h|LTjL>uNrjQt`1p{=G%lFn}J(wO6o9;rVt5x7Xo}q{@pUITO!F3b2A9r?%arNy5X`fSDeRLQ4{(@B(pO`$UiSp`a)A{@>@JrjGb^42y#*&*anAGaD*$Pu}??G~i@THb|uCxp0)a2+ayO5n@ zt*>jE)Q~g7F0@wrDx37)hH7J>)yE)zTXT%ju|9olC_Gdc>lBq>=rq_B3K6boOJ!)9 zD|%9WgSW2USlQlK){3+B?a7UW-MT`JDr;ER6Bn{YBM zgVH6%2R>&J89!-gz){$9JE12HlT1jyRm9aD|ABuGVn*Rt*{VoGT?u@46of}anGHr= zL{fT2c%)X@RDW&wf9Ct+{&@zEAXX)pITK?|F)=1>ghFFUw%KrSc%gpof8-UUZT{uN z^YMkEXt7+AFyFA8xD{cbNdvRpK$Ba5Mg| z5<{9MksNCoSnHIqs`faYCL`VIXr58;X`SM&pJMd3R~fC|v~;6R?bTpgfSQ2_K4EDj z(;Ylb|AK0PF_CqwRdCV_DdfN z*|AnB%kC(fU?;1K%XQcTcCr^u&rn6{yv3c))cgo@1hrXsLRy+RN~P2)(!(?3-?x{R zS`%ZFrMT$0oWiuA0c~7)X>tONU2p^1mS&eAmL+eszPoFx&S=epX-x7C=KB+mc&_{DkF-m;y93`r70gR#1jH5hf zmWb6ADXn8P8aUULgTiwt&zX>r7iD;FFAB_wOR_~6Ui|oeeQJlhxZR?^F98Kk$@kPI z>2c$W0-n3SRosO;CTZ6=joH1i38|(ig)Y?)Wq|+nSUOAvt5&+>hF?5`$%+2X^ueAn zVRD)nZt&RXsFckkH2*x*ZFLvnZa^42p7}jydqfsPvW-$Lw>=^|6?<@95wK$-iy=y* z!QGc+pG0Z0gJ}X5LzE^zkcKRVC{3E21~hm2zgE5ic{dzBuU2>)BBK)G;ch+3Vl(9C zq-w0*)EuJ^-f_KA=w36RhS`38u(cZg^89W24y`3dc{4#ca%tS+or$^G%L#H*n^3Q8EbC}s?FfKHt5iG z^nrldOsToxg1aAHut2TkGTmuKH>Bqn+^JH7o&Ta(S9Y?+SaBAaxrmA6mDCtPz)kWrKqEWckO!y2Gmf~>HX0Xs zutONwPmCcNj2&E-9A{*v@Keo|mEO_gbdJXDUVFaPHz~WOMBUsKn-rfwBQ;|$3ttHm=yNWg z4diB@d^QM@>{}nH6(|2~YQ@PPW98H$?rVJzTM~4>Et^gDW=Gi5tk`nXr-kD74l}GC z^`U0+hLM6JQ_+&zn&wSRGn%o114S2~V*?^I4-=KSY&~(s6%(}l03|hJyEzkMg(vbe zT~z}uqLZ%BO46qme0X+*sD!0-!Q=~Yc_c8(O*`Wk`d5VTd*NxEz+;*i2Mj=WHi}%J_jS%X>Xg`GJBND3!^FS34L)I&pr%9bA z9FX0Ggc(UM%*>M6X;yfn%|@_M zv@=@K7>C393X?9bQAZX#ocxS59K=AfZev_>CATE136iX^Eji1clAM(-l;T>6Wcf#y z*qW7+Y|l(d&OSbM>b9(89?rr@&n?Nhb>3_cL(Q(oc^%n;tR`qdhE&||5Vz*8%xO}qg!O%>*uMujpWHOuKMDb?Y`FV2@`=_8_WwWp43x0TKkty3K@ zM5zs0l~Zp>_mnEDSbSr$O`q(FXN}QLtVtr2fdN%kH^^;6+Ydn}URYbw`Z8#uKubt$ z2=Y^pV<$k#^g!P98gJ3@0XTI`8A<)iEo=%&nkA@G&7;o;%?}>Gw4*JhBrCf#H#y$r z5=9KRbk6(P2sj-UZj22bea->bf#xymgT_f0I~;M@C64Sw7aaO^)u!i|0>{6RD8|M; zHWQtGEq;JAcyqjEIJKhl<>u((65#zCt824Pr}5#kf?RC|vj_?5Fs(+dEi%AIlOwNC z-&kaYMS&iyn}|6WaxErWPLd!|`ZI%!n1VBj5GLG^5Sf#y><^nJ z=o2T9;_eLzuExGM>wDa&h>gh`w+#o{WoK zot@K{f8L~m8Pn^}KQCwbP%JWF;eCr2rwpBUUcvO$t7HEsV@eu(`GxZVE0g@-ZH%XVM#)s$!1eU05rDNG4oLqzuxUWB{pAHpn+ zJ2s6fg_fpeEsn1Qrei)6qfxQu`^Bj?-h}&FxwvrQ#Hp2J0Nl9rG|!!609zU~xUv9% zl9H&TByGHwO8W&NfW!dKQT*!{aQH5b95|?bXGoulbq&yo<_#WIsvD% z%c~vBD|sw0?zx%cB(KCa^0OP~TCEW+JGM0~A*8O8RK{5!`jblV-Ndl`r zqPLt+?O0jkb(7DCP@0kejh+qUQ#n?aoQCj`(;Q`Vj)eBHi_S_jo=+|NCXl8;PJ>>_ z&nO6V-&npkutl}(3D-)bm1e~j!aX>mSr;^Mv zS5ym|#b>ZX9_=-lR8W_yjDmtG^A3^)40jkumI?*JX2ZsfhNa!2QM+J)_Hq7Zf^d)c zBwEwwbt=pu8eG$&*Z9nOojC;eIENaQUNhaYr-9466!>eXV&^jz-BCh!JVRLkfzjp6 zg9}&~+&l}-h50z-WKtLLVH^Il3i$TeZYfzCW^(75=BZ0VDG+_W*b<%OtBNnc2YB>~ z6{x{A@)}F@;&2$Q>4an&xSba}^1VWiSkcskw2N^ralQB|{Nh=?QG!ydfd@Y3Gblq1 zjT$WkCOVxDbPmFIr7X)v@Eb0JcWEy+sU{T^O;VetR(e~+SF9z)_Kt;p$alAxAykQv z{QHr0cP6ZatVxM>@q&cR%!H&&JI20EqDkn*U8JO6ad@R^VS-6#GUe&=OiCZ_bn!(g zLZceh;h}!D!1v4M5PrN}=0tGA(ZIrYf{JBNdSYTmMq*;Ry)q}KswyYDN?Zw}+@!>e z^rYNUk0Yn7j9UIiXc7DIZGnH8i?u8sS8>~6DCfaO>||jkn<*@2i-px}wXlJ05bj`i z2;13q97_8Wgpe4eIntbNE;QGfJI%f35%U%1E#`a72D6mp)5qwT9=8$d+w^mxf=?2R zdJ~JcM5PL$mKY%>!b`gUcrZnLUVK&jrg$Z(LdfnP6elSFtEM@`<$O!P{XeP%-9P63 zlA5nsC_lIIZUJh&!k;KqU~~v)iC$w&xL{I4-~`{Az?)|H+=F~Vl1M7qazF)1x;uGE z=@w#hQ)46Hu|2W^H@4I@r#YpV#B@zgp50=v;S%axF$x^{D*9A{7w0-nxOq=h8bvR5 z6BK#Wesf4A2)8NF&AElmOS_kbZrCUudi-%s-vZiM=bo_nzIibpeU8DKm^`wSjEyYZ zlL6m1r=^FQ9W%)`G$nz3a}jej<2OWwqwmf1mV}2z`)qI;gkzBr(b3G8f^AuwMyIq9 zS~hJ8yjlo2T^=5tqG$|B3vG;0=pq`U;UbBve}iqqr&?+-l9AC`s0PW$!F!@$xRj>g zMlH}#6^&gc6}T)#xO$WR%HVxbZMZw?^riaYGq02yofRm69bjIb`8r$da_?0*m?U_>7q8Ayd-}tKzl| z4BvjspfOS>ni4-tD46b@0=ija88q)&iWyHXCEY@*^CUiVK!kuf6Nq z!6jF#l!~-`l1b#1FwHmeN_ZpN8Q`3XAm;?u)O2c2UQ=&uk~yb-jB`k8Ndryw%+2O{ ztKB{WZfzmnp&R00(CSN3hZ<56QnFJNK2=z#Sp}mb8w@N|PD2PwaawI4YN}2h*60ia zX>oN9NXuwZ>`~vn-R}I`?H>uauH(ap)Aj@FJZrC0U=E;R}z@=`s}Ah73&#j-we( zVa~YZREs0F$XT47jYuISPI8iF6P6BeStu{U19pM5=ma;(6FIg&(Um|Su72Y^io3v( zx2m{JPvqJDZzc|kEG2nOx3Zhz-Nv9%X+)(~ zugxnrA1{Zn0LTp%!2Q_bKzFdYg?m5ny#K!EgZBvv>nK$E!3U-9f8fE+>rXg6bqv}V z7u)FVROje4cEN5nr-fRrc~UH#{fUWEgu<1l2(_l!bCgLoojTO4OfYD&VzNX{dQ7^Q zm7bNJ$)IUcT8+}r!edCQcQOfSoBZ69?hU}zav0j5Hs8t%K_QJPtHqY$vJ6O`eEisPSM-&L^ z7NNCOXn}*2&wlue@DbjBjdh9FiblwH*|__n>1y#7xG;qSdnJ^j2DMUY3`veiON=Uy zOM}Y{h0(4GDc9OVRf=SI9ae@IBcdRAC8(t&WjT}do4{yc(FWXBSRQ6YpD8!vKMXB- zV65GO@n=Q@OWe~2PZAm%4ZFmCw4w(O#!&Nd>yL@25X5VvqO7?#PphRWDbrz#ipsJ% zG85~pKDRB`nsuJ9ptz~2px7tmrj;jW=2&xMqOCcZQbl@WWx6XfIx;KMm0s0Q*xKaI zpWFbnsgJOD>A;lpP32!Rz2YQd*nR8oO``8V+`MR~fBNVVG`T@)e$w{7i-)DI{8@;NSQ1N2p~v!YY=a5Lkiu9CIPZM8)e^6&{B8_Bxw_ zk6C!1Srygn68L+u2yskFE50m?$PPqj-(~OQ93@ z98dONAdVnB)&G-X7t@OynNBQ4+QleiKE4?)K>iSPyvaW*Ug!Tt_|E^OA{)<={QnZZ z@qZvf5)v+9lCY2M#qK1$&rZlLLEH$x zi67uaxCK9G(==S{87@|^ctw`~Be5G=`zEy46pYLl!AaLi)`w3o&gR)cryclAQeNP{ znbVuv5qJ~L6zQPdR{sy2cJv$V#%U)pCnN%wA_sLLJT3rzYVjNGFJ9q)irS0Q?4K-4 z_$PSdBrGw(lVfy2yQ;Kk+qq~Dv=#LL;YI9|yvQQhNz5B3Sp?<9>5DdI_xq;{^~kH9 z*~DAXe(*WY>j++@wDcaQH)tLFCc1O}A|4BTc>Pc|{pMk`2k{hrIE}x8y`uc-#rI-- zcH^@Nb-5AWEAW{ctQ+__QmjPZ0Dgq0!h!M@`M&_(*NI>Ie-fTzF~k#!A#SCL-fMgm z2YHr-pihh2uzRBNcSB+zm=3rDCkRyjBapsT{=LvvtNf>!599gG?DtHE_?;Z)!E4D8 zq}L;T5#TB0p!bg;r5-6A{Hck@#N*UUIpRau0JDc)66rWQ0$%7Npd(E`tKs_u*DO`Z~6R?=0n0SPbpk9#V zF*Z`nWQ4y0H7I2Z!lzJ*8J?NC_|s`Tr5o@Bu%f4#JmpLtp2g$MfO~-_JsspvJqRCT zTX_!KIm`o$0!=914tNrjq4cFJ3{+~Nc0jpd$lcCkx&Z%(G-1Fh9^v~yy)ceL7-&+C z@LteA47HdEcnGaSPu+l9L76a6W;Ty6;qm!^r`cu>^?=mk6ypKhiuR@O4!~|ugTe)X z>p@#e8PCFjGq4B5-FUzx9PkKYVt`v1;?TMrCILnwo?tmkLV6E}@f?;0U^0&tMIWtbI^ z&%GQz%;VjF$3a!f;rDro?s~> z=wOBXX(6X%5n?>Jlb)UuEM~=kd4LCjvm0Z2I&-56+3LY*7 z{2V6)+@Rqmz(e3DHz;5RJOSQt`=19j+)N1`pqP6Bj{y_P;bFi-XjzKMV(&drgP|HUbYS6f*1YP&FYXtIp9HzQFTb^0sJGz+dA~Y z5*}j*JOs|9G%g-fz+-0c@Fc)*F;dm}zegL@`5(g=NcrRf9s}le7|**{J@B6mcp7<5 z0_+0(0eMo`4fq6Fgu=5p+y&b+YTpLL%;vC!!!E!dkfsswEr35D4TbH1PoNf!z;G9b zGkAO{;11+KXq%#eAtLOrZXQ>`T#${Taytk2ZW3a_#<$h?Efe5 zpNy93VpDj1ry$L2gsB!&z{z&jg!+~Oeu8(KKtm7UNjz-=l?nifdz+ENWSppP!@Dhr z=>q&7DO-7N1ZVPa0h@}H9@Y+QX8=+y2o?Yy0tMPR1t?}0!UvHL#gqb4?I^yS$Is?r zJKz(*gy1Y5Q^H|6>j1ZOu}-{O4oLNde2P-KPH`6;*;qpeHtKfAjPW;TQ4IRo#eBYX_` zP|P$Q-UWD?wF7<&oM-qygU1mHI{@DU9cF+^ck-AnK;n}b{tr=i%E8QL@_c6ck0O31 z;_CtF-I@LmfDb+G0;FX$PctXX9xXk9Pomz#xgBEheL_5`h(^naQ7e0FQur zvoRlK@R%aNlc3CO)F=<|6fmb!e1LxkZWPl3_%UihrL=Nb!sY;nF2En~?i_excLRQk zx8_2V6c1PqUR?&Rh-bf|Ie=~A+_ecgs}Q~qId1}|?c(8`9F_pSfwrbJzvnS_z^9NC z#proV0pJnLwvfHd!K#b{OnNORd%j82mQzsI{Q3YX+iSpGfCrHe!4e+h0o;L72+ra$1%NcFP7)|dANf^9fys8#Nh<9 zIIQRKTY1=r8r%%-rKd%JUn1vSz{CVN0vrgo01}r{d>h~iHkHF^JbpSL&AbFl;alPxVkLkHk#R$e*r0xAgRcItJprFQWzEYD25eV6n|3uO*yFCqI_2Q zj`BN|UNu>DwQ5xTh(@EiMeERR(rI;9>7LXp^hx?D`UU#$43C7^LUxCmLKlbr)41GZ zF#W;wow+?sAJ!Lc2)`}--H67B*CQ{CVo_6~_D07}9dn$9@*4jZ2QJ zihCu#D}Gx-V#4Btzb5`RDLv`>WR|=w`Q4NaDL+bH>4nsq)Q2oK%M#10Y1wIiN}rSd zenxu6uQG1S_{mykZMDv~j##g<-fG=$Jz#ysdcyjpO>K*@W!Xw?Q*5(sOKodxH`wm7 z{lWH}?Je6$+jp7zOz8MBt1{a%dooAtnf6)sSF*0o&dr{j{fC^o+|=Cr9M?J?a-7K9 z>vTA0IhQ&wb2(gl^V{-!@`v-UD40^Pr*LWEYemzGZZG;nafv(BeY8YZQd_bSf4?o+ zS@Mi$n&*V)yHa!MaOsgUMOk6ly0TxFJy^E4?5}0tmS0z)t+ZE8s$5ZdwDLsdS5@k& z_^O<$%Br@i-l~;V>#J_B+FrH4>S)!8s;|5S-Zt+R??c`tVSuf2f|v6kq-sJI%b4*i-HMC zDm#Q7=V3Z0VP^l}VKtBco`*FQFOc3DoA5jw&BHoibX>3o!npBWB-?U9Njg)b7#RpF z5N`>Dl?dkt!Yb%%Y64+3lf;>Uu$DE67X`vPmI!^1oTpxG7Ekc79{Go8$;+&uG!Q=8 zQ63JVc%6}ljXWIB!*m;fQ77X`enrA{bgofQ(!FCLaJNBWx{J%KYvr#{a_y zC6~vOFV*%8jr0vkR;hMypik;ty{u324a|2)fyX?eV{plek^aGf;T-u{+u#uY8BEmN zKYwU&cyPf8G8tOtkgAs~k%sygE*cq@hWdv4hF13VI_j77EnCzxFw)+)aK)0Iq2SNp zcX!{=FiMbIjv`kuE;o?&oH%rh^bag-?^&JtkksvRIGv8>o{^D7eX9Z$!k9nEhS*Zp z!{RSiJcZ8_ioJ^M>_H|$w)WsJ zAE8>FY6LkA;g^-i4C3uRggV)3wv2~-h?$SMO*-rC@f01vUud{^xX{*69aT79xip z&^I;Jf_ilGl4#b#iV5)}_*(>AR&gp2=5h=DyJr&eC7J|VkEkdG@{zzdMA;EYfXk3u z4^K-JqZGkb?nQ}I_l3ZZXe#GMxeS7W#2C~D_ z5u)5yA#NF-6F zo5UAXzhRCQVHA8TSSDdM$Z5P{EH%+-2ye=HQhg-;{%U+vxzs9zBjG_c?gK^7q?=6B zzA-)ww#PiYKgbrNq>0pPK<>oZ{rE<2MV|AJ=Y0GkI{#0tDS@7Y_yqYoNNd8rk6j2z z?J!Q^GkJpg1n~szzBvI`;~m06#*oGv;=ffK59&|U$E2V21(`mCc|YZ+MFm(c~S}TC?}6s z#B=o4lE5>{KiJnN_6E6E$ebl}??igZElym!0yL9*2K7mq_Ec}`O>ztQc!~AAZxR>u z@tT~wz2&iCF@ImC5aA||sWhh$e-r0P$Sv4&s4R(>Jj9<5gC}L05q|ybB8~~wP42fu zli=tZ50rgl!|&!CrYIGO>R56 zSIYRy{4CcY$WK3STbUX`yydp&LvGZYsiYCWMZEllC{5;4nq7$hs3qi1~BT;TS zu%jk-d+<#o(8T8x!vmntgx|_!B`)?;HYh6qJ!4O( z1me&MDbEViI6}1_0PfW&aR^kSalYrQbmywsnb?zD&;R)^#=7!c|2{$_ojHQ3FLW;O zj|F)jhMUmp!z&A9dDsbHB^-|3+eqw^MPp|vmc>C|lK`Dj5_T$5K=oAEj;3LCoB`>` z20e})YxZpPv|O}79>z`h?ZUdX5OM-`0kA6eU`1PoRcZyRgf*}ib*zCTQwPqOgx%yu z$V8K&8EC>R*8)va8&>Y^XoXJbUAjrLhn4V5Xe?&4IqW>x63+!)=7AfDTNYsCBd)vv zv&a(kDx%;ra2@rm5m0d@IOjsN(naiISl3^QRnFyX4O`3BLH~3GyAms%tJ!*X4ZD_Y zzY9FZ&aFlI>?tu>=gTyea8MN zi0ldMmhV&6uNWF+UR%1>f-8HHwTU<{5vzsykv3dw)*7`TFw@d%)mo)i#O;D?%8mo` z*_3(Gj?*1!dj$Q|nLAWzHNuYYDQrq-%@a7MaNx>~(L2@Z`W@Q2b+FPq`(NzN#>V>o z9o`LfJAFPm0MCr|i*`)K$Gc(f4k@i}hZ^Dbz;8=hoy>y*cuwG)$0ASQJ5r90eA~G$ z@=dia>#D}9z6ljH;&m-y?5l-QZ&JeX$ej=(=%sE%B&sGacVVzqPl-t^!ZO)tt zF^P92uSo=t(O)b0gJfoTOzi{L;m;|ZnV-^p<>LJd^I{K9`SDp{+7*}Oy}E6k`3C1Y z(d%3Xx1VOk^PAlNbz|mx<$sEQWZm}*&CbvcpnMPJQc#TjHLqd~4O(=W5^m;@$TS-TkW#FIGQYVQFl9D=xU^uB-O-Uii%Y`74IP9y)I=XL|h_DiTwDvcy6lapmHPK_t(K)nYctmRH8(B3tv^dCChM%!j zjx$SUtF-Yq`NU6*}|f)Y&bqQj@Q`#@FQQoFP@$ z*4DRm*4O1one*))w-n4uW?jyOZfB7z-{~ec1Q+7Gb$$W(kpKL@zXJb`hhK9@|6FuQ zPOf8Z;!gFh`whFpLZ`jmacsrkUMR@g_4;Yutimrp**vNXIr?7-GoLv8@#*zD?>umI z#(!Tr-8_83g)c6T`sumpr|l0_j zjL#zH{{N4Ox4YmUTkajn!44pGo~thfyQ?AMm%8i!qkb0b7Q*WNj?1^BSM z0Yk~vG%P>d^XX%cY~0+i`JKnY&g*|ifBC%4YS-Z-{`EIZddpY3<&)RdRd+se*M&1r zefQ)1`qn*$0q5s;6+fJ-d+%R^wueKf&Q%q)UVfyr_2}-Lnq!8e8~2>&|KpmYf4ljy z%Pqbd^ODzY-63?}{mjdb-`5xD?E zFP;0tZRg+9|A*HuUY0#CExAsb`unt~=SRfvd|%k&XK%l1d672z^rqwQKYsJc4fjv^ z+wfl+b$9M~d&ApNHy%>_U6;|V{<2OtvPb}v9imyefR4uS9a9*e~J9`-5sBFRWF;An{%0So%S(&lC~+}9Y8d9 zg|7d)syF(rkYRSL{>JFSi5UMc&h8#(fosC-?sOKqaOsUayRQ@G{C_TDxF$L4WTvlJ zwQ7}PC4`n?2rZ8JgG=*<`j!n2_m2z?tc(cj@3juPfP^NHL1YsPXJcIXyVUvkg8s z{KE5p+llT;nXhQL@VW<{?7r;Z%Dc9=>464 zKHhM6??|@#^(!r|q;J(TZa27R{pP#6-Bq)XKXRvcu5D)Qw8?S9B`b?R+v$;1+p=Hi zEO+hE@3Q>xm%gocpK7Q%`O@_-Ev#D7Y#DlC@|(ww-?-?R5~y)|fB8`NLOge_C|wmnAO^lzm}X_q+N3 z3j*T0pUcUqgcYtt^ebbWkxr80$K`f-eAldD=xj)$SE`+;h#K;?vUoxoxQOs8*D2Ew zowCio#p;ZS-Vd0Sm&btVQGFJb}tt6&+i%OllnR15>xaI zOW@w2z6E_leFO9Ra-^PtUa22D7%PU6Y*-o|8S0-uvShV>c*VR6`sR;FBZD~-HXOzz zBB^#PU*g-gp`Q68Bwaz=8tGfwH!vb)0u#F){V1^0;Y1-Td-|93%v(a3oSEBr50iRE zO7*`~(K5oiK6fdyK{^Q~>?G95kbyQ;yXa? z@(xgYa0f`Lt#9wF_OirLK;8sdW;9z7C$9Z<4RJy0c!w&yLP^Uu|d845_25W^#RPr_|X>ujsq$ z+kG9rhL#EGeXT80TYGhFr?0ji?;(Tc`j$?I#EbBCbabISsk*DPv9%pCus(>STqJ5B z`I_6Bd;y&6r?<7&cXUYOwE_`ZYMZ+1D3|eAJ@9U>Z?A1c)q~P?Yr8bb*V#g^PeQm_ zYO8JsQe92e?NVD;ds}NqeGVtgG+$Gb)Y96iuc_xmYO3ci)V8*C)KBdK^1kY(9K6!v z>-2R8-U*OfY6TVArMl|o>W2CbhtyGDuP0K1Rd^nC^=Oo)4p169fFt13VQFx|*}S;0 ze;BLSzFuiyaDdoqL4RLwhujgWN6<6otw0CT_g#qhIdiY%jL528WjNL0ONtXxK+F;8f~czG{d5?&39tzr_6$=b<3C zFBx1o=vdglz*$TKi9(s@%ynjOvv0Fql|k8Huoy;~{^sN5|C+q)+u0?Ks1GNZPPf-Q zdjD~@bf~9r!NIO)yPiJ!>m%5hh+WBG5FBu z|5$qY)pwq{{f_vOKRmkR!zqca?@v!W@^0AU$8H&&y6(p}PknOagPYGw-FNzfceY?fS^?($`o53_!ER(%_yomuE(XR`iWv?>lc|D?@Zvu3cl9v+dNamp$<9HLiJE zryl&*g;(60)A8lWTOQv3!gEVEH@~puwFg$`mfp7d9oIK&{^dS;aOS(t_(PH52fldj zD(hnfFDHgYyPvjHp33Y>Tw5`3mQeA|-=Ew6+U2_=-Wq=Ur#nJ^ciHpaqgUIW(rZ6@ zA?3#@)4rSYR__nGnx9-z%THH-8)ba4F64LXgrm?py);f9wQHTQ4^dB0yRY5zfBho+ zm)41A^3Dur?06LwF2mRljR4LGssVK>mx+`N&f@$+S4pAESvd1&ob#uxLis~?etBPw z|LEM?{C`vZyiJ#Mc5APhYP05kbL|_q=dAXPSSqJ~x-;S1AC!@6pW44h`OqIPo_pz? z%T7C7FMK-vsja6xwxQ8?Gt3c}Uw7>duXwIov^@1UJMwRSZ|LLwH+_EKK+B5vE>C|z zzdyVDu@|4XvO+ac#mqwv%?qP`mX=u->ttsw5{jJO^p2? D_wy^5 literal 0 HcmV?d00001 diff --git a/install.php b/install.php new file mode 100644 index 0000000..e69de29 diff --git a/lib/api.php b/lib/api.php new file mode 100644 index 0000000..1144f94 --- /dev/null +++ b/lib/api.php @@ -0,0 +1,621 @@ + "", + "apiPassword" => "", + "apiUrl" => "https://panel.myownfreehost.net:2087/xml-api/", + "plan" => [], + ); + + public function __construct() + { + $this->initialize(); + } + + /** + * Initialize with config + * + * @param array $parameters + * @return $this + */ + public function initialize(array $parameters = []) + { + $this->parameters = $parameters; + + // set default parameters + foreach (array_replace($this->config, $parameters) as $key => $value) { + $this->setParameter($key, $value); + } + + return $this; + } + + /** + * Create a new api + * + * @param array $parameters + * @return Api + */ + public static function init(array $parameters = []) + { + $api = new self(); + $api->initialize($parameters); + return $api; + } + + /** + * Get a single parameter. + * + * @param string $key The parameter key + * @return mixed + */ + protected function getParameter($key) + { + if (isset($this->parameters[$key])) { + return $this->parameters[$key]; + } else { + return null; + } + } + + /** + * Set a single parameter + * + * @param string $key The parameter key + * @param mixed $value The value to set + * @return $this + * @throws RuntimeException if a request parameter is modified after the request has been sent. + */ + protected function setParameter($key, $value) + { + $this->parameters[$key] = $value; + return $this; + } + + public function setApiUsername($value) + { + return $this->setParameter("apiUsername", $value); + } + + public function getApiUsername() + { + return $this->getParameter("apiUsername"); + } + + public function setApiPassword($value) + { + return $this->setParameter("apiPassword", $value); + } + + public function getApiPassword() + { + return $this->getParameter("apiPassword"); + } + + public function setPlan($value) + { + return $this->setParameter("plan", $value); + } + + public function getPlan() + { + return $this->getParameter("plan"); + } + + public function setApiUrl($value) + { + return $this->setParameter("apiUrl", $value); + } + + public function getApiUrl() + { + return $this->getParameter("apiUrl"); + } + + public function getDomain() + { + return $this->getParameter("domain"); + } + + public function setDomain($value) + { + return $this->setParameter("domain", $value); + } + public function getPassword() + { + return $this->getParameter("password"); + } + + public function setPassword($value) + { + return $this->setParameter("password", $value); + } + + public function getUserName() + { + return $this->getParameter("username"); + } + + public function setUserName($value) + { + return $this->setParameter("username", $value); + } + + public function getEmail() + { + return $this->getParameter("email"); + } + + public function setEmail($value) + { + return $this->setParameter("email", $value); + } + + public function getReason() + { + return $this->getParameter('reason'); + } + + public function setReason($value) + { + return $this->setParameter('reason', $value); + } + + public function httpAuthGet($url, $param = []) + { + if (!is_array($param)) { + throw new Exception("parameters must is a array"); + } + $authstr = "WHM " . $this->getApiUsername() . ":" . $this->getApiPassword(); + $curlheaders = [ + "Authorization: " . $authstr, + "cache-control: no-cache" + ]; + $p = ""; + foreach ($param as $key => $value) { + $p = $p . $key . "=" . $value . "&"; + } + if (preg_match('/\?[\d\D]+/', $url)) { //matched ?c + $p = "&" . $p; + } else if (preg_match('/\?$/', $url)) { //matched ?$ + $p = $p; + } else { + $p = "?" . $p; + } + $p = preg_replace('/&$/', "", $p); + $url = $url . $p; + echo $url; + $http = curl_init($url); + curl_setopt($http, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($http, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($http, CURLOPT_RETURNTRANSFER, 1); + // curl_setopt($http, CURLOPT_HEADER, 1); + curl_setopt($http, CURLOPT_HTTPHEADER, $curlheaders); + $res = curl_exec($http); + $this->response = $res; + $this->parseResponse(); + curl_close($http); + } + + /* + * http get method + */ + public function httpGet($url, $param = []) + { + if (!is_array($param)) { + throw new Exception("parameters must is a array"); + } + $authstr = "WHM " . $this->getApiUsername() . ":" . $this->getApiPassword(); + $curlheaders = [ + "Authorization: " . $authstr, + "cache-control: no-cache" + ]; + $p = ""; + foreach ($param as $key => $value) { + $p = $p . $key . "=" . $value . "&"; + } + if (preg_match('/\?[\d\D]+/', $url)) { //matched ?c + $p = "&" . $p; + } else if (preg_match('/\?$/', $url)) { //matched ?$ + $p = $p; + } else { + $p = "?" . $p; + } + $p = preg_replace('/&$/', "", $p); + $url = $url . $p; + //echo $url; + $http = curl_init($url); + curl_setopt($http, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($http, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($http, CURLOPT_RETURNTRANSFER, 1); + // curl_setopt($http, CURLOPT_HEADER, 1); + curl_setopt($http, CURLOPT_HTTPHEADER, $curlheaders); + $res = curl_exec($http); + curl_close($http); + // return explode("\r\n\r\n", $res, 2)[1]; + return $res; + } + + protected function parseResponse() + { + $data = (string)$this->response; + + if (strpos(trim($data), '<') !== 0) { + $this->data = null; + } else { + $this->data = $this->xmlToArray((array)simplexml_load_string($data)); + } + } + + /** + * Recursively convert a SimpleXMLElement array to regular arrays + * + * @param array $input + * @return array + */ + protected function xmlToArray($input) + { + foreach ($input as $key => $value) { + if ($value instanceof \SimpleXMLElement) { + $value = (array)$value; + } + + if (is_array($value)) { + $input[$key] = $this->xmlToArray($value); + } + } + + return $input; + } + + /** + * Get the response data. + * + * @return array|null + */ + public function getData() + { + return $this->data; + } + + /** + * Whether the action was successful + * 成功信息 + * + * @return bool + */ + public function isSuccessful() + { + if ($this->getData() && isset($this->getData()['result']['status'])) { + return $this->getData()['result']['status'] == 1; + } else { + return false; + } + } + + /** + * Create a new account + * + * Parameters: + * - username: A custom account username, max. 8 characters of letters and numbers + * - password: The FTP/control panel/database password for the account + * - email: The contact e-mail address of the owner + * - domain: The primary domain name of the account + * - plan: The hosting plan to create the acccount on + * + * @param array $parameters + * @return string + */ + public function createAccount(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = [ + "username" => $this->getUsername(), + "password" => $this->getPassword(), + "contactemail" => $this->getEmail(), + "domain" => $this->getDomain(), + "plan_name" => $this->getPlan(), + ]; + // The email address is a required field. + // The username is invalid (Only letters and numbers 8 characters maximum 12) + // The username is invalid (Only letters and numbers). + // The username is invalid (8 characters maximum 18 (uiisc_test_whm_api)) + // print_r($data); + $this->httpAuthGet($this->getApiUrl() . "createacct", $data); + $msg = "Sorry, an error has occurred. Please try again in a few minutes."; + if ((int)$this->isSuccessful() == 0) { + if (is_array($this->data) && isset($this->data['result']['statusmsg'])) { + print_r("-2"); + if (strlen((string)trim($this->data['result']['statusmsg'])) > 0) { + $msg = trim($this->data['result']['statusmsg']); + } + } elseif ((int)trim($this->response) > 0) { + print_r("-3-"); + $msg = (string)trim($this->response); + } else { + print_r("-000-"); + } + $this->message = [0, $msg]; + } elseif ((int)$this->isSuccessful() == 1) { + if (is_array($this->data) && isset($this->data['result']['statusmsg']) && strlen((string)trim($this->data['result']['statusmsg'])) > 0) { + $this->message = [ + 1, "The account " . $data["username"] . " has been created successfully. Keep the account info in a safe place.", + [ + "account" => $data["username"], + "panel_username" => isset($this->data['result']['options']['vpusername']) ? $this->data['result']['options']['vpusername'] : null, + "password" => $data["password"], + "domain" => $data["domain"], + "email" => $data["contactemail"], + "plan " => $data["plan_name"], + "panel_url" => "http://cpanel.uiisc.com", + "note" => "Remember to wait 5 minutes for your account to be completely created on the server" + ] + ]; + } else { + $this->message = [1, "The account " . $data["username"] . " has been created successfully"]; + } + } else { + $this->message = [0, $msg]; + } + } + + /** + * Suspend account + * + * Parameters: + * - username: The custom username or userid + * - reason: The reason why the account was suspended + * + * @param array $parameters + * @return array + */ + public function suspend(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = ["user" => $this->getUsername(), "reason" => $this->getReason()]; + // $this->response = + $this->httpAuthGet($this->getApiUrl() . "suspendacct", $data); + // $this->parseResponse(); + print_r("\n----response----\n"); + print_r($this->response); + print_r("\n----data----\n"); + print_r($this->data); + $msg = "Sorry an error has occurred please try again in a few minutes."; + if ((int)$this->isSuccessful() == 0) { + if (is_array($this->data) && isset($this->data['result']['statusmsg'])) { + $msg = trim((string)$this->data['result']['statusmsg']); + if (preg_match('/account is NOT currently suspended \(status : (\w*) \)/', $msg, $matches)) { + if (trim($matches[1]) == '') { + $msg = "The account " . $data["user"] . " is NOT currently suspended"; + } else { + $msg = "The account " . $data["user"] . " is " . trim($matches[1]); + } + } + } elseif (strlen((string)$this->response) > 0) { + $msg = trim((string)$this->response); + } + $this->message = [0, $msg]; + } elseif ((int)$this->isSuccessful() == 1) { + if (is_array($this->data) && isset($this->data['result']['statusmsg'])) { + $msg = "The account " . $data["user"] . " has been suspended successfully.
- Remember that in 30 days the account will be completely removed from the server."; + } elseif (strlen((string)$this->response) > 0) { + $msg = trim((string)$this->response); + } + $this->message = [1, $msg]; + } else { + $this->message = [1, $msg]; + } + } + + /** + * Unsuspend account + * + * Parameters: + * - username: The custom username or userid + * + * @param array $parameters + * @return array + */ + public function unsuspend(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = ["user" => $this->getUsername()]; + $this->httpAuthGet($this->getApiUrl() . "unsuspendacct", $data); + // print_r("\n----response----\n"); + // print_r($this->response); + // print_r("\n----data----\n"); + // print_r($this->data); + $msg = "Sorry an error has occurred please try again in a few minutes."; + if ((int)$this->isSuccessful() == 0) { + if (is_array($this->data) && isset($this->data['result']['statusmsg'])) { + $msg = trim((string)$this->data['result']['statusmsg']); + if (preg_match('/account is NOT currently suspended \(status : (\w*) \)/', $msg, $matches)) { + if (trim($matches[1]) == '') { + $msg = "The account " . $data["user"] . " is NOT currently suspended"; + } else { + // This account is NOT currently suspended (status : r ) . . + $msg = "The account " . $data["user"] . " is NOT currently suspended status: " . trim($matches[1]); + } + } + } elseif (strlen((string)$this->response) > 0) { + $msg = trim((string)$this->response); + } + $this->message = [0, $msg]; + } elseif ((int)$this->isSuccessful() == 1) { + // $msg = trim((string)$this->data); + if (is_array($this->data) && isset($this->data['result']['statusmsg'])) { + if (strlen((string)trim($this->data['result']['statusmsg'])) > 0) { + $this->message = [1, "The account " . $data["user"] . " has been activated successfully.
Remember to wait 5 minutes while the server restarts to view the account."]; + } + } elseif (strlen((string)$this->response) > 0) { + $this->message = [1, trim((string)$this->response)]; + } + $this->message = [1, $msg]; + } else { + $this->message = [0, $msg]; + } + } + + /** + * Change the password of an (active) account + * + * Parameters: + * - username: The custom username + * - password: The new password + * + * @param array $parameters + * @return array + */ + public function password(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = [ + "user" => $this->getUserName(), + "pass" => $this->getPassword() + ]; + $this->httpAuthGet($this->getApiUrl() . "passwd", $data); + $msg = "Sorry an error has occurred please try again in a few minutes."; + if (is_array($this->data) && isset($this->data['passwd']['status'])) { + if ((int)($this->data['passwd']['status']) == 0) { + $this->message = [0, "The password for account " . $data["user"] . " change failed."]; + } elseif (((int)($this->data['passwd']['status']) == 1) || (strpos($this->response, 'error occured changing this password') !== false)) { + $this->message = [1, "The password for account " . $data["user"] . " has been changed successfully.
Remember that changing the password is done equally for cPanel,FTP,MySQL"]; + } else { + if (strlen((string)$this->response) > 0) { + $msg = (string)$this->response; + } + $this->message = [0, $msg]; + } + } elseif ((int)$this->response == 0) { + // response is null + $this->message = [0, "The account " . $data["user"] . " does not exist."]; + } else { + $this->message = [0, $msg]; + } + } + + /** + * Check whether a domain is available + * + * Parameters: + * - domain: The domain name or subdomain to check + * + * @param array $parameters + * @return bool + */ + public function availability(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = [ + "api_user" => $this->getApiUsername(), + "api_key" => $this->getApiPassword(), + "domain" => $this->getDomain(), + ]; + $this->response = $this->httpGet($this->getApiUrl() . "checkavailable", $data); + $this->parseResponse(); + $this->data = trim((string)$this->response); + if ((int)$this->response == 1 && (string)$this->data == "1") { + $this->message = [1, "The domain " . $data["domain"] . " is available to register."]; + } elseif ((int)$this->response == 0) { + if (strlen((string)$this->response) == 1) { + $this->message = [0, "The domain " . $data["domain"] . " is already registered."]; + } elseif (strlen((string)$this->response) > 1) { + $this->message = [0, $this->data]; + } + } + } + + /** + * Get All domains belonging to Account + * + * Parameters: + * - username the VistaPanel username like uii_1992000 + * + * @param array $parameters + * @return array + */ + public function getUserDomains(array $parameters = []) + { + $this->initialize(array_replace($this->parameters, $parameters)); + $data = [ + "api_user" => $this->getApiUsername(), + "api_key" => $this->getApiPassword(), + "username" => $this->getUserName(), + ]; + $this->response = $this->httpGet($this->getApiUrl() . "getuserdomains", $data); + $this->data = trim((string)$this->response); + if ($this->data == "null") { + $this->message = array(1, "The account " . $data["username"] . " does not exist.", []); + } elseif (strpos($this->response, '[[') === 0) { + // [["ACTIVE","doudou.uiisc.com"],["ACTIVE","doudoudzj.uiisc.com"]] + // [["SUSPENDED","doudou.uiisc.com"],["SUSPENDED","foundation.pub"]] + $this->domain = array_map(function ($item) { + return ["status" => strtolower($item[0]), "domain" => strtolower($item[1])]; + }, json_decode($this->response, true)); + $str = ""; + foreach ($this->domain as $key=>$value) { + $str .= "domain " . $key . ": " . $value["status"] . " - " . $value["domain"] . "
"; + } + $this->message = array(1, "The account " . $data["username"] . " has " . count($this->domain) . " domains.
" . $str); + } else { + $this->message = array(0, $this->data); + } + } + + /** + * Get the Status of Account + * + * @return string|null + */ + public function getStatus() + { + if ($this->data != "null" && strpos($this->response, '[[') === 0) { + $statuses = array_unique(array_map(function ($item) { + return strtolower($item["status"]); + }, $this->domain)); + // print_r($statuses); + if (count($statuses) == 1) { + return $statuses[0]; + } elseif (count($statuses) > 1) { + return "The account domains have different statuses " . $this->getUserName() . "." . $this->data; + } else { + return null; + } + } else { + return null; + } + } + + /** + * Get the status of the account if the account is not active. + * + * The result is one of the following chars: + * - x: suspended + * - r: reactivating + * - c: closing + * + * @return string + */ + public function getAccountStatus() + { + return $this->status; + } +}