-
Notifications
You must be signed in to change notification settings - Fork 116
Creating a Custom Connector
Connectors are the mechanism by which Stream logs activity that's happening in WordPress.
Connectors are really just a simple way to encapsulate the instructions Stream needs to monitor actions taken by specific WordPress components, like Posts, as well as actions by specific plugins, like Jetpack.
A Connector is comprised of six primary components:
- Connector name/slug
- Connector label
- Action callbacks
- Action labels
- Context labels
- Callback functions
A Connector should be thought of as a top-level Context, and Contexts listed within our Connector as second-level Contexts.
These second-level Contexts help to further categorize actions that are happening within the Connector we are tracking.
For example, if there is a custom post type called "Books" and there is a book post called "Moby Dick" that is updated, the Stream record data would look like this:
Summary: "Moby Dick" book updated
Contexts: Posts > Books
Action: Updated
Every Connector registered in Stream must be a child class that inherits from the main WP_Stream\Connector
abstract class where the required arguments for Connector methods are defined.
namespace My_Plugin;
class Connector extends \WP_Stream\Connector {
/**
* Connector slug
*
* @var string
*/
public $name = 'my_plugin';
/**
* Actions registered for this connector
*
* These are actions that My Plugin has created, we are defining them here to
* tell Stream to run a callback each time this action is fired so we can
* log information about what happened.
*
* @var array
*/
public $actions = array(
'my_plugin_update_foo',
'my_plugin_update_bar',
);
/**
* The minimum version required for My Plugin
*
* @const string
*/
const PLUGIN_MIN_VERSION = '1.0.0';
/**
* Display an admin notice if plugin dependencies are not satisfied
*
* If My Plugin does not have the minimum required version number specified
* in the constant above, then Stream will display an admin notice for us.
*
* @return bool
*/
public function is_dependency_satisfied() {
$version_compare = version_compare( My_Plugin_Class::$version, self::PLUGIN_MIN_VERSION, '>=' );
if ( class_exists( 'My_Plugin_Class' ) && $version_compare ) {
return true;
}
return false;
}
/**
* Return translated connector label
*
* @return string
*/
public function get_label() {
return __( 'My Plugin', 'my-plugin-text-domain' );
}
/**
* Return translated context labels
*
* @return array
*/
public function get_context_labels() {
return array(
'foo' => __( 'Foo', 'my-plugin-text-domain' ),
'bar' => __( 'Bar', 'my-plugin-text-domain' ),
);
}
/**
* Return translated action labels
*
* @return array
*/
public function get_action_labels() {
return array(
'created' => __( 'Created', 'my-plugin-text-domain' ),
'updated' => __( 'Updated', 'my-plugin-text-domain' ),
);
}
/**
* Add action links to Stream drop row in admin list screen
*
* This method is optional.
*
* @param array $links Previous links registered
* @param Record $record Stream record
*
* @return array Action links
*/
public function action_links( $links, $record ) {
// Check if the Foo or Bar exists
if ( $record->object_id && get_post_status( $record->object_id ) ) {
$post_type_name = $this->get_post_type_name( get_post_type( $record->object_id ) );
$action_link_text = sprintf(
esc_html_x( 'Edit %s', 'Post type singular name', 'stream' ),
$post_type_name
);
$links[ $action_link_text ] = get_edit_post_link( $record->object_id );
}
return $links;
}
/**
* Track create and update actions on Foos
*
* @param array $foo
* @param bool $is_new
*
* @return void
*/
public function callback_my_plugin_update_foo( $foo, $is_new ) {
$action = __( 'updated', 'my-plugin-text-domain' );
if ( $is_new ) {
$action = __( 'created', 'my-plugin-text-domain' );
}
$this->log(
// Summary message
sprintf(
__( '"%1$s" foo %2$s', 'my-plugin-text-domain' ),
$foo['title'],
$action
),
// This array is compacted and saved as Stream meta
array(
'action' => $action,
'id' => $foo['id'],
'title' => $foo['title'],
),
$foo['id'], // Object ID
'foo', // Context
$action
);
}
/**
* Track create and update actions on Bars
*
* @param array $bar
* @param bool $is_new
*
* @return void
*/
public function callback_my_plugin_update_bar( $bar, $is_new ) {
$action = __( 'updated', 'my-plugin-text-domain' );
if ( $is_new ) {
$action = __( 'created', 'my-plugin-text-domain' );
}
$this->log(
// Summary message
sprintf(
__( '"%1$s" bar %2$s', 'my-plugin-text-domain' ),
$bar['title'],
$action
),
// This array is compacted and saved as Stream meta
array(
'action' => $action,
'id' => $bar['id'],
'title' => $bar['title'],
),
$bar['id'], // Object ID
'bar', // Context
$action // Action
);
}
}
Now we need to tell Stream to include our new child class every time it loads the rest of Connectors in Stream.
This will also make your custom Contexts and Actions appear in the Stream Records filter dropdown menus.
To register a Connector, hook into the wp_stream_connectors
filter from inside your plugin.
/**
* Register the My Plugin connector for Stream
*
* @filter wp_stream_connectors
*
* @param array $classes Array of connector class names
*
* @return array
*/
function my_plugin_register_stream_connector( $classes ) {
require plugin_dir_path( __FILE__ ) . '/class-wp-stream-connector-my-plugin.php';
$class_name = '\My_Plugin\Connector';
if ( ! class_exists( $class_name ) ) {
return;
}
$stream = wp_stream_get_instance();
$class = new $class_name();
if ( ! method_exists( $class, 'is_dependency_satisfied' ) ) {
return;
}
if ( $class->is_dependency_satisfied() ) {
$classes[] = $class;
}
return $classes;
}
add_filter( 'wp_stream_connectors', 'my_plugin_register_stream_connector' );