type = $params['type'] ?? null; $obj->attribute = $params['attribute'] ?? $params['field'] ?? null; $obj->value = $params['value'] ?? null; $obj->dateTime = $params['dateTime'] ?? false; $obj->timeZone = $params['timeZone'] ?? null; unset($params['field']); foreach (array_keys($params) as $key) { if (!property_exists($obj, $key)) { throw new InvalidArgumentException("Unknown parameter '{$key}'."); } } if (!$obj->type) { throw new InvalidArgumentException("No 'type' in where item."); } if ( !$obj->attribute && !in_array($obj->type, $obj->noAttributeTypeList) ) { throw new InvalidArgumentException("No 'attribute' in where item."); } if (in_array($obj->type, $obj->withNestedItemsTypeList)) { $obj->value = $obj->value ?? []; if ( !is_array($obj->value) || count($obj->value) && array_keys($obj->value) !== range(0, count($obj->value) - 1) ) { throw new InvalidArgumentException("Bad 'value'."); } } return $obj; } public static function fromRawAndGroup(array $paramList): self { return self::fromRaw([ 'type' => self::TYPE_AND, 'value' => $paramList, ]); } public function getRaw(): array { $raw = [ 'type' => $this->type, 'value' => $this->value, ]; if ($this->attribute) { $raw['attribute'] = $this->attribute; } if ($this->dateTime) { $raw['dateTime'] = $this->dateTime; } if ($this->timeZone) { $raw['timeZone'] = $this->timeZone; } return $raw; } /** * Get a type; */ public function getType(): string { return $this->type; } /** * Get an attribute. */ public function getAttribute(): ?string { return $this->attribute; } /** * Get a value. * * @return mixed */ public function getValue() { return $this->value; } /** * Get nested where items (for 'and', 'or' types). * * @return Item[] * * @throws RuntimeException If a type does not support nested items. */ public function getItemList(): array { if (!in_array($this->type, $this->withNestedItemsTypeList)) { throw new RuntimeException("Nested items not supported for '{$this->type}' type."); } $list = []; foreach ($this->value as $raw) { $list[] = Item::fromRaw($raw); } return $list; } /** * Whether is 'date-time'. */ public function isDateTime(): bool { return $this->dateTime; } /** * Get a time zone. Actual only for 'date-time' items. */ public function getTimeZone(): ?string { return $this->timeZone; } /** * Create a builder. */ public static function createBuilder(): ItemBuilder { return new ItemBuilder(); } }