appName = $appName; $this->modelName = $modelName; $key = "kintone.host"; $host = config($key); if (!$host) { throw new ConfigException("kintone.host", $host); } $key = "kintone.applications." . $appName . ".apiToken"; $apiToken = config($key); if (!$apiToken) { throw new ConfigException($key, $apiToken); } $key = "kintone.applications." . $appName . ".appId"; $appId = config($key); if (!$appId) { throw new ConfigException($key, $appId); } $this->addAppToken($appName); $this->host = $host; $this->appId = $appId; } public function addAppToken(string $appName): static { $key = "kintone.applications." . $appName . ".apiToken"; $apiToken = config($key); if (!$apiToken) { throw new ConfigException($key, $apiToken); } $this->apiToken = $this->apiToken ? $this->apiToken . "," . $apiToken : $apiToken; return $this; } public function setFields(array $fields): static { $this->fields = [ ...$fields, ...self::DEFAULT_FIELDS, ]; return $this; } public function __destruct() { $this->deleteCursor(); } /** * @param integer $id * @return TValue */ public function find(int $id) { $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->get($this->getRecordUrl(), [ "app" => $this->appId, "id" => $id, ]); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } $result = $this->modelName ? new $this->modelName() : new $this->appName(); $result->setDataFromRecordResponse($response['record']); return $result; } /** * @param KintoneRecordQuery|null|null $query * @return Collection */ public function some(KintoneRecordQuery|null $query = null) { $data = [ "app" => $this->appId, 'fields' => $this->fields, ]; if ($query !== null) { $data["query"] = $query->toQuery(); } $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->get($this->getRecordsUrl(), $data); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } $ret = collect(); foreach ($response["records"] as $data) { /** * @var KintoneModel $model */ $model = $this->modelName ? new $this->modelName() : new $this->appName(); $model->setDataFromRecordResponse($data); $ret->put($model->getRecordId(), $model); } return $ret; } /** * @param KintoneRecordQuery|null|null $query * @return TValue */ public function first(KintoneRecordQuery|null $query = null) { $list = $this->some($query); if ($list->count() !== 1) { throw new ModelNotFoundException(sprintf("モデル取得数エラー %s count:%d queey:<%s>", $this->appName, $list->count(), $query->toQuery())); } return $list->first(); } /** * @param TValue $model * @return void */ public function update(KintoneModel &$model) { $sendData = [ "app" => $this->appId, "id" => $model->getRecordId(), "record" => $model->getApiLayout(), "revision" => $model->getRevision(), ]; // logger([ // "ACTION" => "KINTONE UPDATE", // "APP" => $this->appName, // "RECORD_NO" => $model->getRecordId(), // "SEND_DATA" => $sendData, // "JSON" => json_encode($sendData, JSON_UNESCAPED_UNICODE), // ]); $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->put($this->getRecordUrl(), $sendData); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } $model->clean($response["revision"]); return $response; } /** * @param TValue $model * @return void */ public function create(KintoneModel &$model) { $sendData = [ "app" => $this->appId, "record" => $model->getApiLayout(), ]; $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->post($this->getRecordUrl(), $sendData); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); Log::error($response->body()); Log::error($sendData); throw $e; } } $model->clean($response["revision"]); $model->setRecordId($response["id"]); return $response; } public function createCursor(KintoneRecordQuery|null $query = null) { $data = [ "app" => $this->appId, 'fields' => $this->fields, ]; if ($query !== null) { $data["query"] = $query->toQuery(); } $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->post($this->getCursorUrl(), $data); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage(), ['data' => $data]); Log::error($response->body()); throw $e; } } $cursor = $response["id"]; $totalCount = intval($response["totalCount"]); $this->cursor = $cursor; if (0 < $totalCount) { $this->hasNext = true; $this->cursorDataCount = $totalCount; } else { $this->deleteCursor(); } return $response; } /** * @return Collection */ public function next() { if (!$this->hasNext) { return collect(); } $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->get($this->getCursorUrl(), [ "id" => $this->cursor, ]); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } $ret = collect(); $hasNext = $response["next"]; if (!$hasNext) { $this->cursor = null; $this->hasNext = false; $this->cursorDataCount = 0; } foreach ($response["records"] as $data) { /** * @var KintoneModel $model */ $model = new $this->appName(); $model->setDataFromRecordResponse($data); $ret->push($model); } return $ret; } /** * @return Collection */ public function all(KintoneRecordQuery|null $query = null) { if ($this->cursor !== null) { $this->deleteCursor(); } $this->createCursor($query); $list = collect(); while (true) { $ret = $this->next(); foreach ($ret as $ele) { $list->push($ele); } if ($this->cursor === null) { break; } } return $list; } public function deleteCursor() { if ($this->cursor === null) { return; } $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->delete($this->getCursorUrl(), [ "id" => $this->cursor, ]); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } $this->cursor = null; $this->hasNext = false; $this->cursorDataCount = 0; } public function fileGet(string $fileKey) { $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->get($this->getFileUrl(), [ "fileKey" => $fileKey, ]); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); Log::error($response->body()); throw $e; } } return $response; } /** * ファイルアップロード * * @param UploadedFile|TmpFile $file * @return string fileKey */ public function filePut(UploadedFile|TmpFile $file): string { $content = ""; $sendFileName = ""; if ($file instanceof UploadedFile) { $content = file_get_contents($file); $sendFileName = sprintf("file.%s", $file->extension()); } else if ($file instanceof TmpFile) { $content = $file->get(); $sendFileName = $file->getAppFileName(); } $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ]) ->attach("file", $content, $sendFileName) ->post($this->getFileUrl()); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); Log::error($response->body()); throw $e; } } return $response['fileKey']; } public function getAppFormFields(): array { $response = Http::withHeaders([ "X-Cybozu-API-Token" => $this->apiToken, ])->get($this->getAppFormFieldsUrl(), [ "app" => $this->appId, ]); if ($response->failed()) { $e = $response->toException(); if ($e instanceof Exception) { Log::error($e->getMessage()); throw $e; } } return $response['properties']; } private function getRecordUrl() { return $this->getUrl(self::URL_RECORD); } private function getRecordsUrl() { return $this->getUrl(self::URL_RECORDS); } private function getCursorUrl() { return $this->getUrl(self::URL_CURSOL); } private function getFileUrl() { return $this->getUrl(self::URL_FILE); } private function getAppFormFieldsUrl() { return $this->getUrl(self::URL_APP_FORM_FIELDS); } private function getUrl(string $path) { return $this->host . $path; } }