src/ActivityPhp/Type/TypeResolver.php
<?php
/*
* This file is part of the ActivityPhp package.
*
* Copyright (c) landrok at github.com/landrok
*
* For the full copyright and license information, please see
* <https://github.com/landrok/activitypub/blob/master/LICENSE>.
*/
namespace ActivityPhp\Type;
use ActivityPhp\Type\Core\ObjectType;
use Exception;
/**
* \ActivityPhp\Type\TypeResolver is an abstract class for
* resolving class names called by their short names (AS types).
*/
abstract class TypeResolver
{
/**
* A list of core types
*
* @var array
*/
protected static $coreTypes = [
'Activity', 'Collection', 'CollectionPage',
'IntransitiveActivity', 'Link', 'ObjectType',
'OrderedCollection', 'OrderedCollectionPage',
'Object'
];
/**
* A list of actor types
*
* @var array
*/
protected static $actorTypes = [
'Application', 'Group', 'Organization', 'Person', 'Service'
];
/**
* A list of activity types
*
* @var array
*/
protected static $activityTypes = [
'Accept', 'Add', 'Announce', 'Arrive', 'Block',
'Create', 'Delete', 'Dislike', 'Flag', 'Follow',
'Ignore', 'Invite', 'Join', 'Leave', 'Like', 'Listen',
'Move', 'Offer', 'Question', 'Read', 'Reject', 'Remove',
'TentativeAccept', 'TentativeReject', 'Travel', 'Undo',
'Update', 'View',
];
/**
* A list of object types
*
* @var array
*/
protected static $objectTypes = [
'Article', 'Audio', 'Document', 'Event', 'Image',
'Mention', 'Note', 'Page', 'Place', 'Profile',
'Relationship', 'Tombstone', 'Video',
];
/**
* A list of custom types
*
* @var array
*/
protected static $customTypes = [];
/**
* A list of dialect types
*
* @var array
*/
protected static $dialectTypes = [];
/**
* Add a custom type definition in the pool.
*
* @param string $name A short name.
* @param string $class Fully qualified class name.
* @throws \Exception if class does not exist
*/
public static function addCustomType(string $name, string $class)
{
if (!class_exists($class)) {
throw new Exception(
sprintf(
'Class "%s" is not defined',
$class
)
);
}
self::$customTypes[$name] = $class;
}
/**
* Get namespaced class for a given short type
*
* @param string $type
* @return string Related namespace
* @throw \Exception if a namespace was not found.
*/
public static function getClass($type)
{
$ns = __NAMESPACE__;
if ($type == 'Object') {
$type .= 'Type';
}
switch ($type) {
// Custom dialect types
case in_array($type, self::$dialectTypes):
$class = new ObjectType();
$class->type = $type;
return $class;
// Custom classes by facades
case isset(self::$customTypes[$type]):
return self::$customTypes[$type];
case in_array($type, self::$coreTypes):
$ns .= '\Core';
break;
case in_array($type, self::$activityTypes):
$ns .= '\Extended\Activity';
break;
case in_array($type, self::$actorTypes):
$ns .= '\Extended\Actor';
break;
case in_array($type, self::$objectTypes):
$ns .= '\Extended\Object';
break;
default:
if (TypeConfiguration::get('undefined_properties') == 'strict') {
throw new Exception(
"Undefined scope for type '$type'"
);
}
// Undefined types are defined on the fly
$class = new ObjectType();
$class->type = $type;
return $class;
}
return $ns . '\\' . $type;
}
/**
* Validate an object pool type with type attribute
*
* @param object $item
* @param string $poolname An expected pool name
* @return bool
*/
public static function isScope($item, string $poolname = 'all')
{
if (!is_object($item)
|| !isset($item->type)
|| !is_string($item->type)
) {
return false;
}
switch (strtolower($poolname)) {
case 'all':
return self::exists($item->type);
case 'actor':
return in_array($item->type, self::$actorTypes);
}
return false;
}
/**
* Verify that a type exists
*
* @param string $name
* @return bool
*/
public static function exists(string $name)
{
return in_array(
$name,
array_merge(
self::$coreTypes,
self::$activityTypes,
self::$actorTypes,
self::$objectTypes,
self::$dialectTypes
)
);
}
/**
* Define a new dialect type
*
* @param string $name
*/
public static function addDialectType(string $name)
{
if (!self::exists($name)) {
array_push(self::$dialectTypes, $name);
}
}
/**
* Remove a dialect type
*
* @param string $name
*/
public static function removeDialectType(string $name)
{
if (self::exists($name)) {
foreach (self::$dialectTypes as $key => $value) {
if ($name == $value) {
array_splice(self::$dialectTypes, $key, 1);
return;
}
}
}
}
}