Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add hub bookmarks to nodes #56

Merged
merged 6 commits into from
Feb 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions includes/class-accepted-actions.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Accepted_Actions {
'network_user_updated' => 'User_Updated',
'newspack_network_woo_membership_updated' => 'Woocommerce_Membership_Updated',
'network_manual_sync_user' => 'User_Manually_Synced',
'network_nodes_synced' => 'Nodes_Synced',
];

/**
Expand All @@ -54,5 +55,6 @@ class Accepted_Actions {
'network_user_updated',
'newspack_network_woo_membership_updated',
'network_manual_sync_user',
'network_nodes_synced',
];
}
11 changes: 11 additions & 0 deletions includes/class-data-listeners.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public static function register_listeners() {
Data_Events::register_listener( 'woocommerce_subscription_status_changed', 'newspack_node_subscription_changed', [ __CLASS__, 'item_changed' ] );
Data_Events::register_listener( 'woocommerce_order_status_changed', 'newspack_node_order_changed', [ __CLASS__, 'item_changed' ] );
Data_Events::register_listener( 'newspack_network_user_updated', 'network_user_updated', [ __CLASS__, 'user_updated' ] );
Data_Events::register_listener( 'newspack_network_nodes_synced', 'network_nodes_synced', [ __CLASS__, 'nodes_synced' ] );
}

/**
Expand Down Expand Up @@ -85,4 +86,14 @@ public static function item_changed( $item_id, $status_from, $status_to, $item )
public static function user_updated( $user_data ) {
return $user_data;
}

/**
* Filters the nodes data for the event being triggered
*
* @param array $nodes_data The nodes data.
* @return array
*/
public static function nodes_synced( $nodes_data ) {
return [ 'nodes_data' => $nodes_data ];
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran into some issues treating $data as an array in the incoming events class so had to massage this here to work with the nodes data array.

}
}
23 changes: 19 additions & 4 deletions includes/hub/class-node.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
* Class to represent one Node of the netowrk
*/
class Node {
/**
* HUB_NODES_SYNCED_OPTION for network nodes.
*/
const HUB_NODES_SYNCED_OPTION = 'newspack_hub_nodes_synced';

/**
* The WP_Post object for this Node
Expand Down Expand Up @@ -116,13 +120,13 @@ public function get_connect_link() {
}

/**
* Gets a collection of bookmarks for this Node
* Generates a collection of bookmarks for this Node
*
* @param string $url The URL of the Node.
* @return array
*/
public function get_bookmarks() {

$base_url = trailingslashit( $this->get_url() );
public static function generate_bookmarks( $url ) {
$base_url = trailingslashit( $url );

return [
[
Expand Down Expand Up @@ -155,4 +159,15 @@ public function get_bookmarks() {
],
];
}

/**
* Gets a collection of bookmarks for this Node.
*
* @return array
*/
public function get_bookmarks() {
$base_url = $this->get_url();

return self::generate_bookmarks( $base_url );
}
}
70 changes: 68 additions & 2 deletions includes/hub/class-nodes.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
* Class to handle Nodes post type
*/
class Nodes {

/**
* POST_TYPE_SLUG for the Nodes.
*/
Expand All @@ -28,6 +27,11 @@ class Nodes {
public static function init() {
add_action( 'init', [ __CLASS__, 'register_post_type' ] );
add_action( 'save_post', [ __CLASS__, 'save_post' ] );
add_action( 'trashed_post', [ __CLASS__, 'trashed_node' ] );
add_action( 'untrashed_post', [ __CLASS__, 'untrashed_node' ] );
add_action( 'newspack_network_node_saved', [ __CLASS__, 'sync_nodes' ] );
add_action( 'newspack_network_node_trashed', [ __CLASS__, 'sync_nodes' ] );
add_action( 'newspack_network_node_untrashed', [ __CLASS__, 'sync_nodes' ] );
}

/**
Expand Down Expand Up @@ -98,7 +102,6 @@ public static function filter_editor_settings( $settings, $editor_id ) {
* @return void
*/
public static function register_post_type() {

$labels = array(
'name' => _x( 'Nodes', 'Post Type General Name', 'newspack-network' ),
'singular_name' => _x( 'Node', 'Post Type Singular Name', 'newspack-network' ),
Expand Down Expand Up @@ -272,4 +275,67 @@ public static function save_post( $post_id ) {
*/
do_action( 'newspack_network_node_saved', $post_id );
}

/**
* Trashed post callback
*
* @param int $post_id The ID of the post being trashed.
* @return void
*/
public static function trashed_node( $post_id ) {
if ( self::POST_TYPE_SLUG !== get_post_type( $post_id ) ) {
return;
}

/**
* Fires an action when a node is successfully trashed in the Hub admin
*
* @param int $post_id The ID of the node post.
*/
do_action( 'newspack_network_node_trashed', $post_id );
}

/**
* Untrashed post callback
*
* @param int $post_id The ID of the post being untrashed.
* @return void
*/
public static function untrashed_node( $post_id ) {
if ( self::POST_TYPE_SLUG !== get_post_type( $post_id ) ) {
return;
}

/**
* Fires an action when a node is successfully untrashed in the Hub admin
*
* @param int $post_id The ID of the node post.
*/
do_action( 'newspack_network_node_untrashed', $post_id );
}

/**
* Sync nodes data to all nodes in network.
*
* @param int $post_id The ID of the post being saved.
* @return void
*/
public static function sync_nodes( $post_id ) {
$nodes = self::get_all_nodes();

if ( empty( $nodes ) ) {
return;
}

$nodes_data = [];
foreach ( $nodes as $node ) {
$nodes_data[] = [
'id' => $node->get_id(),
'title' => $node->get_name(),
'url' => $node->get_url(),
];
}

do_action( 'newspack_network_nodes_synced', $nodes_data );
}
}
25 changes: 25 additions & 0 deletions includes/hub/stores/event-log-items/class-nodes-synced.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* Newspack Nodes Synced Log Item
*
* @package Newspack
*/

namespace Newspack_Network\Hub\Stores\Event_Log_Items;

use Newspack_Network\Hub\Stores\Abstract_Event_Log_Item;

/**
* Class to handle the Nodes Synced Log Item
*/
class Nodes_Synced extends Abstract_Event_Log_Item {

/**
* Gets a summary for this event
*
* @return string
*/
public function get_summary() {
return __( 'Node data synced', 'newspack-network' );
}
}
58 changes: 58 additions & 0 deletions includes/incoming-events/class-nodes-synced.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Newspack Nodes Synced Incoming Event class
*
* @package Newspack
*/

namespace Newspack_Network\Incoming_Events;

use Newspack_Network\Debugger;
use Newspack_Network\Hub\Node;

/**
* Class to handle the Nodes Synced Event
*
* This event is always sent from the Hub and received by Nodes.
*/
class Nodes_Synced extends Abstract_Incoming_Event {
/**
* Process event in Node
*
* @return void
*/
public function process_in_node() {
Debugger::log( 'Processing network_nodes_synced event.' );
// Get data passed for node urls.
$data = $this->get_data();

// If the data is empty, return early.
if ( empty( $data ) ) {
Debugger::log( 'No data passed for network_nodes_synced event.' );
return;
}

$nodes_data = $data->nodes_data;

// If the nodes data is empty, return early.
if ( empty( $nodes_data ) ) {
Debugger::log( 'No nodes data passed for network_nodes_synced event.' );
return;
}

foreach ( $nodes_data as $key => $node ) {
// We don't need top store data for the current node.
if ( $node['url'] === get_site_url() ) {
unset( $nodes_data[ $key ] );
}
}

$updated = update_option( Node::HUB_NODES_SYNCED_OPTION, $nodes_data );

if ( $updated ) {
Debugger::log( 'network_nodes_synced event processed. Synced ' . count( $nodes_data ) . ' nodes.' );
} else {
Debugger::log( 'Error processing network_nodes_synced event.' );
}
}
}
43 changes: 42 additions & 1 deletion includes/node/class-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

use Newspack_Network\Admin;
use Newspack_Network\Crypto;
use Newspack_Network\Hub\Node as Hub_Node;
use Newspack_Network\Hub\Nodes as Hub_Nodes;
use WP_Error;

/**
Expand Down Expand Up @@ -48,6 +50,7 @@ public static function init() {
add_action( 'admin_menu', [ __CLASS__, 'add_menu' ] );
add_filter( 'allowed_options', [ __CLASS__, 'allowed_options' ] );
add_action( 'admin_init', [ __CLASS__, 'process_connection_form' ] );
add_action( 'admin_bar_menu', [ __CLASS__, 'admin_bar_menu' ], 100 );
}

/**
Expand Down Expand Up @@ -542,7 +545,7 @@ public static function notice_connection_success() {
<div class="misc-pub-section">
<a
class="button"
href="<?php echo esc_url( wp_unslash( self::get_hub_url() ) ); ?>/wp-admin/edit.php?post_type=<?php echo esc_attr( \Newspack_Network\Hub\Nodes::POST_TYPE_SLUG ); ?>"
href="<?php echo esc_url( wp_unslash( self::get_hub_url() ) ); ?>/wp-admin/edit.php?post_type=<?php echo esc_attr( Hub_Nodes::POST_TYPE_SLUG ); ?>"
>
<?php esc_html_e( 'Go back to the Hub', 'newspack-network' ); ?>
</a>
Expand All @@ -564,4 +567,42 @@ public static function notice_connection_error() {
</div>
<?php
}

/**
* Adds the nodes and their bookmarks to the Admin Bar menu
*
* @param \WP_Admin_Bar $wp_admin_bar The WP_Admin_Bar instance.
* @return void
*/
public static function admin_bar_menu( $wp_admin_bar ) {
$nodes_data = get_option( Hub_Node::HUB_NODES_SYNCED_OPTION, [] );
$nodes_data[] = [
'id' => 0,
'url' => self::get_hub_url(),
'title' => __( 'Hub', 'newspack-network' ),
];

foreach ( $nodes_data as $node ) {
$item_id = 'node-' . $node['id'];
$wp_admin_bar->add_node(
[
'id' => $item_id,
'title' => $node['title'],
'href' => $node['url'],
'parent' => 'site-name',
]
);

foreach ( Hub_Node::generate_bookmarks( $node['url'] ) as $bookmark ) {
$wp_admin_bar->add_node(
[
'id' => $item_id . '-' . sanitize_title( $bookmark['label'] ),
'title' => $bookmark['label'],
'href' => $bookmark['url'],
'parent' => $item_id,
]
);
}
}
}
}