api.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. <?php
  2. if (!defined('IN_SYS')) {
  3. // exit('禁止访问');
  4. header("Location: ../index.php");
  5. exit;
  6. }
  7. /**
  8. * mofh-whm-api-client
  9. */
  10. class Api
  11. {
  12. public $message = [];
  13. public $domain;
  14. protected $parameters;
  15. protected $data;
  16. protected $response;
  17. protected $status;
  18. protected $config = array(
  19. "apiUsername" => "",
  20. "apiPassword" => "",
  21. "apiUrl" => "https://panel.myownfreehost.net:2087/xml-api/",
  22. "plan" => [],
  23. );
  24. public function __construct()
  25. {
  26. $this->initialize();
  27. }
  28. /**
  29. * Initialize with config
  30. *
  31. * @param array $parameters
  32. * @return $this
  33. */
  34. public function initialize(array $parameters = [])
  35. {
  36. $this->parameters = $parameters;
  37. // set default parameters
  38. foreach (array_replace($this->config, $parameters) as $key => $value) {
  39. $this->setParameter($key, $value);
  40. }
  41. return $this;
  42. }
  43. /**
  44. * Create a new api
  45. *
  46. * @param array $parameters
  47. * @return Api
  48. */
  49. public static function init(array $parameters = [])
  50. {
  51. $api = new self();
  52. $api->initialize($parameters);
  53. return $api;
  54. }
  55. /**
  56. * Get a single parameter.
  57. *
  58. * @param string $key The parameter key
  59. * @return mixed
  60. */
  61. protected function getParameter($key)
  62. {
  63. if (isset($this->parameters[$key])) {
  64. return $this->parameters[$key];
  65. } else {
  66. return null;
  67. }
  68. }
  69. /**
  70. * Set a single parameter
  71. *
  72. * @param string $key The parameter key
  73. * @param mixed $value The value to set
  74. * @return $this
  75. * @throws RuntimeException if a request parameter is modified after the request has been sent.
  76. */
  77. protected function setParameter($key, $value)
  78. {
  79. $this->parameters[$key] = $value;
  80. return $this;
  81. }
  82. public function setApiUsername($value)
  83. {
  84. return $this->setParameter("apiUsername", $value);
  85. }
  86. public function getApiUsername()
  87. {
  88. return $this->getParameter("apiUsername");
  89. }
  90. public function setApiPassword($value)
  91. {
  92. return $this->setParameter("apiPassword", $value);
  93. }
  94. public function getApiPassword()
  95. {
  96. return $this->getParameter("apiPassword");
  97. }
  98. public function setPlan($value)
  99. {
  100. return $this->setParameter("plan", $value);
  101. }
  102. public function getPlan()
  103. {
  104. return $this->getParameter("plan");
  105. }
  106. public function setApiUrl($value)
  107. {
  108. return $this->setParameter("apiUrl", $value);
  109. }
  110. public function getApiUrl()
  111. {
  112. return $this->getParameter("apiUrl");
  113. }
  114. public function getDomain()
  115. {
  116. return $this->getParameter("domain");
  117. }
  118. public function setDomain($value)
  119. {
  120. return $this->setParameter("domain", $value);
  121. }
  122. public function getPassword()
  123. {
  124. return $this->getParameter("password");
  125. }
  126. public function setPassword($value)
  127. {
  128. return $this->setParameter("password", $value);
  129. }
  130. public function getUserName()
  131. {
  132. return $this->getParameter("username");
  133. }
  134. public function setUserName($value)
  135. {
  136. return $this->setParameter("username", $value);
  137. }
  138. public function getEmail()
  139. {
  140. return $this->getParameter("email");
  141. }
  142. public function setEmail($value)
  143. {
  144. return $this->setParameter("email", $value);
  145. }
  146. public function getReason()
  147. {
  148. return $this->getParameter('reason');
  149. }
  150. public function setReason($value)
  151. {
  152. return $this->setParameter('reason', $value);
  153. }
  154. public function httpAuthGet($url, $param = [])
  155. {
  156. if (!is_array($param)) {
  157. throw new Exception("parameters must is a array");
  158. }
  159. $authstr = "WHM " . $this->getApiUsername() . ":" . $this->getApiPassword();
  160. $curlheaders = [
  161. "Authorization: " . $authstr,
  162. "cache-control: no-cache"
  163. ];
  164. $p = "";
  165. foreach ($param as $key => $value) {
  166. $p = $p . $key . "=" . $value . "&";
  167. }
  168. if (preg_match('/\?[\d\D]+/', $url)) { //matched ?c
  169. $p = "&" . $p;
  170. } else if (preg_match('/\?$/', $url)) { //matched ?$
  171. $p = $p;
  172. } else {
  173. $p = "?" . $p;
  174. }
  175. $p = preg_replace('/&$/', "", $p);
  176. $url = $url . $p;
  177. echo $url;
  178. $http = curl_init($url);
  179. curl_setopt($http, CURLOPT_SSL_VERIFYPEER, 0);
  180. curl_setopt($http, CURLOPT_SSL_VERIFYHOST, 0);
  181. curl_setopt($http, CURLOPT_RETURNTRANSFER, 1);
  182. // curl_setopt($http, CURLOPT_HEADER, 1);
  183. curl_setopt($http, CURLOPT_HTTPHEADER, $curlheaders);
  184. $res = curl_exec($http);
  185. $this->response = $res;
  186. $this->parseResponse();
  187. curl_close($http);
  188. }
  189. /*
  190. * http get method
  191. */
  192. public function httpGet($url, $param = [])
  193. {
  194. if (!is_array($param)) {
  195. throw new Exception("parameters must is a array");
  196. }
  197. $authstr = "WHM " . $this->getApiUsername() . ":" . $this->getApiPassword();
  198. $curlheaders = [
  199. "Authorization: " . $authstr,
  200. "cache-control: no-cache"
  201. ];
  202. $p = "";
  203. foreach ($param as $key => $value) {
  204. $p = $p . $key . "=" . $value . "&";
  205. }
  206. if (preg_match('/\?[\d\D]+/', $url)) { //matched ?c
  207. $p = "&" . $p;
  208. } else if (preg_match('/\?$/', $url)) { //matched ?$
  209. $p = $p;
  210. } else {
  211. $p = "?" . $p;
  212. }
  213. $p = preg_replace('/&$/', "", $p);
  214. $url = $url . $p;
  215. //echo $url;
  216. $http = curl_init($url);
  217. curl_setopt($http, CURLOPT_SSL_VERIFYPEER, 0);
  218. curl_setopt($http, CURLOPT_SSL_VERIFYHOST, 0);
  219. curl_setopt($http, CURLOPT_RETURNTRANSFER, 1);
  220. // curl_setopt($http, CURLOPT_HEADER, 1);
  221. curl_setopt($http, CURLOPT_HTTPHEADER, $curlheaders);
  222. $res = curl_exec($http);
  223. curl_close($http);
  224. // return explode("\r\n\r\n", $res, 2)[1];
  225. return $res;
  226. }
  227. protected function parseResponse()
  228. {
  229. $data = (string)$this->response;
  230. if (strpos(trim($data), '<') !== 0) {
  231. $this->data = null;
  232. } else {
  233. $this->data = $this->xmlToArray((array)simplexml_load_string($data));
  234. }
  235. }
  236. /**
  237. * Recursively convert a SimpleXMLElement array to regular arrays
  238. *
  239. * @param array $input
  240. * @return array
  241. */
  242. protected function xmlToArray($input)
  243. {
  244. foreach ($input as $key => $value) {
  245. if ($value instanceof \SimpleXMLElement) {
  246. $value = (array)$value;
  247. }
  248. if (is_array($value)) {
  249. $input[$key] = $this->xmlToArray($value);
  250. }
  251. }
  252. return $input;
  253. }
  254. /**
  255. * Get the response data.
  256. *
  257. * @return array|null
  258. */
  259. public function getData()
  260. {
  261. return $this->data;
  262. }
  263. /**
  264. * Whether the action was successful
  265. * 成功信息
  266. *
  267. * @return bool
  268. */
  269. public function isSuccessful()
  270. {
  271. if ($this->getData() && isset($this->getData()['result']['status'])) {
  272. return $this->getData()['result']['status'] == 1;
  273. } else {
  274. return false;
  275. }
  276. }
  277. /**
  278. * Create a new account
  279. *
  280. * Parameters:
  281. * - username: A custom account username, max. 8 characters of letters and numbers
  282. * - password: The FTP/control panel/database password for the account
  283. * - email: The contact e-mail address of the owner
  284. * - domain: The primary domain name of the account
  285. * - plan: The hosting plan to create the acccount on
  286. *
  287. * @param array $parameters
  288. * @return string
  289. */
  290. public function createAccount(array $parameters = [])
  291. {
  292. $this->initialize(array_replace($this->parameters, $parameters));
  293. $data = [
  294. "username" => $this->getUsername(),
  295. "password" => $this->getPassword(),
  296. "contactemail" => $this->getEmail(),
  297. "domain" => $this->getDomain(),
  298. "plan_name" => $this->getPlan(),
  299. ];
  300. // The email address is a required field.
  301. // The username is invalid (Only letters and numbers 8 characters maximum 12)
  302. // The username is invalid (Only letters and numbers).
  303. // The username is invalid (8 characters maximum 18 (uiisc_test_whm_api))
  304. // print_r($data);
  305. $this->httpAuthGet($this->getApiUrl() . "createacct", $data);
  306. $msg = "Sorry, an error has occurred. Please try again in a few minutes.";
  307. if ((int)$this->isSuccessful() == 0) {
  308. if (is_array($this->data) && isset($this->data['result']['statusmsg'])) {
  309. print_r("-2");
  310. if (strlen((string)trim($this->data['result']['statusmsg'])) > 0) {
  311. $msg = trim($this->data['result']['statusmsg']);
  312. }
  313. } elseif ((int)trim($this->response) > 0) {
  314. print_r("-3-");
  315. $msg = (string)trim($this->response);
  316. } else {
  317. print_r("-000-");
  318. }
  319. $this->message = [0, $msg];
  320. } elseif ((int)$this->isSuccessful() == 1) {
  321. if (is_array($this->data) && isset($this->data['result']['statusmsg']) && strlen((string)trim($this->data['result']['statusmsg'])) > 0) {
  322. $this->message = [
  323. 1, "The account <b>" . $data["username"] . "</b> has been created successfully. Keep the account info in a safe place.",
  324. [
  325. "account" => $data["username"],
  326. "panel_username" => isset($this->data['result']['options']['vpusername']) ? $this->data['result']['options']['vpusername'] : null,
  327. "password" => $data["password"],
  328. "domain" => $data["domain"],
  329. "email" => $data["contactemail"],
  330. "plan " => $data["plan_name"],
  331. "panel_url" => "http://cpanel.uiisc.com",
  332. "note" => "Remember to wait 5 minutes for your account to be completely created on the server"
  333. ]
  334. ];
  335. } else {
  336. $this->message = [1, "The account <b>" . $data["username"] . "</b> has been created successfully"];
  337. }
  338. } else {
  339. $this->message = [0, $msg];
  340. }
  341. }
  342. /**
  343. * Suspend account
  344. *
  345. * Parameters:
  346. * - username: The custom username or userid
  347. * - reason: The reason why the account was suspended
  348. *
  349. * @param array $parameters
  350. * @return array
  351. */
  352. public function suspend(array $parameters = [])
  353. {
  354. $this->initialize(array_replace($this->parameters, $parameters));
  355. $data = ["user" => $this->getUsername(), "reason" => $this->getReason()];
  356. // $this->response =
  357. $this->httpAuthGet($this->getApiUrl() . "suspendacct", $data);
  358. // $this->parseResponse();
  359. print_r("\n----response----\n");
  360. print_r($this->response);
  361. print_r("\n----data----\n");
  362. print_r($this->data);
  363. $msg = "Sorry an error has occurred please try again in a few minutes.";
  364. if ((int)$this->isSuccessful() == 0) {
  365. if (is_array($this->data) && isset($this->data['result']['statusmsg'])) {
  366. $msg = trim((string)$this->data['result']['statusmsg']);
  367. if (preg_match('/account is NOT currently suspended \(status : (\w*) \)/', $msg, $matches)) {
  368. if (trim($matches[1]) == '') {
  369. $msg = "The account <b>" . $data["user"] . "</b> is NOT currently suspended";
  370. } else {
  371. $msg = "The account <b>" . $data["user"] . "</b> is " . trim($matches[1]);
  372. }
  373. }
  374. } elseif (strlen((string)$this->response) > 0) {
  375. $msg = trim((string)$this->response);
  376. }
  377. $this->message = [0, $msg];
  378. } elseif ((int)$this->isSuccessful() == 1) {
  379. if (is_array($this->data) && isset($this->data['result']['statusmsg'])) {
  380. $msg = "The account <b>" . $data["user"] . "</b> has been suspended successfully.<br/><i>- Remember that in 30 days the account will be completely removed from the server.</i>";
  381. } elseif (strlen((string)$this->response) > 0) {
  382. $msg = trim((string)$this->response);
  383. }
  384. $this->message = [1, $msg];
  385. } else {
  386. $this->message = [1, $msg];
  387. }
  388. }
  389. /**
  390. * Unsuspend account
  391. *
  392. * Parameters:
  393. * - username: The custom username or userid
  394. *
  395. * @param array $parameters
  396. * @return array
  397. */
  398. public function unsuspend(array $parameters = [])
  399. {
  400. $this->initialize(array_replace($this->parameters, $parameters));
  401. $data = ["user" => $this->getUsername()];
  402. $this->httpAuthGet($this->getApiUrl() . "unsuspendacct", $data);
  403. // print_r("\n----response----\n");
  404. // print_r($this->response);
  405. // print_r("\n----data----\n");
  406. // print_r($this->data);
  407. $msg = "Sorry an error has occurred please try again in a few minutes.";
  408. if ((int)$this->isSuccessful() == 0) {
  409. if (is_array($this->data) && isset($this->data['result']['statusmsg'])) {
  410. $msg = trim((string)$this->data['result']['statusmsg']);
  411. if (preg_match('/account is NOT currently suspended \(status : (\w*) \)/', $msg, $matches)) {
  412. if (trim($matches[1]) == '') {
  413. $msg = "The account <b>" . $data["user"] . "</b> is NOT currently suspended";
  414. } else {
  415. // This account is NOT currently suspended (status : r ) . .
  416. $msg = "The account <b>" . $data["user"] . "</b> is NOT currently suspended status: " . trim($matches[1]);
  417. }
  418. }
  419. } elseif (strlen((string)$this->response) > 0) {
  420. $msg = trim((string)$this->response);
  421. }
  422. $this->message = [0, $msg];
  423. } elseif ((int)$this->isSuccessful() == 1) {
  424. // $msg = trim((string)$this->data);
  425. if (is_array($this->data) && isset($this->data['result']['statusmsg'])) {
  426. if (strlen((string)trim($this->data['result']['statusmsg'])) > 0) {
  427. $this->message = [1, "The account <b>" . $data["user"] . "</b> has been activated successfully.<br/><i>Remember to wait 5 minutes while the server restarts to view the account.</i>"];
  428. }
  429. } elseif (strlen((string)$this->response) > 0) {
  430. $this->message = [1, trim((string)$this->response)];
  431. }
  432. $this->message = [1, $msg];
  433. } else {
  434. $this->message = [0, $msg];
  435. }
  436. }
  437. /**
  438. * Change the password of an (active) account
  439. *
  440. * Parameters:
  441. * - username: The custom username
  442. * - password: The new password
  443. *
  444. * @param array $parameters
  445. * @return array
  446. */
  447. public function password(array $parameters = [])
  448. {
  449. $this->initialize(array_replace($this->parameters, $parameters));
  450. $data = [
  451. "user" => $this->getUserName(),
  452. "pass" => $this->getPassword()
  453. ];
  454. $this->httpAuthGet($this->getApiUrl() . "passwd", $data);
  455. $msg = "Sorry an error has occurred please try again in a few minutes.";
  456. if (is_array($this->data) && isset($this->data['passwd']['status'])) {
  457. if ((int)($this->data['passwd']['status']) == 0) {
  458. $this->message = [0, "The password for account <b>" . $data["user"] . "</b> change failed."];
  459. } elseif (((int)($this->data['passwd']['status']) == 1) || (strpos($this->response, 'error occured changing this password') !== false)) {
  460. $this->message = [1, "The password for account <b>" . $data["user"] . "</b> has been changed successfully.<br/>Remember that changing the password is done equally for cPanel,FTP,MySQL"];
  461. } else {
  462. if (strlen((string)$this->response) > 0) {
  463. $msg = (string)$this->response;
  464. }
  465. $this->message = [0, $msg];
  466. }
  467. } elseif ((int)$this->response == 0) {
  468. // response is null
  469. $this->message = [0, "The account <b>" . $data["user"] . "</b> does not exist."];
  470. } else {
  471. $this->message = [0, $msg];
  472. }
  473. }
  474. /**
  475. * Check whether a domain is available
  476. *
  477. * Parameters:
  478. * - domain: The domain name or subdomain to check
  479. *
  480. * @param array $parameters
  481. * @return bool
  482. */
  483. public function availability(array $parameters = [])
  484. {
  485. $this->initialize(array_replace($this->parameters, $parameters));
  486. $data = [
  487. "api_user" => $this->getApiUsername(),
  488. "api_key" => $this->getApiPassword(),
  489. "domain" => $this->getDomain(),
  490. ];
  491. $this->response = $this->httpGet($this->getApiUrl() . "checkavailable", $data);
  492. $this->parseResponse();
  493. $this->data = trim((string)$this->response);
  494. if ((int)$this->response == 1 && (string)$this->data == "1") {
  495. $this->message = [1, "The domain <b>" . $data["domain"] . "</b> is available to register."];
  496. } elseif ((int)$this->response == 0) {
  497. if (strlen((string)$this->response) == 1) {
  498. $this->message = [0, "The domain <b>" . $data["domain"] . "</b> is already registered."];
  499. } elseif (strlen((string)$this->response) > 1) {
  500. $this->message = [0, $this->data];
  501. }
  502. }
  503. }
  504. /**
  505. * Get All domains belonging to Account
  506. *
  507. * Parameters:
  508. * - username the VistaPanel username like uii_1992000
  509. *
  510. * @param array $parameters
  511. * @return array
  512. */
  513. public function getUserDomains(array $parameters = [])
  514. {
  515. $this->initialize(array_replace($this->parameters, $parameters));
  516. $data = [
  517. "api_user" => $this->getApiUsername(),
  518. "api_key" => $this->getApiPassword(),
  519. "username" => $this->getUserName(),
  520. ];
  521. $this->response = $this->httpGet($this->getApiUrl() . "getuserdomains", $data);
  522. $this->data = trim((string)$this->response);
  523. if ($this->data == "null") {
  524. $this->message = array(1, "The account <b>" . $data["username"] . "</b> does not exist.", []);
  525. } elseif (strpos($this->response, '[[') === 0) {
  526. // [["ACTIVE","doudou.uiisc.com"],["ACTIVE","doudoudzj.uiisc.com"]]
  527. // [["SUSPENDED","doudou.uiisc.com"],["SUSPENDED","foundation.pub"]]
  528. $this->domain = array_map(function ($item) {
  529. return ["status" => strtolower($item[0]), "domain" => strtolower($item[1])];
  530. }, json_decode($this->response, true));
  531. $str = "";
  532. foreach ($this->domain as $key=>$value) {
  533. $str .= "domain " . $key . ": <b>" . $value["status"] . "</b> - " . $value["domain"] . "<br/>";
  534. }
  535. $this->message = array(1, "The account <b>" . $data["username"] . "</b> has " . count($this->domain) . " domains.<br/>" . $str);
  536. } else {
  537. $this->message = array(0, $this->data);
  538. }
  539. }
  540. /**
  541. * Get the Status of Account
  542. *
  543. * @return string|null
  544. */
  545. public function getStatus()
  546. {
  547. if ($this->data != "null" && strpos($this->response, '[[') === 0) {
  548. $statuses = array_unique(array_map(function ($item) {
  549. return strtolower($item["status"]);
  550. }, $this->domain));
  551. // print_r($statuses);
  552. if (count($statuses) == 1) {
  553. return $statuses[0];
  554. } elseif (count($statuses) > 1) {
  555. return "The account domains have different statuses <b>" . $this->getUserName() . "</b>." . $this->data;
  556. } else {
  557. return null;
  558. }
  559. } else {
  560. return null;
  561. }
  562. }
  563. /**
  564. * Get the status of the account if the account is not active.
  565. *
  566. * The result is one of the following chars:
  567. * - x: suspended
  568. * - r: reactivating
  569. * - c: closing
  570. *
  571. * @return string
  572. */
  573. public function getAccountStatus()
  574. {
  575. return $this->status;
  576. }
  577. }