|
- <?php
-
- namespace App\Kintone;
-
- use App\Exceptions\AppCommonException;
- use App\Exceptions\ConfigException;
- use App\Files\TmpFile;
- use App\Kintone\Models\KintoneModel;
- use Exception;
- use Illuminate\Database\Eloquent\ModelNotFoundException;
- use Illuminate\Http\UploadedFile;
- use Illuminate\Support\Collection;
- use Illuminate\Support\Facades\Http;
- use Log;
-
- /**
- * @template TValue of KintoneModel
- */
- class KintoneAccess
- {
-
- private string $appName;
- private ?string $modelName;
- private string $host;
- private string $apiToken = "";
- private int $appId;
-
- private const DEFAULT_FIELDS = [
- "作成日時",
- "更新日時",
- '$id',
- '$revision',
- ];
-
- private array $fields = [];
-
- private string|null $cursor = null;
- private int $cursorDataCount = 0;
- private bool $hasNext = false;
-
- private const URL_RECORD = "/k/v1/record.json";
- private const URL_RECORDS = "/k/v1/records.json";
- private const URL_CURSOL = "/k/v1/records/cursor.json";
- private const URL_FILE = "/k/v1/file.json";
- private const URL_APP_FORM_FIELDS = "/k/v1/app/form/fields.json";
-
-
- public function __construct(string $appName, ?string $modelName)
- {
- $this->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<string,TValue>
- */
- 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<int,TValue>
- */
- 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<int,TValue>
- */
- 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;
- }
- }
|