user = OPENPROVIDER['username']; $this->pass = OPENPROVIDER['password']; $this->ip = OPENPROVIDER['ip']; } /*** * トークンの受け取り。 * このライブリリーを使ったら、一回「login()」を実行する事が必須となります。 * * @return Result 結果 */ public function login(): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache('login'); if (time() < ($this->lastAuth + $this->tokenDuration)) { $this->token = $cache['data']['token']; $this->lastAuth = $cache['last_auth']; return \Result::Success('', $cache); } $curl = new Curl("{$this->BASEURL}/auth/login"); $payload = [ 'username' => $this->user, 'password' => $this->pass, 'ip' => $this->ip ?: '0.0.0.0', ]; $curl->setMethod("POST"); $curl->setPostRaw(json_encode($payload)); $curl->addHeader("Content-Type", "application/json"); $curl->addHeader("Accept", "application/json"); $res = $curl->execute(); if (!$res->isSuccess) { $err = "CURLの実行に失敗: ".$curl->message; assert_unless_success($res, $err); return \Result::Error($err); } $body = $curl->getResponseBody(); if ($curl->getResponseCode() != 200) { $err = json_decode($body, true); assert_not_null($err, "エラーの受け取りに失敗。"); assert($curl->getResponseCode() == 200, $err['desc']); return \Result::Error(); } assert_not_null($body, "返事ボディーは空です。"); $res = json_decode($body, true); if (isset($res['data']['token'])) { $this->token = $res['data']['token']; $this->lastAuth = time(); $res['last_auth'] = $this->lastAuth; $this->setCache('login', $res); return \Result::Success('', $res); } return \Result::Error('ログインに失敗。'); } // カスタマー // ドメイン //// ドメイン /*** * ドメイン一覧。 * * @return Result 結果。 */ public function listDomains(array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache('listdomains'); if ($this->isValidLifespan($cache, $query)) return \Result::Success('', $cache); $curl = $this->setupCurl('/domains'); $res = $this->curlResult($curl); if (isset($res['data']['results'])) { $this->setCache('listdomains', $res->data); return \Result::Success('', $res['data']['results']); } return \Result::Error('ドメインの確認に失敗。'); } /** * ドメイン名の登録。 * * @param string $name 登録したいドメイン名(例:"076studio.jp") * @param array $info カスタマー情報等 * @param int $period 年間(デフォルト=1年) * @return Result 結果。配列の場合:'activation_date'(リアルタイムで成功したのみ), 'auth_code'(TLDが対応している場合のみ), 'expiration_date', 'id', 'renewal_date', 'status'(ACT又はREQ) */ public function createDomain(string $name, array $info, int $period = 1): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); if (!isset($info['owner_handle']) || $info['owner_handle'] === '') $info['owner_handle'] = OPENPROVIDER['owner_handle']; if (!isset($info['admin_handle']) || $info['admin_handle'] === '') $info['admin_handle'] = OPENPROVIDER['owner_handle']; if (!isset($info['tech_handle']) || $info['tech_handle'] === '') $info['tech_handle'] = OPENPROVIDER['owner_handle']; if (!isset($info['billing_handle']) || $info['billing_handle'] === '') $info['billing_handle'] = OPENPROVIDER['owner_handle']; if (!isset($info['reseller_handle']) || $info['reseller_handle'] === '') $info['reseller_handle'] = OPENPROVIDER['owner_handle']; if (!isset($info['name_servers']) || empty($info['name_servers'])) $info['name_servers'] = ['ns1.openprovider.nl', 'ns2.openprovider.be', 'ns3.openprovider.eu']; if (!isset($info['autorenew']) || $info['autorenew'] === '') $info['autorenew'] = 'default'; // 新しい顧客の場合 $parts = explode('.', $name, 2); assert_exists($parts[0]); assert_exists($parts[1]); $domain = [ 'name' => $parts[0], 'extension' => $parts[1], ]; $ns = []; foreach ($info['name_servers'] as $n) { $ns[] = ['name' => $n]; } $payload = [ 'name' => $domain, 'period' => $period, 'owner_handle' => $owner_handle, 'admin_handle' => $admin_handle, 'tech_handle' => $tech_handle, 'billing_handle' => $billing_handle, 'reseller_handle' => $reseller_handle, 'name_servers' => $ns, 'autorenew' => $autorenew, ]; $curl = $this->setupCurl('/domains/', 'POST', $payload); kys('TODO'); $res = $this->curlResult($curl); if (isset($res['data'])) return \Result::Success('', $res); return \Result::Error('ドメインの確認に失敗。'); } /*** * ドメインを登録可能かどうかの確認。 * * @param array $domains ドメイン名リスト。例:['076.moe', '076.co.jp', '076.com'] * @param bool $with_price 値段を表示するかどうか。デフォルトは「false」 * @return Result 結果。配列の場合:'domain'と'status'はいつでもあり、'reason', 'premium', 'is_premium'が多分あり、そして'price'が「with_price」が「true」の場合のみ。 */ public function checkDomainAvailable(array $domains, bool $with_price = false): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $domainList = []; foreach ($domains as $d) { $domain = explode('.', $d); assert_exists($domain[0]); assert_exists($domain[1]); if (count($domain) !== 2) { return \Result::Error("不正なドメイン形: {$d}"); } $domainList[] = [ 'name' => $domain[0], 'extension' => $domain[1], ]; } $payload = [ 'domains' => $domainList, 'with_price' => $with_price, ]; $curl = $this->setupCurl('/domains/check', 'POST', $payload); $res = $this->curlResult($curl); if (isset($res->data['data']['results'])) return \Result::Success('', $res->data['data']['results']); return \Result::Error('ドメインの確認に失敗。'); } //// 追加データ //// 顧客様の追加データ /** * 顧客様の一覧 * * @param array $query 検索クエリー * @return Result */ public function listCustomers(array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache('listcustomers'); if ($this->isValidLifespan($cache, $query)) return \Result::Success('', $cache); foreach ($query as $k => $v) { if (is_bool($v)) $query[$k] = $v ? '1' : '0'; } $uri = '/customers?'.http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $res->data['query'] = $query; $this->setCache('listcustomers', $res->data); return \Result::Success('', $res->data); } return \Result::Error('顧客様一覧の受け取りに失敗。'); } /** * 顧客様の表示 * * @param string $handle ハンドル * @param bool $withAdditionalData 詳細データ含むか? * @return Result */ public function getCustomer(string $handle, bool $withAdditionalData = false): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cacheName = "getcustomer-{$handle}"; $cache = $this->getCache($cacheName); if ($this->isValidLifespan($cache, $handle, 'handle')) return \Result::Success('', $cache); $query = [ 'with_additional_data' => $withAdditionalData ? 'true' : 'false' ]; $uri = "/customers/{$handle}?".http_build_query($query, '', '&', PHP_QUERY_RFC3986); // kys($uri); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $res->data['handle'] = $handle; $this->setCache($cacheName, $res->data); return \Result::Success('', $res->data); } return \Result::Error('顧客様の受け取りに失敗。'); } //// ドメイン値段 /** * ドメイン値段一覧 * * @param array $query 検索クエリー * @return Result */ public function getDomainPrices(array $query): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $name = ''; $ext = ''; if (isset($query['domain.name'])) $name = $query['domain.name']; if (isset($query['domain.extension'])) $ext = $query['domain.extension']; $cacheName = $name && $ext ? "domainprices-{$name}.{$ext}" : 'domainprices'; $cache = $this->getCache($cacheName); if ($this->isValidLifespan($cache)) return \Result::Success('', $cache); $uri = "/domains/prices?".http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache($cacheName, $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } //// 認証コード //// TLD /** * TLD一覧 * * @param array $query 検索クエリー * @return Result */ public function listTlds(array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache('listtlds'); if ($this->isValidLifespan($cache)) return \Result::Success('', $cache); if (empty($query)) $query = [ 'limit' => 10, 'offset' => 0, 'order' => 'ASC' ]; foreach ($query as $k => $v) if (is_bool($v)) $query[$k] = $v ? '1' : '0'; $uri = '/tlds?'.http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache('listtlds', $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } /** * TLDの表示 * * @param string $tld TLD * @param array $query 検索クエリー * @return Result */ public function getTld(string $tld, array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache("gettld-{$tld}"); if ($this->isValidLifespan($cache)) return \Result::Success('', $cache); if (empty($query)) $query = [ 'limit' => 10, 'offset' => 0 ]; foreach ($query as $k => $v) if (is_bool($v)) $query[$k] = $v ? '1' : '0'; $uri = "/tlds/{$tld}?".http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache("gettld-{$tld}", $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } /** * TLDの受け取り */ // 請求 //// 請求書 //// 支払 //// トランザクション // DNS //// DomainToken //// ネームサーバー //// NSグループ //// テンプレート //// ゾーン /** * DNSゾーン一覧 * * @param array $query * @return Result */ public function listDnsZones(array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache('listdnszones'); if ($this->isValidLifespan($cache, $query)) return \Result::Success('', $cache); if (empty($query)) $query = [ 'limit' => 25, 'offset' => 0, 'order_by.name' => 'asc' ]; foreach ($query as $k => $v) if (is_bool($v)) $query[$k] = $v ? '1' : '0'; $uri = "/dns/zones?".http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache('listdnszones', $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } /** * DNSゾーン一覧 * * @param string $domain ドメイン名 * @param array $query 検索クエリー * @return Result */ public function getDnsZone(string $domain, array $query = []): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache("getdnszone-{$domain}"); if ($this->isValidLifespan($cache)) return \Result::Success('', $cache); if (empty($query)) $query = [ 'limit' => 100, 'offset' => 0, 'order_by.name' => 'asc' ]; foreach ($query as $k => $v) if (is_bool($v)) $query[$k] = $v ? '1' : '0'; $uri = "/dns/zones/{$domain}?".http_build_query($query, '', '&', PHP_QUERY_RFC3986); $curl = $this->setupCurl($uri); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache("getdnszone-{$domain}", $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } //// ゾーンレコード /** * DNSレコード一覧 * * @param string $domain * @return Result */ public function listZoneRecords(string $domain): \Result { if (!OPENPROVIDER_ENABLED) return \Result::error('エラー:OpenProviderは無効です。'); $cache = $this->getCache("getzonerecords-{$domain}"); if ($this->isValidLifespan($cache)) return \Result::Success('', $cache); $curl = $this->setupCurl("/dns/zones/{$domain}/records"); $res = $this->curlResult($curl); if (isset($res->data['data'])) { $this->setCache("getzonerecords-{$domain}", $res->data); return \Result::Success('', $res->data); } return \Result::Error('TLD一覧の受け取りに失敗。'); } // Easydmarc // ライセンス // リセラー・顧客様 // SpamExpert // SSL証明書 //////// /** * トークンの受け取り。 * * @return string トークン */ public function getToken(): string { if (!OPENPROVIDER_ENABLED) return ''; return $this->token; } /** * リセラーIDの受け取り。 * * @return int リセラーID */ public function getResellerId(): int { if (!OPENPROVIDER_ENABLED) return 0; return $this->resellerId; } ////////// private function setupCurl(string $uri, string $resType = 'GET', array $payload = []): Curl { $curl = new Curl("{$this->BASEURL}{$uri}"); $curl->setMethod($resType); if (!empty($payload)) $curl->setPostRaw(json_encode($payload)); $curl->setBearerAuth($this->token); $curl->addHeader('Content-Type', 'application/json'); $curl->addHeader('Accept', 'application/json'); return $curl; } private function curlResult(Curl &$curl): \Result { $res = $curl->execute(); if (!$res->isSuccess) { $err = "CURL実行に失敗: {$curl->message}"; assert_unless_success($res, $err); return \Result::Error($err); } $body = $curl->getResponseBody(); if ($curl->getResponseCode() != 200) { $err = json_decode($body, true); assert_not_null($err, "エラーの受け取りに失敗。"); assert($curl->getResponseCode() == 200, $err['desc']); return \Result::Error($err['desc']); } assert_not_null($body, "返事ボディーは空です。"); return \Result::Success('', json_decode($body, true)); } /** * キャッシュの作成 * * @param string $type キャッシュ類(例:login、domainlist等) * @param array $data 保存するデータ * @return Result */ private function setCache(string $type, array $data): \Result { if (!file_exists($this->dataDir)) { if (!mkdir($this->dataDir, 0755)) return \Result::Error('エラー:ユーザーのアイコンディレクトリの作成に失敗。'); } $data['lifespan'] = time(); $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if (file_put_contents("{$this->dataDir}{$type}.json", $json) === false) return \Result::Error('エラー:ユーザーデータの保存に失敗。'); return \Result::Success(); } /** * キャッシュから受け取り * * @param string $type キャッシュ類(例:login、domainlist等) * @return array */ private function getCache(string $type): array { if (!file_exists("{$this->dataDir}{$type}.json")) return []; $content = file_get_contents("{$this->dataDir}{$type}.json"); if ($content === false) return []; $data = json_decode($content, true); if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) return []; if ($type === 'login') { $this->token = $data['data']['token']; $this->lastAuth = $data['last_auth']; } return $data; } /** * キャッシュを破壊する * * @param string $name キャッシュのファイル名 * @return Result */ private function murderCache(string $name): \Result { if (!file_exists("{$this->dataDir}{$name}.json")) return \Result::Error('キャッシュファイルが存在しない。'); if (!unlink("{$this->dataDir}{$name}.json")) return \Result::Error('キャッシュファイルの削除に失敗。'); return \Result::Success(); } /** * キャッシュ有効期限の確認 * * @param array $cache * @param mixed $data デフォルト=null * @param string $dataPoint デフォルト=query * @return bool */ private function isValidLifespan(array $cache, mixed $data = null, string $dataPoint = 'query'): bool { if (NULL === $data) return (!empty($cache) && (isset($cache['lifespan']) && time() < ($cache['lifespan'] + $this->dataDuration))); else return (!empty($cache) && (isset($cache[$dataPoint]) && $cache[$dataPoint] === $data) && (isset($cache['lifespan']) && time() < ($cache['lifespan'] + $this->dataDuration))); } }