Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

275 lines
6.5KB

  1. <?php
  2. namespace App\Kintone;
  3. use App\Exceptions\ConfigException;
  4. use App\Kintone\Models\KintoneModel;
  5. use Exception;
  6. use Illuminate\Http\Client\Response;
  7. use Illuminate\Support\Collection;
  8. use Illuminate\Support\Facades\Http;
  9. use Log;
  10. class KintoneAccess
  11. {
  12. private string $appName;
  13. private string $host;
  14. private string $apiToken;
  15. private int $appId;
  16. private string|null $cursor = null;
  17. private int $cursorDataCount = 0;
  18. private bool $hasNext = false;
  19. private const URL_RECORD = "/k/v1/record.json";
  20. private const URL_CURSOL = "/k/v1/records/cursor.json";
  21. public function __construct(string $appName)
  22. {
  23. $this->appName = $appName;
  24. $key = "kintone.host";
  25. $host = config($key);
  26. if (!$host) {
  27. throw new ConfigException("kintone.host", $host);
  28. }
  29. $key = "kintone.applications." . $appName . ".apiToken";
  30. $apiToken = config($key);
  31. if (!$apiToken) {
  32. throw new ConfigException($key, $apiToken);
  33. }
  34. $key = "kintone.applications." . $appName . ".appId";
  35. $appId = config($key);
  36. if (!$appId) {
  37. throw new ConfigException($key, $appId);
  38. }
  39. $this->host = $host;
  40. $this->apiToken = $apiToken;
  41. $this->appId = $appId;
  42. }
  43. public function __destruct()
  44. {
  45. $this->deleteCursor();
  46. }
  47. public function find(int $id, KintoneModel &$result): Response
  48. {
  49. $response = Http::withHeaders([
  50. "X-Cybozu-API-Token" => $this->apiToken,
  51. ])->get($this->getRecordUrl(), [
  52. "app" => $this->appId,
  53. "id" => $id,
  54. ]);
  55. if ($response->failed()) {
  56. $e = $response->toException();
  57. if ($e instanceof Exception) {
  58. throw $e;
  59. }
  60. }
  61. $result->setDataFromRecordResponse($response['record']);
  62. return $response;
  63. }
  64. public function update(KintoneModel &$model)
  65. {
  66. $response = Http::withHeaders([
  67. "X-Cybozu-API-Token" => $this->apiToken,
  68. ])->put($this->getRecordUrl(), [
  69. "app" => $this->appId,
  70. "id" => $model->getRecordId(),
  71. "record" => $model->getApiLayout(),
  72. "revision" => $model->getRevision(),
  73. ]);
  74. if ($response->failed()) {
  75. $e = $response->toException();
  76. if ($e instanceof Exception) {
  77. throw $e;
  78. }
  79. }
  80. $model->clean($response["revision"]);
  81. return $response;
  82. }
  83. public function create(KintoneModel &$model)
  84. {
  85. $response = Http::withHeaders([
  86. "X-Cybozu-API-Token" => $this->apiToken,
  87. ])->post($this->getRecordUrl(), [
  88. "app" => $this->appId,
  89. "record" => $model->getApiLayout(),
  90. ]);
  91. if ($response->failed()) {
  92. $e = $response->toException();
  93. if ($e instanceof Exception) {
  94. Log::error($e->getMessage());
  95. throw $e;
  96. }
  97. }
  98. $model->clean($response["revision"]);
  99. $model->setRecordId($response["id"]);
  100. return $response;
  101. }
  102. public function createCursor(KintoneRecordQuery|null $query = null, array|null $fields = null)
  103. {
  104. $data = [
  105. "app" => $this->appId,
  106. ];
  107. if ($query !== null) {
  108. $data["query"] = $query->toQuery();
  109. }
  110. if ($fields !== null) {
  111. $data["fields"] = $fields;
  112. }
  113. $response = Http::withHeaders([
  114. "X-Cybozu-API-Token" => $this->apiToken,
  115. ])->post($this->getCursorUrl(), $data);
  116. if ($response->failed()) {
  117. $e = $response->toException();
  118. if ($e instanceof Exception) {
  119. Log::error($e->getMessage());
  120. throw $e;
  121. }
  122. }
  123. $this->cursor = $response["id"];
  124. $this->cursorDataCount = $response["totalCount"];
  125. if (0 < $this->cursorDataCount) {
  126. $this->hasNext = true;
  127. }
  128. return $response;
  129. }
  130. /**
  131. * @return Collection<KintoneModel>
  132. */
  133. public function next()
  134. {
  135. if (!$this->hasNext) {
  136. return collect();
  137. }
  138. $response = Http::withHeaders([
  139. "X-Cybozu-API-Token" => $this->apiToken,
  140. ])->get($this->getCursorUrl(), [
  141. "id" => $this->cursor,
  142. ]);
  143. if ($response->failed()) {
  144. $e = $response->toException();
  145. if ($e instanceof Exception) {
  146. Log::error($e->getMessage());
  147. throw $e;
  148. }
  149. }
  150. $ret = collect();
  151. $hasNext = $response["next"];
  152. if (!$hasNext) {
  153. $this->cursor = null;
  154. $this->hasNext = false;
  155. $this->cursorDataCount = 0;
  156. }
  157. foreach ($response["records"] as $data) {
  158. /**
  159. * @var KintoneModel $model
  160. */
  161. $model = new $this->appName();
  162. $model->setDataFromRecordResponse($data);
  163. $ret->push($model);
  164. }
  165. return $ret;
  166. }
  167. /**
  168. * @return Collection<KintoneModel>
  169. */
  170. public function all(KintoneRecordQuery|null $query = null, array|null $fields = null)
  171. {
  172. if ($this->cursor !== null) {
  173. $this->deleteCursor();
  174. }
  175. $this->createCursor($query, $fields);
  176. $list = collect();
  177. while (true) {
  178. $ret = $this->next();
  179. foreach ($ret as $ele) {
  180. $list->push($ele);
  181. }
  182. if ($this->cursor === null) {
  183. break;
  184. }
  185. }
  186. return $list;
  187. }
  188. public function deleteCursor()
  189. {
  190. if ($this->cursor === null) {
  191. return;
  192. }
  193. $response = Http::withHeaders([
  194. "X-Cybozu-API-Token" => $this->apiToken,
  195. ])->delete($this->getCursorUrl(), [
  196. "id" => $this->cursor,
  197. ]);
  198. if ($response->failed()) {
  199. $e = $response->toException();
  200. if ($e instanceof Exception) {
  201. Log::error($e->getMessage());
  202. throw $e;
  203. }
  204. }
  205. $this->cursor = null;
  206. $this->hasNext = false;
  207. $this->cursorDataCount = 0;
  208. }
  209. private function getRecordUrl()
  210. {
  211. return $this->getUrl(self::URL_RECORD);
  212. }
  213. private function getCursorUrl()
  214. {
  215. return $this->getUrl(self::URL_CURSOL);
  216. }
  217. private function getUrl(string $path)
  218. {
  219. return $this->host . $path;
  220. }
  221. }