<?php namespace ActivityPhp\Type; use Exception; /** * \ActivityPhp\Type\Dialect is an abstract class for * dialects management. */ abstract class Dialect { /** * A list of supported dialects by their names * * @var array */ private static $dialects = []; /** * A list of types => properties * where properties overloads basic ones * * @var array * * [ * 'Person' => [ * 'propertyName' => [ * 'defaultValue' => null, * 'validator' => '', * 'dialects' => ['mastodon', 'peertube'], * ] * ] * ] */ private static $definitions = []; /** * Loaded types definitions * * @var array */ private static $loaded = []; /** * Clear all dialects, definitions and loaded array */ public static function clear() { self::$dialects = []; self::$definitions = []; self::$loaded = []; } /** * Load a dialect as an active one. * * @param string $dialect Dialect name. */ public static function load(string $dialect) { $dialects = []; if ($dialect == '*') { $dialects = self::$dialects; } else { $dialects[] = $dialect; } foreach ($dialects as $dialect) { // Dialect does not exist if (!in_array($dialect, self::$dialects)) { throw new Exception( "Dialect '{$dialect}' has no definition" ); } // dialect not already loaded ? if (!in_array($dialect, self::$loaded)) { array_push(self::$loaded, $dialect); } } // Load new types foreach (self::$definitions as $type => $properties) { foreach ($properties as $property => $definition) { if (count(array_intersect($definition['dialects'], self::$loaded))) { if (!TypeResolver::exists($type)) { TypeResolver::addDialectType($type); } } } } } /** * Unload a dialect. * * @param string $dialect Dialect name. */ public static function unload(string $dialect) { self::$loaded = array_filter( self::$loaded, function ($value) use ($dialect) { return $value != $dialect && $dialect != '*'; } ); // Unload new types foreach (self::$definitions as $type => $properties) { foreach ($properties as $property => $definition) { if (!count(array_intersect($definition['dialects'], self::$loaded))) { if (TypeResolver::exists($type)) { TypeResolver::removeDialectType($type); } } } } } /** * Add a dialect definition in the pool. * * @param string $name Dialect name. * @param array $definition Types definitions * @param bool $load */ public static function add(string $name, array $definition, bool $load = true) { // dialect not already defined ? if (!in_array($name, self::$dialects)) { array_push(self::$dialects, $name); } /* --------------------------------------------------------- | Push definition into definitions | --------------------------------------------------------- */ // Extend Types properties foreach ($definition as $types => $properties) { $xpt = explode('|', $types); foreach ($xpt as $type) { if (!is_array($properties)) { throw new Exception( "Properties for Type '$type' must be an array." . " Given=" . print_r($properties, true) ); } self::putType($type, $properties, $name); // Define new types if needed if ($load && !TypeResolver::exists($type)) { TypeResolver::addDialectType($type); } } } // load if needed if ($load && !in_array($name, self::$loaded)) { array_push(self::$loaded, $name); } } /** * Add a type in the pool. * * @param string $type Type name. * @param array $definition * @param string $dialect Dialect name */ private static function putType(string $type, array $properties, string $dialect) { // Type already extended ? if (!isset(self::$definitions[$type])) { self::$definitions[$type] = []; } // Define a property foreach ($properties as $property => $config) { if (is_string($config)) { $property = $config; } self::$definitions[$type][$property] = self::createProperty($type, $property, $config, $dialect); } } /** * Transform various form of property configs into a local and * exploitable property configuration. * * @param string $type * @param string $property * @param string|array $config * @param string $dialect * @return array */ private static function createProperty(string $type, string $property, $config, string $dialect) { $local = [ 'defaultValue' => null, 'validator' => null, 'dialects' => [], ]; // Property already defined if (array_key_exists($property, self::$definitions[$type])) { $local = self::$definitions[$type][$property]; } // New dialect attachment for this property if (!in_array($dialect, $local['dialects'])) { array_push($local['dialects'], $dialect); } $local['defaultValue'] = is_array($config) && isset($config['defaultValue']) ? $config['defaultValue'] : null; // Validator should be loaded in type factory when this // dialect is loaded $local['validator'] = is_array($config) && isset($config['validator']) ? $config['validator'] : null; return $local; } /** * Check if there is a dialect that extends a given type * * @param \ActivityPhp\Type\AbstractObject $type */ public static function extend(AbstractObject $type) { // No extensions for this type if (!isset(self::$definitions[$type->type])) { return; } $definition = self::$definitions[$type->type]; foreach ($definition as $property => $config) { // Dialect is not loaded for this property if (!count(array_intersect(self::$loaded, $config['dialects']))) { continue; } // Extends type $type->extend($property, $config['defaultValue']); // @todo Loads a validator for property } } /** * Get all loaded dialects (defined and loaded) * * @return array */ public static function getLoadedDialects() { return self::$loaded; } /** * Get defined dialects (ready to load) * * @return array */ public static function getDialects() { return self::$dialects; } /** * Get all defined ActivityPub Dialects definitions * * @return array */ public static function getDefinitions() { return self::$definitions; } } __halt_compiler();----SIGNATURE:----XXu38jYgtL3SF/Wnag0fCAJ/juakLzO0grKuCmw11jBM+7GPqSILIhrg26wKHUXKlExzgfRGQNCe1mHtQdnPglewKCRNnthXvcnZmQm/mD3t5y9WvKU0n0wRVxwn2J7cdEAgh+qrQ/Lg5AeasevnWLI3Plq7Lf1/+FrpN8Z7j3WUPHAZ2XALv0FJHT+32f7dGTkk8qQDY9qes0GTg677e3B/hnY5j/LDyX7/tHfv3oVKJgfCqK4HZNTnC/84v5iW9Uhh8ev8AErz0L2MIPERoMeapfxByu8PL2lOQbNnth3qF/dXV+Mw84DXA1IfIchabFxHw6PHMWtw6rhzXWGXk1XX1x0j1ydXfkjnhjZP8e7j95aLx+sInG5c8guXwnabZjXzOTTNcg1ceOuRWLRbcYJ8ebVqKLjdr/PkI1oiOd166rEWm8HgLS6FFlOBqoGlPbMtiFMX2JShLc/tg+4vyTHtwYx7cj79lRfbrEbevYu3jinPZE9IwmxT/ScPYj0WkLdq4IDErrkycAIjPlw4JaeoykZcNF/AKXeay9PdkY7L3v+aZIf0T35VgySApOVwnD+FMvJ75lYgqk/DB2f+WXTE8aNYWPacQ6t8OU268LeA1JJbd7zcllxxswUuJuwtnACBUofsVYwSrSgfEnthhqYYzFxJXXRQNMDYUrIDJQw=----ATTACHMENT:----Mzg2Mzc2NzQ3NDM0MTU3IDIyOTA2OTgxNzE4NDk2ODggMzIzMjU4ODMwODc5Njk2