wordpress-activitypub/includes/transformer/class-factory.php
2023-12-22 19:07:44 +01:00

306 lines
8.4 KiB
PHP

<?php
namespace Activitypub\Transformer;
use Activitypub\Transformer\Post;
use Activitypub\Transformer\Comment;
use Activitypub\Transformer\Attachment;
/**
* Transformer Factory
*/
class Factory {
const DEFAULT_TRANSFORMER_MAPPING = array(
'WP_Post' => array(
'post' => 'activitypub/post',
'page' => 'activitypub/post',
'attachment' => 'activitypub/attachment',
),
'WP_Comment' => 'activitypub/comment'
);
/**
* Transformers.
*
* Holds the list of all the ActivityPub transformers. Default is `null`.
*
* @since version_number_transformer_management_placeholder
* @access private
*
* @var \ActivityPub\Transformer\Base[]
*/
private $transformers = null;
/**
* F instance.
*
* Holds the transformer instance.
*
* @since version_number_transformer_management_placeholder
* @access protected
*/
protected static $_instances = [];
/**
* Instance.
*
* Ensures only one instance of the transformer manager class is loaded or can be loaded.
*
* @since version_number_transformer_management_placeholder
* @access public
* @static
*
* @return Transformer_Manager An instance of the class.
*/
public static function instance() {
$class_name = static::class_name();
if ( empty( static::$_instances[ $class_name ] ) ) {
static::$_instances[ $class_name ] = new static();
}
return static::$_instances[ $class_name ];
}
/**
* Class name.
*
* Retrieve the name of the class.
*
* @since version_number_transformer_management_placeholder
* @access public
* @static
*/
public static function class_name() {
return get_called_class();
}
/**
* Checks if a transformer is registered.
*
* @since version_number_transformer_management_placeholder
*
* @param string $name Transformer name including namespace.
* @return bool True if the block type is registered, false otherwise.
*/
public function is_registered( $name ) {
return isset( $this->transformers[ $name ] );
}
/**
* Register a transformer.
*
* @since version_number_transformer_management_placeholder
* @access public
*
* @param \ActivityPub\Transformer\Base $transformer_instance ActivityPub Transformer.
*
* @return bool True if the ActivityPub transformer was registered.
*/
public function register( \ActivityPub\Transformer\Base $transformer_instance ) {
if ( ! $transformer_instance instanceof \ActivityPub\Transformer\Base ) {
_doing_it_wrong(
__METHOD__,
\esc_html__( 'ActivityPub transformer instance must be a of \ActivityPub\Transformer_Base class.' ),
'version_number_transformer_management_placeholder'
);
return false;
}
$transformer_name = $transformer_instance->get_name();
if ( preg_match( '/[A-Z]+/', $transformer_name ) ) {
_doing_it_wrong(
__METHOD__,
\esc_html__( 'ActivityPub transformer names must not contain uppercase characters.' ),
'version_number_transformer_management_placeholder'
);
return false;
}
$name_matcher = '/^[a-z0-9-]+\/[a-z0-9-]+$/';
if ( ! preg_match( $name_matcher, $transformer_name ) ) {
_doing_it_wrong(
__METHOD__,
\esc_html__( 'ActivityPub transformer names must contain a namespace prefix. Example: my-plugin/my-custom-transformer' ),
'version_number_transformer_management_placeholder'
);
return false;
}
if ( $this->is_registered( $transformer_name ) ) {
_doing_it_wrong(
__METHOD__,
/* translators: %s: Block name. */
sprintf( 'ActivityPub transformer with name "%s" is already registered.', esc_html( $transformer_name ) ),
'version_number_transformer_management_placeholder'
);
return false;
}
/**
* Should the ActivityPub transformer be registered.
*
* @since version_number_transformer_management_placeholder
*
* @param bool $should_register Should the ActivityPub transformer be registered. Default is `true`.
* @param \ActivityPub\Transformer\Base $transformer_instance Widget instance.
*/
$should_register = apply_filters( 'activitypub_transformer_is_enabled', true, $transformer_instance );
if ( ! $should_register ) {
return false;
}
$this->transformers[ $transformer_name ] = $transformer_instance;
return true;
}
/**
* Init transformers.
*
* Initialize ActivityPub transformer manager.
* Include the builtin transformers by default and add third party ones.
*
* @since version_number_transformer_management_placeholder
* @access private
*/
private function init_transformers() {
$builtin_transformers = [
'post',
'attachment'
];
$this->transformers = [];
foreach ( $builtin_transformers as $transformer_name ) {
$class_name = ucfirst( $transformer_name );
$class_name = '\Activitypub\Transformer\\' . $class_name;
$this->register( new $class_name() );
}
/**
* Let other transformers register.
*
* Fires after the built-in Activitypub transformers are registered.
*
* @since version_number_transformer_management_placeholder
*
* @param Transformer_Factory $this The widgets manager.
*/
do_action( 'activitypub_transformers_register', $this );
}
/**
* Get available ActivityPub transformers.
*
* Retrieve the registered transformers list. If given a transformer name
* it returns the given transformer if it is registered.
*
* @since version_number_transformer_management_placeholder
* @access public
*
* @param string $transformer_name Optional. Transformer name. Default is null.
*
* @return Base|Base[]|null Registered transformers.
*/
public function get_transformer_class( $transformer_name = null ) {
if ( is_null( $this->transformers ) ) {
$this->init_transformers();
}
if ( null !== $transformer_name ) {
return isset( $this->transformers[ $transformer_name ] ) ? $this->transformers[ $transformer_name ] : null;
}
return $this->transformers;
}
public static function get_default_transformer( $object ) {
/**
* Filter the transformer for a given object.
*
* Add your own transformer based on the object class or the object type.
*
* Example usage:
*
* // Filter be object class
* add_filter( 'activitypub_transformer', function( $transformer, $object, $object_class ) {
* if ( $object_class === 'WP_Post' ) {
* return new My_Post_Transformer( $object );
* }
* return $transformer;
* }, 10, 3 );
*
* // Filter be object type
* add_filter( 'activitypub_transformer', function( $transformer, $object, $object_class ) {
* if ( $object->post_type === 'event' ) {
* return new My_Event_Transformer( $object );
* }
* return $transformer;
* }, 10, 3 );
*
* @param Activitypub\Transformer\Base $transformer The transformer to use.
* @param mixed $object The object to transform.
* @param string $object_class The class of the object to transform.
*
* @return mixed The transformer to use.
*/
$transformer = apply_filters( 'activitypub_transformer', null, $object, get_class( $object ) );
if ( $transformer ) {
return $transformer;
}
// Use the built-in transformers.
switch ( get_class( $object ) ) {
case 'WP_Post':
if ( 'attachment' === $object->post_type ) {
return new Attachment( $object );
}
return new Post( $object );
case 'WP_Comment':
return new Comment( $object );
default:
return null;
}
}
/**
* Get the mapped ActivityPub transformer.
*
* Returns a new instance of the needed WordPress to ActivityPub transformer.
*
* @since version_number_transformer_management_placeholder
* @access public
*
* @param WP_Post|WP_Comment $object The WordPress Post/Comment.
*
* @return \ActivityPub\Transformer\Base|null Registered transformers.
*/
public function get_transformer( $object ) {
switch ( get_class( $object ) ) {
case 'WP_Post':
$post_type = get_post_type( $object );
$transformer_mapping = \get_option( 'activitypub_transformer_mapping', self::DEFAULT_TRANSFORMER_MAPPING );
$transformer_name = $transformer_mapping[ 'WP_Post' ][ $post_type ];
if ( $transformer_name ) {
$transformer_class = $this->get_transformer_class( $transformer_name );
} else {
return self::get_default_transformer( $object );
}
if ( $transformer_class ) {
return new $transformer_class( $object );
} else {
return self::get_default_transformer( $object );
}
case 'WP_Comment':
return new Comment( $object );
default:
self::get_default_transformer( $object );
}
}
}