diff --git a/connectors/example.php b/connectors/example.php index 296ba47..257ba14 100644 --- a/connectors/example.php +++ b/connectors/example.php @@ -1,38 +1,56 @@ __( 'Post', 'stream-connector-example' ), 'page' => __( 'Page', 'stream-connector-example' ), @@ -42,58 +60,94 @@ public static function get_context_labels() { /** * Return translated action labels * + * "Action" here does not refer to a WordPress action hook. Rather, + * an "action" in the context of this function is a discrete loggable thing + * which gets logged by a connector. There is not a 1:1 relationship between + * connectors and "actions", as a single connector may log different "actions" + * or different connectors may log the same "action" + * * @return array Action label translations */ - public static function get_action_labels() { + public function get_action_labels() { return array( - 'random' => __( 'Random', 'stream-connector-example' ), - 'chosen' => __( 'Chosen', 'stream-connector-example' ), + 'edit_odd' => __( 'Edit Odd-Numbered Post', 'stream-connector-example' ) ); } /** - * Log example entry + * Example connector logging on the save_post hook. + * + * Stream connector callbacks are named after the WO action hook, prefixed with 'callback_`. + * The parameters passed to your callback are the parameters passed to that hook. * - * @action init + * So, for our example here, the parameters for `save_post` are: + * + * @action save_post + * @param int $post_id the ID of the post being saved + * @param WP_Post $post the post object + * @param bool $update whether the post is being udpated. + * @return void + * @link https://developer.wordpress.org/reference/hooks/save_post/ */ - public static function callback_example_after_generate_post_id( $post_id, $post_type ) { - $post_title = get_the_title( $post_id ); - - if ( isset( $_GET['id'] ) && 'random' === $_GET['id'] ) { - $action = 'random'; - } else { - $action = 'chosen'; + public function callback_save_post( $post_id, $post, $update ) { + if ( 0 !== $post_id % 2 ) { + // the post ID is even } + $post_title = get_the_title( $post_id ); - $post_type_obj = get_post_type_object( $post_type ); - $post_type_name = $post_type_obj->labels->singular_name; - - $message = sprintf( __( 'This is an example entry for the "%s" %s.' , 'stream-example-conector' ), $post_title, $post_type_name ); - $context = $post_type; + $post_type_obj = get_post_type_object( $post->post_type ); + $message = sprintf( + __( 'Edited an odd-numbered post: "%1$s" %2$s.' , 'stream-example-conector' ), + $post_title, + $post_id + ); + $context = $post->post_type; + $action = 'edit_odd'; + + /** + * Parameters to self::log are: + * + * @param string $message sprintf-ready error message string. + * @param array $args sprintf (and extra) arguments to use. + * @param int $object_id Target object id. + * @param string $context Context of the event. Could be a WordPress object type like post, page, user. Could be something specific to your plugin. + * @param string $action Action of the event, which needs to match an item in get_action_labels() + * @param int $user_id User responsible for the event — whic we're leaving off + * + * @link https://github.com/xwp/stream/blob/305583d70e8a7667d1f99df85196024a7334ed50/classes/class-connector.php#L146-L158 + */ self::log( $message, array( 'post_title' => $post_title, + 'post_id' => $post_id, ), $post_id, - array( $context => $action ) + $context, + $action + // $user_id - if the log entry should be attributed to a different user ); } /** - * Add action links to Stream Records screen + * Add action links + * + * These appear on individual Stream entries when the mouse hovers over that entry. + * They're analogous to the links that appear on on the psots list table to let you view/edit/trash posts. + * + * This is not mandatory, but if there's an action that an admin would need to do in response to this log entry, this is where you'd put it. * * @filter wp_stream_action_links_{connector} * @param array $links Previous links registered * @param int $record Stream record * @return array Action links */ - public static function action_links( $links, $record ) { + public function action_links( $links, $record ) { if ( get_post( $record->object_id ) ) { if ( $link = get_edit_post_link( $record->object_id ) ) { - $post_title = wp_stream_get_meta( $record->ID, 'post_title', true ); + $post_title = $record->get_meta( 'post_title', true ); $links[ __( 'Edit', 'stream-example-conector' ) ] = $link; } @@ -104,5 +158,4 @@ public static function action_links( $links, $record ) { return $links; } - -} \ No newline at end of file +} diff --git a/example-deactivated.png b/example-deactivated.png new file mode 100644 index 0000000..81394d7 Binary files /dev/null and b/example-deactivated.png differ diff --git a/example.png b/example.png new file mode 100644 index 0000000..a3d7f40 Binary files /dev/null and b/example.png differ diff --git a/readme.md b/readme.md index 70fa107..aabd440 100644 --- a/readme.md +++ b/readme.md @@ -1,23 +1,57 @@ # Stream Connector - Example -This plugin adds a random post generator which logs Stream entries. +This plugin adds a connector which logs when posts with odd-numbered IDs are saved. -**Contributors:** [x-team](http://profiles.wordpress.org/x-team), [lukecarbis](http://profiles.wordpress.org/lukecarbis) +**Contributors:** [Ben Keith](https://profiles.wordpress.org/benlk/), [10up](https://profiles.wordpress.org/10up/), [x-team](http://profiles.wordpress.org/x-team), [lukecarbis](http://profiles.wordpress.org/lukecarbis) **Tags:** [stream](http://wordpress.org/plugins/tags/stream), [connector](http://wordpress.org/plugins/tags/connector) -**Requires at least:** 3.7 -**Tested up to:** 3.9 -**Stable tag:** trunk (master) -**License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html) +**Requires at least:** 4.5 +**Tested up to:** 6.2 +**Stable tag:** trunk (master) +**License:** [GPLv2 or later](http://www.gnu.org/licenses/gpl-2.0.html) -## Description ## +## Demonstration code -To get started, copy connectors/example.php into your own plugin, then copy the register_stream_connector() function from stream-example-connector.php and hook it into your own plugin via the plugins_loaded action. +1. Download this plugin, activate it. +2. Go to your posts screen (Dashboard > Posts) and find a post with an odd-numbered ID. +3. Edit the post and save it. +4. Go to your Stream connectors -The good stuff is in connectors/example.php - once you've copied out the register_stream_connector() function, you can ignore the rest of this file. +## Creating your own connector -To see this connector in action, activate it from your Plugins screen, and choose Stream Example from the admin menu +To get started: -## Changelog ## +1. Copy `connectors/example.php` into your own plugin + 1. Give your connector new values for `$name` and `get_label()`, and rename the connector class. +2. Copy the `register_stream_connector()` function from `stream-example-connector.php` into your own plugin, and hook it in via the `plugins_loaded` action. +3. Stream Connectors connect by being hooked on an action or filter. Identify which hooks you want to use, and add those to the `$actions` array. + - Note: You can use custom hooks. For example, if you want to log a WP_CLI command in Stream, you could define a custom hook: `apply_actions( 'my_example_cli_action', [ 'some', 'important', context' ] );` +4. For each hook, Stream will call a callback method in your Connector class, named `connector_{$hook}`. These callbacks are hooked directly on the specified hook, and take all the parameters that hook receives. +5. Your connector extends the `\WP_Stream\Connector` class, and each callback calls the `self::log()` method with a set of arguments documented in the example. -### 1.0 - April 24, 2014 ### -Initial build. \ No newline at end of file +![Screenshot of the example entry in the Stream log.](./example.png) + +The editable parts of a log entry: + +1. The message, which is generated at the time the log entry is created. Changes to the `log()` method after the entry is logged will not update prior log entries. +2. The user who undertook the action. This can be modified with the sixth parameter of `log()` if necessary, such as if you're logging from a WP_CLI command. +3. The connector's name, which is a string returned by your `get_label()` method. +4. The connector's context label. A context is a string passed as the fourth parameter to the `log()` method, which must match an index in the array returned by your `get_context_labels()` method. The can be something simple like a post slug, or whatever you want. +5. The connector's action label. A connector action is a string passed as the _fifth_ parameter to the `log()` method, and does not need to match the action or hook that your connector callback is hooked on. The action string mush match an index in the array returned by your `get_action_labels()` method. This should be short but explain what action is being logged, and why that action is significant. +6. The IP address that is responsible for the event, from the point of view of the server. Proxies, WP-CLI, and other factors may make this number not accurately reflect the responsible actor's IP address. +## What if my connector gets deactivated? + +![Screenshot of the example entry in the Stream log.](./example.png) + +Some of the information disappears: + +- the connector label +- the action label + +That's it. + +## Changelog + +- 1.0.0: Revised by [Ben Keith](https://profiles.wordpress.org/benlk/) of [10up](https://profiles.wordpress.org/10up/) to support Stream version 3 + - replaced post generation example with a simpler example that logs when odd-numbered posts are edited + - improved documentation: now with screenshots, more inline comments, and an expanded readme.md +- 0.1.0: Initial Version by [x-team](http://profiles.wordpress.org/x-team) and [lukecarbis](http://profiles.wordpress.org/lukecarbis) diff --git a/readme.txt b/readme.txt index 7aa8e10..babc784 100644 --- a/readme.txt +++ b/readme.txt @@ -1,26 +1,26 @@ === Stream Connector Example === -Contributors: X-team, lukecarbis +Contributors: benlk, 10up, X-team, lukecarbis Tags: example, connector, stream -Requires at least: 3.7 -Tested up to: 3.9 +Requires at least: 4.5 +Tested up to: 6.2 Stable tag: trunk License: GPLv2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html -This plugin adds a random post generator which logs Stream entries. +This plugin adds example code that logs when odd-numbered posts are edited. == Description == -How to use this plugin - This plugin has been made to be copied and changed to suit your own needs. -To get started, copy connectors/example.php into your own plugin, then copy the register_stream_connector() function from stream-example-connector.php and hook it into your own plugin via the plugins_loaded action. +To get started, copy `connectors/example.php` into your own plugin, then copy the `register_stream_connector()` function from stream-example-connector.php and hook it into your own plugin via the plugins_loaded action. + +The good stuff is in `connectors/example.php` - once you've copied out the `register_stream_connector()` function, you can ignore the rest of this file. -The good stuff is in connectors/example.php - once you've copied out the register_stream_connector() function, you can ignore the rest of this file. +To see this connector in action, activate it from your Plugins screen, then edit and save an odd-numbered post. -To see this connector in action, activate it from your Plugins screen, and choose Stream Example from the admin menu +For more information, see `readme.md` in the root of this plugin. == Changelog == = 0.1.0 = -Initial concept built. \ No newline at end of file +Initial concept built. diff --git a/stream-connector-example.php b/stream-connector-example.php index cb4f435..7beb6ef 100644 --- a/stream-connector-example.php +++ b/stream-connector-example.php @@ -2,10 +2,10 @@ /** * Plugin Name: Stream Connector - Example * Depends: Stream - * Plugin URI: http://x-team.com - * Description: This plugin adds a random post generator which logs entries in your Stream. - * Version: 0.1.0 - * Author: X-Team + * Plugin URI: https://10up.com + * Description: This plugin provides example code that will enable you to buid a custom connector for XWP's Stream plugin. + * Version: 1.0.0 + * Author: Ben Keith, 10up * Author URI: http://wp-stream.com/ * License: GPLv2+ * Text Domain: stream-connector-example @@ -23,8 +23,8 @@ * The good stuff is in connectors/example.php - once you've copied out the * register_stream_connector() function, you can ignore the rest of this file. * - * To see this connector in action, activate it from your Plugins screen, and - * choose Stream Example from the admin menu + * To see this connector in action, activate it from your Plugins screen, + * and then edit an odd-numbered post. */ class Stream_Example_Plugin { @@ -34,16 +34,19 @@ class Stream_Example_Plugin { */ public function __construct() { add_action( 'plugins_loaded', array( $this, 'register_stream_connector' ) ); - add_action( 'admin_menu', array( $this, 'register_menu' ) ); } /** * If Stream is active, register the Stream Connector * + * Note the namespacing on the class `\WP_Stream\Connector`. + * If your connector isn't activating, check whether you have the latest version + * of Stream installed, whether it's active, and whether that class exists in it. + * * @action plugins_loaded */ public function register_stream_connector() { - if ( ! class_exists( 'WP_Stream' ) ) { + if ( ! class_exists( '\WP_Stream\Connector' ) ) { return; } @@ -51,96 +54,12 @@ public function register_stream_connector() { 'wp_stream_connectors', function( $classes ) { include dirname( __FILE__ ) . '/connectors/example.php'; - $classes[] = 'WP_Stream_Connector_Example'; + $classes[] = new WP_Stream_Connector_Example(); return $classes; } ); } - /** - * Register menu item - * - * @action admin_menu - */ - public function register_menu() { - add_menu_page( - __( 'Random Post Generator', 'stream-connector-example' ), - __( 'Stream Example', 'stream-connector-example' ), - WP_Stream_Admin::VIEW_CAP, - 'example', - array( $this, 'page' ), - '', - 3 - ); - } - - /** - * Render Random Number Generator Page - */ - public function page() { - ?> -
-

- 1, - 'post_type' => $type, - 'orderby' => 'rand' - ) - ); - $post_id = $post_rand[0]->ID; - } else { - $post_id = (int) filter_input( INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT ); - } - - $post_id = apply_filters( 'example_post_id', $post_id, $type ); - do_action( 'example_after_generate_post_id', $post_id, $type ); - - echo '

' . sprintf( __( 'The %s is', 'stream-connector-example' ), $type ) . ' ' . get_the_title( $post_id ) . '

'; - } - - $post_choices = get_posts( - array( - 'posts_per_page' => 3, - 'post_type' => 'post', - 'orderby' => 'rand' - ) - ); - $page_choices = get_posts( - array( - 'posts_per_page' => 3, - 'post_type' => 'page', - 'orderby' => 'rand' - ) - ); - ?> -
-

-

- - - ID ); ?> - -
-
-
-

-

- - - ID ); ?> - -
-
-
-