breznflow/includes/Features/RelatedWorkflows.php
Michael fd83e4810b BreznFlow 1.0.0 — WordPress.org submission
Initial public release of BreznFlow, an n8n workflow renderer for WordPress.
Fully PHPCS-compliant (WordPress Coding Standards), security-hardened,
and ready for WordPress.org plugin review.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 11:27:36 +00:00

106 lines
2.6 KiB
PHP

<?php
/**
* Finds related workflows by shared node types.
*
* @package BreznFlow
* @since 1.0.0
*/
namespace BreznFlow\Features;
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Finds and displays workflows related by shared node types.
*
* @since 1.0.0
*/
class RelatedWorkflows {
/**
* Registers related workflows hooks.
*
* @since 1.0.0
* @return void
*/
public function register(): void {
// Can be extended to add hooks for related workflow display.
}
/**
* Gets related workflows by shared node types.
* Results are cached in a transient for 1 hour.
*
* @param int $post_id Workflow post ID.
* @param int $limit Max number of related workflows to return.
* @return array Array of WP_Post objects.
*/
public static function get( int $post_id, int $limit = 5 ): array {
$settings = get_option( 'breznflow_settings', array() );
if ( isset( $settings['related_workflows'] ) && ! $settings['related_workflows'] ) {
return array();
}
$cache_key = 'breznflow_related_' . $post_id;
$cached = get_transient( $cache_key );
if ( false !== $cached ) {
return $cached;
}
$summary = get_post_meta( $post_id, '_breznflow_node_summary', true );
if ( ! $summary ) {
return array();
}
$node_types = array_keys( (array) json_decode( $summary, true ) );
if ( empty( $node_types ) ) {
return array();
}
// Search other workflows with overlapping node types.
$related = get_posts(
array(
'post_type' => 'breznflow_workflow',
'post_status' => 'publish',
'posts_per_page' => $limit,
'post__not_in' => array( $post_id ), // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
array(
'key' => '_breznflow_node_summary',
'compare' => 'EXISTS',
),
),
)
);
// Filter by shared node types.
$scored = array();
foreach ( $related as $post ) {
$other_summary = get_post_meta( $post->ID, '_breznflow_node_summary', true );
if ( ! $other_summary ) {
continue;
}
$other_types = array_keys( (array) json_decode( $other_summary, true ) );
$shared = count( array_intersect( $node_types, $other_types ) );
if ( $shared > 0 ) {
$scored[] = array(
'post' => $post,
'shared' => $shared,
);
}
}
usort(
$scored,
static function ( $a, $b ) {
return $b['shared'] - $a['shared'];
}
);
$result = array_column( array_slice( $scored, 0, $limit ), 'post' );
set_transient( $cache_key, $result, HOUR_IN_SECONDS );
return $result;
}
}