|
- <?php
-
- namespace App\Kintone\Models;
-
- use App\Exceptions\AppCommonException;
- use App\Exceptions\ConfigException;
- use App\Kintone\File;
- use App\Kintone\KintoneAccess;
- use App\Kintone\KintoneRecordQuery;
- use App\Util\DateUtil;
- use Illuminate\Support\Arr;
- use Illuminate\Support\Carbon;
- use LogicException;
- use stdClass;
-
- abstract class KintoneModel
- {
- const CONFIG_KEY = "";
-
- const FIELD_RECORD_NUMBER = "レコード番号";
- const FIELD_CREATED_TIME = "作成日時";
- const FIELD_UPDATED_TIME = "更新日時";
-
- static public function configKey(): string
- {
- if (!static::CONFIG_KEY) {
- throw new LogicException(sprintf("Kintone 設定キー 未設定:%s", static::class));
- }
- return static::CONFIG_KEY;
- }
-
- static public function setConfig(): array
- {
-
- $configStr = env(static::configKey());
- if (!$configStr) {
- throw new ConfigException(static::configKey(), $configStr);
- }
-
- $params = explode(",", $configStr);
- if (count($params) !== 2) {
- throw new ConfigException(static::configKey(), $configStr);
- }
-
- [$apiToken, $appId] = $params;
-
- return [static::class => [
- 'apiToken' => $apiToken,
- 'appId' => (int)$appId,
- ]];
- }
-
- /**
- * @return KintoneAccess<static>
- */
- static public function getAccess(): KintoneAccess
- {
- $access = new KintoneAccess(static::class);
- $access->setFields(array_keys(static::FIELDS));
- return $access;
- }
-
- /**
- * @return KintoneRecordQuery<static>
- */
- static public function getQuery(): KintoneRecordQuery
- {
- return new KintoneRecordQuery(static::class);
- }
- protected ?int $recordId = null;
-
- protected ?int $revision = null;
-
- protected ?Carbon $createdAt = null;
-
- protected ?Carbon $updatedAt = null;
-
- protected ?stdClass $dataOrigin = null;
- protected stdClass $data;
-
- protected const FIELDS = [];
-
- protected const FIELD_NAMES = [];
-
- private array $changed = [];
-
- public function __construct()
- {
- $this->data = new stdClass();
- }
-
- public function set(string $fieldCode, $value)
- {
- $field = Arr::get(static::FIELDS, $fieldCode);
- if ($field instanceof FieldType) {
- $this->setData($fieldCode, $field, $value);
- } else if (is_array($field)) {
- $this->setTable($fieldCode, $value);
- }
-
- data_set($this->changed, $fieldCode, true);
- return $this;
- }
-
- private function setTable(string $fieldCode, array $table)
- {
- foreach ($table as $index => $row) {
- $row = data_get($row, "value");
- $this->setTableRow($fieldCode, $index, $row);
- }
- }
-
- private function setTableRow(string $fieldCode, int $index, array $row)
- {
- foreach ($row as $columnFieldCode => $column) {
- $value = $column["value"];
- $type = static::FIELDS[$fieldCode][$columnFieldCode];
- $insertKey = sprintf("%s.%d.%s", $fieldCode, $index, $columnFieldCode);
- $this->setData($insertKey, $type, $value);
- }
- }
-
- private function setData(string $path, FieldType $type, $value)
- {
-
-
-
- return $this;
- // if (
- // $type === FieldType::STRING ||
- // $type === FieldType::ARRAY
- // ) {
- // data_set($this->data, $path, $value);
- // // logger([$path, $value]);
- // return $this;
- // }
- // if ($type === FieldType::DATETIME) {
- // data_set($this->data, $path, DateUtil::parse($value));
- // return $this;
- // }
- }
-
- public function setDataFromRecordResponse(array $data): bool
- {
- $ret = true;
- foreach ($data as $fieldCode => $ele) {
- $type = data_get($ele, "type");
- $value = data_get($ele, "value");
- if ($type === "RECORD_NUMBER") {
- $this->recordId = $value;
- continue;
- }
- if ($type === "__REVISION__") {
- $this->revision = $value;
- continue;
- }
- if ($type === "CREATED_TIME") {
- $this->createdAt = DateUtil::parse($value);
- continue;
- }
- if ($type === "UPDATED_TIME") {
- $this->updatedAt = DateUtil::parse($value);
- continue;
- }
-
- $type = FieldType::tryFrom($type);
- if ($type === null) continue;
-
- if ($type === FieldType::DATETIME) {
- if ($value) {
- data_set($this->data, $fieldCode, DateUtil::parse($value));
- } else {
- data_set($this->data, $fieldCode, null);
- }
- continue;
- }
- if ($type === FieldType::FILE) {
- $ret = [];
- foreach ($value as $f) {
- $ret[] = new File($f);
- }
- data_set($this->data, $fieldCode, $ret);
- continue;
- }
- if ($type === FieldType::SUBTABLE) {
- continue;
- }
-
-
- // 以外はそのまま格納
- data_set($this->data, $fieldCode, $value);
- }
-
- $ret = $this->setDataCustom($data);
- if ($ret) {
- $this->clean();
- }
- return $ret;
- }
-
- /**
- * 変更前データを現在データで上書きする
- *
- * @return void
- */
- public function clean(?int $revision = null)
- {
- $this->dataOrigin = clone $this->data;
- if ($revision !== null) {
- $this->revision = $revision;
- }
- $this->changed = [];
- }
-
- public function getApiLayout(): array
- {
- $ret = [];
- foreach (static::FIELDS as $fieldCode => $type) {
-
- // 変更があった項目のみレイアウトへ出力する
- if (!Arr::has($this->changed, $fieldCode)) {
- continue;
- }
-
- $path = sprintf("%s.value", $fieldCode);
- if ($type === FieldType::DATETIME) {
- data_set($ret, $path, $this->getDate($fieldCode)->toIso8601ZuluString());
- continue;
- }
- data_set($ret, $path, data_get($this->data, $fieldCode));
- }
-
- return array_merge($ret, $this->getApiLayoutCustom());
- }
-
- public function get(string $key)
- {
- $a = json_decode(json_encode($this->data), true);
- return data_get($this->data, $key);
- }
-
- public function getStr(string $key): ?string
- {
- return $this->get($key);
- }
-
- public function getNumber(string $key): ?int
- {
- return $this->get($key);
- }
-
- public function getDate(string $key): ?Carbon
- {
- return $this->get($key);
- }
-
- public function getTable(string $key): ?array
- {
- return $this->get($key);
- }
-
- public function getRecordId(): ?int
- {
- return $this->recordId;
- }
- public function setRecordId(int $recordId): void
- {
- $this->recordId = $recordId;
- }
-
- public function getRevision(): ?int
- {
- return $this->revision;
- }
-
- public function setRevision(int $revision): void
- {
- $this->revision = $revision;
- }
-
- public function getUpdatedAt(): ?Carbon
- {
- return $this->updatedAt;
- }
- public function getCreatedAt(): ?Carbon
- {
- return $this->createdAt;
- }
-
- public function toArray(): array
- {
- if ($this->recordId === null) {
- throw new LogicException("保存前モデルのシリアライズ検知");
- }
-
- $ret = [
- 'record_no' => $this->recordId,
- 'revision' => $this->revision,
- ];
-
- /**
- * @var string $fieldCode
- */
- foreach ($this->data as $fieldCode => $value) {
-
- $type = data_get(static::FIELDS, $fieldCode);
-
- $columnName = data_get(static::FIELD_NAMES, $fieldCode, $fieldCode);
-
- if ($type === null) {
- $ret[$columnName] = $value;
- continue;
- }
-
- if ($type === FieldType::DATETIME) {
- if ($value instanceof Carbon) {
- $ret[$columnName] = $value->format('Y/m/d H:i:s');
- } else {
- $ret[$columnName] = $value;
- }
- continue;
- }
-
-
- $ret[$columnName] = $value;
- }
-
-
- return $ret;
- }
-
-
- /**
- * オーバーライドを期待
- *
- * @param array $data
- * @return boolean
- */
- protected function setDataCustom(array $data): bool
- {
- return true;
- }
- /**
- * オーバーライドを期待
- *
- * @return array
- */
- protected function getApiLayoutCustom(): array
- {
- return [];
- }
- }
|