/** * {@inheritdoc} */ public function guard($value, Field $field) { /** @var BigNumber $value */ Assertion::isInstanceOf($value, 'Gdbots\\Pbj\\WellKnown\\BigNumber', null, $field->getName()); Assertion::true($value->isGreaterThanOrEqualTo('-9223372036854775808'), sprintf('Field [%s] cannot be less than [-9223372036854775808].', $field->getName()), $field->getName()); Assertion::true($value->isLessThanOrEqualTo('9223372036854775807'), sprintf('Field [%s] cannot be greater than [9223372036854775807].', $field->getName()), $field->getName()); }
/** * {@inheritdoc} */ public function guard($value, Field $field) { /** @var BigNumber $value */ Assertion::isInstanceOf($value, 'Gdbots\\Pbj\\WellKnown\\BigNumber', null, $field->getName()); Assertion::true(!$value->isNegative(), sprintf('Field [%s] cannot be negative.', $field->getName()), $field->getName()); Assertion::true($value->isLessThanOrEqualTo('18446744073709551615'), sprintf('Field [%s] cannot be greater than [18446744073709551615].', $field->getName()), $field->getName()); }
/** * {@inheritdoc} */ public function guard($value, Field $field) { Assertion::string($value, null, $field->getName()); // intentionally using strlen to get byte length, not mb_strlen $length = strlen($value); $minLength = $field->getMinLength(); $maxLength = NumberUtils::bound($field->getMaxLength(), $minLength, $this->getMaxBytes()); $okay = $length >= $minLength && $length <= $maxLength; Assertion::true($okay, sprintf('Field [%s] must be between [%d] and [%d] bytes, [%d] bytes given.', $field->getName(), $minLength, $maxLength, $length), $field->getName()); }
/** * {@inheritdoc} */ public function guard($value, Field $field) { parent::guard($value, $field); if ($pattern = $field->getPattern()) { Assertion::regex($value, $pattern, null, $field->getName()); } switch ($field->getFormat()->getValue()) { case Format::UNKNOWN: break; case Format::DATE: Assertion::regex($value, '/^\\d{4}-\\d{2}-\\d{2}$/', null, $field->getName()); break; case Format::DATE_TIME: Assertion::true(DateUtils::isValidISO8601Date($value), sprintf('Field [%s] must be a valid ISO8601 date-time. Format must match one of [%s], [%s] or [%s].', $field->getName(), DateUtils::ISO8601_ZULU, DateUtils::ISO8601, \DateTime::ISO8601), $field->getName()); break; case Format::SLUG: Assertion::regex($value, '/^([\\w\\/-]|[\\w-][\\w\\/-]*[\\w-])$/', null, $field->getName()); break; case Format::EMAIL: Assertion::email($value, null, $field->getName()); break; case Format::HASHTAG: Assertion::true(HashtagUtils::isValid($value), sprintf('Field [%s] must be a valid hashtag. @see HashtagUtils::isValid', $field->getName()), $field->getName()); break; case Format::IPV4: case Format::IPV6: /* * todo: need separate assertion for ipv4 and ipv6 */ Assertion::url('http://' . $value, sprintf('Field [%s] must be a valid [%s].', $field->getName(), $field->getFormat()->getValue()), $field->getName()); break; case Format::HOSTNAME: case Format::URI: case Format::URL: /* * fixme: need better handling for HOSTNAME, URI and URL... assertion library just has one "url" handling * but we really need separate ones for each of these formats. right now we're just prefixing * the value with a http so it looks like a url. this won't work for thinks like mailto: * urn:, etc. */ if (false === strpos($value, 'http')) { $value = 'http://' . $value; } Assertion::url($value, sprintf('Field [%s] must be a valid [%s].', $field->getName(), $field->getFormat()->getValue()), $field->getName()); break; case Format::UUID: Assertion::uuid($value, null, $field->getName()); break; default: break; } }
/** * {@inheritdoc} */ public function guard($value, Field $field) { /** @var Identifier $value */ Assertion::isInstanceOf($value, 'Gdbots\\Pbj\\WellKnown\\Identifier', null, $field->getName()); Assertion::isInstanceOf($value, $field->getClassName(), null, $field->getName()); $v = $value->toString(); //Assertion::string($v, null, $field->getName()); // intentionally using strlen to get byte length, not mb_strlen $length = strlen($v); $maxBytes = $this->getMaxBytes(); $okay = $length > 0 && $length <= $maxBytes; Assertion::true($okay, sprintf('Field [%s] must be between [1] and [%d] bytes, [%d] bytes given.', $field->getName(), $maxBytes, $length), $field->getName()); }
/** * @param string $curie * @return SchemaCurie * @throws InvalidSchemaCurie */ public static function fromString($curie) { if (isset(self::$instances[$curie])) { return self::$instances[$curie]; } $okay = strlen($curie) < 146; Assertion::true($okay, 'SchemaCurie cannot be greater than 145 chars.', 'curie'); if (!preg_match(self::VALID_PATTERN, $curie, $matches)) { throw new InvalidSchemaCurie(sprintf('SchemaCurie [%s] is invalid. It must match the pattern [%s].', $curie, self::VALID_PATTERN)); } self::$instances[$curie] = new self($matches[1], $matches[2], $matches[3], $matches[4]); return self::$instances[$curie]; }
/** * {@inheritdoc} */ public function guard($value, Field $field) { /** @var Message $value */ Assertion::isInstanceOf($value, 'Gdbots\\Pbj\\Message', null, $field->getName()); Assertion::isInstanceOf($value, $field->getClassName(), null, $field->getName()); if (!$field->hasAnyOfClassNames()) { return; } $classNames = $field->getAnyOfClassNames(); if (empty($classNames)) { // means it can be "any message" return; } foreach ($classNames as $className) { if ($value instanceof $className) { return; } } Assertion::true(false, sprintf('Field [%s] must be an instance of at least one of: %s.', $field->getName(), implode(',', $classNames)), $field->getName()); }
/** * {@inheritdoc} */ public function guard($value, Field $field) { Assertion::integer($value, null, $field->getName()); Assertion::true(DateUtils::isValidTimestamp($value), sprintf('Field [%s] value [%d] is not a valid unix timestamp.', $field->getName(), $value), $field->getName()); }
/** * @param mixed $default * @throws AssertionFailed * @throws \Exception */ private function guardDefault($default) { if ($this->isASingleValue()) { $this->guardValue($default); return; } Assertion::nullOrIsArray($default, sprintf('Field [%s] default must be an array.', $this->name)); if (null === $default) { return; } if ($this->isAMap()) { Assertion::true(ArrayUtils::isAssoc($default), sprintf('Field [%s] default must be an associative array.', $this->name)); } foreach ($default as $k => $v) { Assertion::notNull($v, sprintf('Field [%s] default for key [%s] cannot be null.', $this->name, $k)); $this->guardValue($v); } }
/** * @param array $data * @return Message * * @throws \Exception * @throws GdbotsPbjException */ private function doDeserialize(array $data) { $schemaId = SchemaId::fromString((string) $data[Schema::PBJ_FIELD_NAME]); $className = MessageResolver::resolveId($schemaId); /** @var Message $message */ $message = new $className(); Assertion::isInstanceOf($message, 'Gdbots\\Pbj\\Message'); if ($message::schema()->getCurieMajor() !== $schemaId->getCurieMajor()) { throw new InvalidResolvedSchema($message::schema(), $schemaId, $className); } $schema = $message::schema(); foreach ($data as $fieldName => $value) { if (!$schema->hasField($fieldName)) { continue; } if (null === $value) { $message->clear($fieldName); continue; } $field = $schema->getField($fieldName); $type = $field->getType(); switch ($field->getRule()->getValue()) { case FieldRule::A_SINGLE_VALUE: $message->set($fieldName, $type->decode($value, $field, $this)); break; case FieldRule::A_SET: case FieldRule::A_LIST: Assertion::isArray($value, sprintf('Field [%s] must be an array.', $fieldName), $fieldName); $values = []; foreach ($value as $v) { $values[] = $type->decode($v, $field, $this); } if ($field->isASet()) { $message->addToSet($fieldName, $values); } else { $message->addToList($fieldName, $values); } break; case FieldRule::A_MAP: Assertion::true(ArrayUtils::isAssoc($value), sprintf('Field [%s] must be an associative array.', $fieldName), $fieldName); foreach ($value as $k => $v) { $message->addToMap($fieldName, $k, $type->decode($v, $field, $this)); } break; default: break; } } return $message->set(Schema::PBJ_FIELD_NAME, $schema->getId()->toString())->populateDefaults(); }
/** * {@inheritdoc} * @return static */ public final function removeFromMap($fieldName, $key) { $this->guardFrozenMessage(); $field = static::schema()->getField($fieldName); Assertion::true($field->isAMap(), sprintf('Field [%s] must be a map.', $fieldName), $fieldName); unset($this->data[$fieldName][$key]); if (empty($this->data[$fieldName])) { $this->clearedFields[$fieldName] = true; } return $this; }
/** * @param string $schemaId * @return SchemaId * @throws InvalidSchemaId */ public static function fromString($schemaId) { if (isset(self::$instances[$schemaId])) { return self::$instances[$schemaId]; } $okay = strlen($schemaId) < 151; Assertion::true($okay, 'Schema id cannot be greater than 150 chars.', 'schemaId'); if (!preg_match(self::VALID_PATTERN, $schemaId, $matches)) { throw new InvalidSchemaId(sprintf('Schema id [%s] is invalid. It must match the pattern [%s].', $schemaId, self::VALID_PATTERN)); } self::$instances[$schemaId] = new self($matches[1], $matches[2], $matches[3], $matches[4], $matches[5]); return self::$instances[$schemaId]; }