Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * WP Fusion Integration Action Scraper
- *
- * Captures all action outputs from WP Fusion integrations and dumps them
- * for LLM/AI analysis.
- *
- * @package WP Fusion
- * @copyright Copyright (c) 2024, Very Good Plugins, https://verygoodplugins.com
- * @license GPL-3.0+
- * @since x.x.x
- */
- if ( ! defined( 'ABSPATH' ) ) {
- exit; // Exit if accessed directly
- }
- class WPF_Integration_Scraper {
- /**
- * List of integration classes to monitor.
- *
- * @since x.x.x
- * @var array
- */
- private $monitored_integrations = array(
- 'WPF_BuddyPress',
- 'WPF_Woocommerce',
- 'WPF_GForms_Integration',
- 'WPF_LearnDash',
- 'WPF_Contact_Form_7',
- 'WPF_Ninja_Forms',
- 'WPF_WPForms',
- 'WPF_Easy_Digital_Downloads',
- 'WPF_LifterLMS',
- 'WPF_Ultimate_Member',
- 'WPF_Affiliate_WP',
- 'WPF_Wishlist_Member'
- );
- /**
- * Actions to capture from each integration.
- *
- * @since x.x.x
- * @var array
- */
- private $target_actions = array();
- /**
- * Captured data storage.
- *
- * @since x.x.x
- * @var array
- */
- private $captured_data = array();
- /**
- * File path for dumping captured data.
- *
- * @since x.x.x
- * @var string
- */
- private $dump_file;
- /**
- * Initialize the scraper.
- *
- * @since x.x.x
- */
- public function __construct() {
- $this->dump_file = WP_CONTENT_DIR . '/wpf-integration-dump.json';
- $this->init();
- }
- /**
- * Initialize scraper hooks.
- *
- * @since x.x.x
- */
- public function init() {
- // Wait until all plugins are loaded.
- add_action( 'plugins_loaded', array( $this, 'scrape_integration_actions' ), 999 );
- // Hook into WordPress shutdown to dump final data.
- add_action( 'shutdown', array( $this, 'dump_captured_data' ) );
- }
- /**
- * Dynamically scrape all add_action calls from integration classes.
- *
- * @since x.x.x
- */
- public function scrape_integration_actions() {
- foreach ( $this->monitored_integrations as $class_name ) {
- if ( ! class_exists( $class_name ) ) {
- continue;
- }
- // Get reflection of the class.
- $reflection = new ReflectionClass( $class_name );
- // Get the file contents.
- $file_path = $reflection->getFileName();
- if ( ! $file_path || ! file_exists( $file_path ) ) {
- continue;
- }
- $file_contents = file_get_contents( $file_path );
- // Extract all add_action calls.
- $this->extract_actions_from_content( $file_contents, $class_name );
- }
- // Now hook into all discovered actions.
- $this->hook_into_discovered_actions();
- }
- /**
- * Extract add_action calls from file content.
- *
- * @since x.x.x
- *
- * @param string $content File content.
- * @param string $class_name Class name.
- */
- private function extract_actions_from_content( $content, $class_name ) {
- // Regex to match add_action calls.
- $pattern = '/add_action\s*\(\s*[\'"]([^\'"]+)[\'"]\s*,\s*array\s*\(\s*\$this\s*,\s*[\'"]([^\'"]+)[\'"]\s*\)/';
- preg_match_all( $pattern, $content, $matches, PREG_SET_ORDER );
- foreach ( $matches as $match ) {
- $action_name = $match[1];
- $method_name = $match[2];
- if ( ! isset( $this->target_actions[ $class_name ] ) ) {
- $this->target_actions[ $class_name ] = array();
- }
- $this->target_actions[ $class_name ][] = array(
- 'action' => $action_name,
- 'method' => $method_name,
- );
- }
- // Also match add_filter calls.
- $filter_pattern = '/add_filter\s*\(\s*[\'"]([^\'"]+)[\'"]\s*,\s*array\s*\(\s*\$this\s*,\s*[\'"]([^\'"]+)[\'"]\s*\)/';
- preg_match_all( $filter_pattern, $content, $filter_matches, PREG_SET_ORDER );
- foreach ( $filter_matches as $match ) {
- $filter_name = $match[1];
- $method_name = $match[2];
- if ( ! isset( $this->target_actions[ $class_name ] ) ) {
- $this->target_actions[ $class_name ] = array();
- }
- $this->target_actions[ $class_name ][] = array(
- 'action' => $filter_name,
- 'method' => $method_name,
- 'type' => 'filter',
- );
- }
- }
- /**
- * Hook into all discovered actions with our universal capture handler.
- *
- * @since x.x.x
- */
- private function hook_into_discovered_actions() {
- foreach ( $this->target_actions as $class_name => $actions ) {
- foreach ( $actions as $action_data ) {
- $action_name = $action_data['action'];
- $method_name = $action_data['method'];
- $type = isset( $action_data['type'] ) ? $action_data['type'] : 'action';
- // Hook with very high priority to capture everything.
- if ( 'filter' === $type ) {
- add_filter( $action_name, function( $value ) use ( $class_name, $action_name, $method_name ) {
- return $this->universal_capture_handler( $value, $class_name, $action_name, $method_name, func_get_args(), 'filter' );
- }, 9999, 10 );
- } else {
- add_action( $action_name, function() use ( $class_name, $action_name, $method_name ) {
- $this->universal_capture_handler( null, $class_name, $action_name, $method_name, func_get_args(), 'action' );
- }, 9999, 10 );
- }
- }
- }
- }
- /**
- * Universal handler that captures all action/filter data.
- *
- * @since x.x.x
- *
- * @param mixed $value Filter value (null for actions).
- * @param string $class_name Integration class name.
- * @param string $action_name Action/filter name.
- * @param string $method_name Method name.
- * @param array $args All arguments passed to the action/filter.
- * @param string $type 'action' or 'filter'.
- * @return mixed
- */
- private function universal_capture_handler( $value, $class_name, $action_name, $method_name, $args, $type = 'action' ) {
- // Capture the data.
- $capture_entry = array(
- 'timestamp' => current_time( 'mysql' ),
- 'class' => $class_name,
- 'hook' => $action_name,
- 'method' => $method_name,
- 'type' => $type,
- 'args' => $this->sanitize_args_for_json( $args ),
- 'user_id' => get_current_user_id(),
- 'url' => $_SERVER['REQUEST_URI'] ?? '',
- 'post_data' => $this->sanitize_args_for_json( $_POST ),
- 'get_data' => $this->sanitize_args_for_json( $_GET ),
- );
- // Add backtrace for context.
- $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 10 );
- $capture_entry['backtrace'] = array_map( function( $trace ) {
- return array(
- 'file' => isset( $trace['file'] ) ? basename( $trace['file'] ) : 'unknown',
- 'line' => $trace['line'] ?? 0,
- 'function' => $trace['function'] ?? 'unknown',
- 'class' => $trace['class'] ?? '',
- );
- }, $backtrace );
- // Store the captured data.
- $this->captured_data[] = $capture_entry;
- // For filters, return the original value.
- return $value;
- }
- /**
- * Sanitize arguments for JSON encoding.
- *
- * @since x.x.x
- *
- * @param mixed $data Data to sanitize.
- * @return mixed
- */
- private function sanitize_args_for_json( $data ) {
- if ( is_object( $data ) ) {
- // Convert objects to arrays, but capture class name.
- if ( method_exists( $data, 'to_array' ) ) {
- return array(
- '__object_class' => get_class( $data ),
- '__data' => $data->to_array(),
- );
- } else {
- return array(
- '__object_class' => get_class( $data ),
- '__data' => get_object_vars( $data ),
- );
- }
- } elseif ( is_array( $data ) ) {
- return array_map( array( $this, 'sanitize_args_for_json' ), $data );
- } elseif ( is_resource( $data ) ) {
- return '__resource__';
- } else {
- return $data;
- }
- }
- /**
- * Dump all captured data to file for LLM analysis.
- *
- * @since x.x.x
- */
- public function dump_captured_data() {
- if ( empty( $this->captured_data ) ) {
- return;
- }
- // Prepare final dump structure.
- $dump_data = array(
- 'capture_session' => array(
- 'start_time' => current_time( 'mysql' ),
- 'total_captures' => count( $this->captured_data ),
- 'monitored_classes' => $this->monitored_integrations,
- 'discovered_actions' => $this->target_actions,
- ),
- 'captures' => $this->captured_data,
- );
- // Write to file.
- file_put_contents(
- $this->dump_file,
- json_encode( $dump_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ),
- LOCK_EX
- );
- // Also create a summary for quick analysis.
- $this->create_summary_file( $dump_data );
- }
- /**
- * Create a summary file for quick LLM analysis.
- *
- * @since x.x.x
- *
- * @param array $dump_data Full dump data.
- */
- private function create_summary_file( $dump_data ) {
- $summary = array(
- 'session_info' => $dump_data['capture_session'],
- 'hook_frequency' => array(),
- 'class_activity' => array(),
- 'user_interactions' => array(),
- );
- // Analyze the captured data.
- foreach ( $dump_data['captures'] as $capture ) {
- // Hook frequency.
- $hook_key = $capture['hook'];
- if ( ! isset( $summary['hook_frequency'][ $hook_key ] ) ) {
- $summary['hook_frequency'][ $hook_key ] = 0;
- }
- $summary['hook_frequency'][ $hook_key ]++;
- // Class activity.
- $class_key = $capture['class'];
- if ( ! isset( $summary['class_activity'][ $class_key ] ) ) {
- $summary['class_activity'][ $class_key ] = array();
- }
- if ( ! isset( $summary['class_activity'][ $class_key ][ $hook_key ] ) ) {
- $summary['class_activity'][ $class_key ][ $hook_key ] = 0;
- }
- $summary['class_activity'][ $class_key ][ $hook_key ]++;
- // User interactions.
- $user_id = $capture['user_id'];
- if ( ! isset( $summary['user_interactions'][ $user_id ] ) ) {
- $summary['user_interactions'][ $user_id ] = 0;
- }
- $summary['user_interactions'][ $user_id ]++;
- }
- // Sort by frequency.
- arsort( $summary['hook_frequency'] );
- // Write summary.
- file_put_contents(
- str_replace( '.json', '-summary.json', $this->dump_file ),
- json_encode( $summary, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ),
- LOCK_EX
- );
- }
- /**
- * Get captured data (for debugging).
- *
- * @since x.x.x
- *
- * @return array
- */
- public function get_captured_data() {
- return $this->captured_data;
- }
- /**
- * Clear captured data.
- *
- * @since x.x.x
- */
- public function clear_captured_data() {
- $this->captured_data = array();
- }
- /**
- * Enable/disable specific integration monitoring.
- *
- * @since x.x.x
- *
- * @param string $class_name Integration class name.
- * @param bool $enable Enable or disable monitoring.
- */
- public function toggle_integration_monitoring( $class_name, $enable = true ) {
- if ( $enable && ! in_array( $class_name, $this->monitored_integrations ) ) {
- $this->monitored_integrations[] = $class_name;
- } elseif ( ! $enable ) {
- $this->monitored_integrations = array_diff( $this->monitored_integrations, array( $class_name ) );
- }
- }
- }
- // Initialize the scraper.
- new WPF_Integration_Scraper();
Advertisement
Add Comment
Please, Sign In to add comment