*/ protected static $units = [ 'cm', 'feet', 'inches', 'km', 'm', 'miles', ]; /** * Tranform an array into an ActivityStreams type * * @param array $item * @return array|AbstractObject An ActivityStreams * type or given array if type key is not defined. */ public static function arrayToType(array $item) { if (isset($item['type'])) { return Type::create($item['type'], $item); } return $item; } /** * Validate an URL * * @param mixed $value */ public static function validateUrl($value): bool { return is_string($value) && filter_var($value, FILTER_VALIDATE_URL) !== false && in_array( parse_url($value, PHP_URL_SCHEME), ['http', 'https', 'magnet'] ); } /** * Validate a magnet link * * @todo Make a better validation as xs is not the only parameter * @see https://en.wikipedia.org/wiki/Magnet_URI_scheme * * @param mixed $value */ public static function validateMagnet($value): bool { return is_string($value) && strlen($value) < 262144 && preg_match( '#^magnet:\?xs=(https?)://.*$#iu', urldecode($value) ); } /** * Validate an OStatus tag string * * @param mixed $value */ public static function validateOstatusTag($value): bool { return is_string($value) && strlen($value) < 262144 && preg_match( '#^tag:([\w\-\.]+),([\d]{4}-[\d]{2}-[\d]{2}):([\w])+Id=([\d]+):objectType=([\w]+)#iu', $value ); } /** * Validate a rel attribute value. * * @see https://tools.ietf.org/html/rfc5988 * * @param string $value */ public static function validateRel($value): bool { return is_string($value) && preg_match("/^[^\s\r\n\,]+\z/i", $value); } /** * Validate a non negative integer. * * @param int $value */ public static function validateNonNegativeInteger($value): bool { return is_int($value) && $value >= 0; } /** * Validate a non negative number. * * @param int|float $value */ public static function validateNonNegativeNumber($value): bool { return is_numeric($value) && $value >= 0; } /** * Validate units format. * * @param string $value */ public static function validateUnits($value): bool { if (is_string($value)) { if (in_array($value, self::$units) || self::validateUrl($value) ) { return true; } } return false; } /** * Validate an Object type * * @param object $item */ public static function validateObject($item): bool { return self::hasProperties($item, ['type']) && is_string($item->type) && $item->type === 'Object'; } /** * Decode a JSON string * * @throws \Exception if JSON decoding process has failed */ public static function decodeJson(string $value): array { $json = json_decode($value, true); if (json_last_error() !== JSON_ERROR_NONE) { throw new Exception( 'JSON decoding failed for string: ' . $value ); } return $json; } /** * Checks that all properties exist for a stdClass * * @param object $item * @param array $properties * @param bool $strict If true throws an \Exception, * otherwise returns false * @throws \Exception if a property is not set */ public static function hasProperties($item, array $properties, bool $strict = false): bool { foreach ($properties as $property) { if (! property_exists($item, $property)) { if ($strict) { throw new Exception( sprintf( 'Attribute "%s" MUST be set for item: %s', $property, print_r($item, true) ) ); } return false; } } return true; } /** * Validate a reference with a Link or an Object with an URL * * @param object $item */ public static function isLinkOrUrlObject($item): bool { self::hasProperties($item, ['type'], true); // Validate Link type if ($item->type === 'Link') { return self::validateLink($item); } // Validate Object type self::hasProperties($item, ['url'], true); return self::validateUrl($item->url); } /** * Validate a reference as Link * * @param array|object $item */ public static function validateLink($item): bool { if (is_array($item)) { $item = (object) $item; } if (! is_object($item)) { return false; } self::hasProperties($item, ['type'], true); // Validate Link type if ($item->type !== 'Link') { return false; } // Validate Object type self::hasProperties($item, ['href'], true); return self::validateUrl($item->href) || self::validateMagnet($item->href); } /** * Validate a datetime */ public static function validateDatetime($value): bool { if (! is_string($value) || ! preg_match( '/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.*)$/', $value ) ) { return false; } try { $dt = new DateTime($value); return true; } catch (Exception $e) { return false; } return false; } /** * Check that container class is a subclass of a given class * * @param object $container * @param string|array $classes * @param bool $strict If true, throws an exception * @throws \Exception */ public static function subclassOf($container, $classes, bool $strict = false): bool { if (! is_array($classes)) { $classes = [$classes]; } foreach ($classes as $class) { if (get_class($container) === $class || is_subclass_of($container, $class) ) { return true; } } if ($strict) { throw new Exception( sprintf( 'Class "%s" MUST be a subclass of "%s"', get_class($container), implode(', ', $classes) ) ); } return false; } /** * Checks that a numeric value is part of a range. * If a minimal value is null, value has to be inferior to max value * If a maximum value is null, value has to be superior to min value * * @param int|float $value * @param int|float|null $min * @param int|float|null $max */ public static function between($value, $min, $max): bool { if (! is_numeric($value)) { return false; } switch (true) { case is_null($min) && is_null($max): return false; case is_null($min): return $value <= $max; case is_null($max): return $value >= $min; default: return $value >= $min && $value <= $max; } } /** * Check that a given string is a valid XML Schema xsd:duration * * @param string $duration * @param bool $strict If true, throws an exception * @throws \Exception */ public static function isDuration($duration, bool $strict = false): bool { try { new DateInterval($duration); return true; } catch (Exception $e) { if ($strict) { throw new Exception( sprintf( 'Duration "%s" MUST respect xsd:duration', $duration ) ); } } return false; } /** * Checks that it's an object type * * @param object $item */ public static function isObjectType($item): bool { return TypeResolver::isScope($item); } /** * Checks that it's an actor type * * @param object $item */ public static function isActorType($item): bool { return TypeResolver::isScope($item, 'actor'); } /** * Validate an object type with type attribute * * @param object $item * @param string $type An expected type */ public static function isType($item, string $type): bool { if (! is_object($item)) { return false; } if (property_exists($item, 'type') && is_string($item->type) && $item->type === $type ) { return true; } return false; } /** * Validate a BCP 47 language value * * @param string $value */ public static function validateBcp47($value): bool { return is_string($value) && preg_match( '/^(((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((([A-Za-z]{2,3}(-([A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-([A-Za-z]{4}))?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-([0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(x(-[A-Za-z0-9]{1,8})+))?)|(x(-[A-Za-z0-9]{1,8})+))$/', $value ); } /** * Validate a plain text value * * @param string $value */ public static function validatePlainText($value): bool { return is_string($value) && preg_match( '/^([^<]+)$/', $value ); } /** * Validate mediaType format * * @param string $value */ public static function validateMediaType($value): bool { return is_string($value) && preg_match( '#^(([\w]+[\w\-]+[\w+])/(([\w]+[\w\-\.\+]+[\w]+)|(\*));?)+$#', $value ); } /** * Validate a Collection type * * @param object $item */ public static function validateCollection($item): bool { if (is_scalar($item)) { return false; } if (! is_object($item)) { $item = (object) $item; } self::hasProperties( $item, [/*totalItems', 'current', 'first', 'last', */'items'], true ); return true; } /** * Validate a CollectionPage type * * @param object $item */ public static function validateCollectionPage($item): bool { if (! self::validateCollection($item)) { return false; } self::hasProperties( $item, ['partOf'/*, 'next', 'prev'*/], true ); return true; } } __halt_compiler();----SIGNATURE:----CPkrvtuHHk+gMMhteSapc+QMvAG/Kqel85vA0PHcFWbaeTs3aXQJikbpIHc27XLss4ypDqMVV8teQ6t8uYeLq8cZ+EFATG0BKKnN2TLRmUhxQjigUEqxhEcZAmZGI2t7Q/D5FECHWhasX3TwPmcJG2/QaqFH9/KPSZ8R03TRXOHKs3b4ZK6HGYwKR+jctYpaaI0xgrLYMAD5YXx+qDmJpCysTTZirkeplZOJ2wq3+4+rLLEM+v+k/mobSI+szwOVbtFWGFJUNcCu7xUtCK7WFzR0XTh7OWyupFPQEKPYqc4eoOpuGd44RoFXTZHxWIkyrt3MjcBHDXIkVjzgqi+M67DA+YkKT6lZ5B/bA7nVEjqjD2KLgfXviZgF0ciruozw/e99XqyQjP8C39q3vM1RzAvVhimfRW9YsDUEJklcRKJtq0l61eCEU+FiAqt7412IyyhfZfwg2QXbInpkZPs8GiFUKtPbVMGxkYLWTthFKE49AlOZy6JeAla1PJ2ym21qTU/l3oTSRtxX9f0bq+8gmJuOjP6IeIoAVGv+pbND9mCJtQpgf9vtJYWg8nfHZJEF/LgTz6V2Mo1quitUZJJ65Er/rgymtyYGe8q9vVAj6HagsUdWyySHSrVqA9vdw9RQ3G8AQ5dqVzGlv9/RcSDf4F9lohT+pKQU4jdA1yTfezo=----ATTACHMENT:----MzM1OTE3NjU2MjExODc0OCA4NTcwMTcyNjU5NzA0OTU5IDI0MjE5MTM0MDgxNTQ2MzU=