Skip to content
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
1 change: 1 addition & 0 deletions echodash.php
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ private function integrations_includes() {
'learndash' => 'SFWD_LMS',
'lifterlms' => 'LLMS',
'pretty-links' => 'PrliLink',
'searchwp' => 'SearchWP',
'woocommerce' => 'WooCommerce',
'woo-subscriptions' => 'WC_Subscriptions_Product',
);
Comment on lines +278 to 281

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix SearchWP dependency detection to ensure the integration loads

class_exists( 'SearchWP' ) is unlikely to be true in modern SearchWP (v4+ uses namespaced classes). Use the Query class to detect presence.

Apply this diff:

-			'searchwp'                => 'SearchWP',
+			// Detect SearchWP v4+ via its namespaced Query class.
+			'searchwp'                => '\SearchWP\Query',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'searchwp' => 'SearchWP',
'woocommerce' => 'WooCommerce',
'woo-subscriptions' => 'WC_Subscriptions_Product',
);
// Detect SearchWP v4+ via its namespaced Query class.
'searchwp' => '\SearchWP\Query',
'woocommerce' => 'WooCommerce',
'woo-subscriptions' => 'WC_Subscriptions_Product',
);
🤖 Prompt for AI Agents
In echodash.php around lines 278 to 281, the current detection for the SearchWP
dependency using class_exists('SearchWP') is outdated because SearchWP v4+ uses
namespaced classes. Update the detection logic to check for the presence of the
SearchWP\Query class instead, ensuring the integration loads correctly with
modern versions.

Expand Down
190 changes: 190 additions & 0 deletions includes/integrations/searchwp/class-echodash-searchwp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
<?php
/**
* SearchWP integration for EchoDash.
*
* Provides comprehensive tracking for SearchWP events including:
* - Search queries with results
* - Zero-result searches
*
* @package EchoDash
*/

defined( 'ABSPATH' ) || exit;

/**
* SearchWP integration.
*
* @since 2.0.0
*/
class EchoDash_SearchWP extends EchoDash_Integration {

/**
* The slug for EchoDash's module tracking.
*
* @since 2.0.0
* @var string $slug
*/
public $slug = 'searchwp';

/**
* The plugin name for EchoDash's module tracking.
*
* @since 2.0.0
* @var string $name
*/
public $name = 'SearchWP';

/**
* The icon background color for the integration.
*
* @since 2.0.0
* @var string $icon_background_color
*/
protected $icon_background_color = '#fafbfb';

/**
* Get things started.
*
* @since 2.0.0
*/
public function init() {
add_action( 'searchwp\query\ran', array( $this, 'search_query_performed' ), 10, 1 );
}

/**
* Gets the triggers for the integration.
*
* @access protected
*
* @since 2.0.0
*
* @return array The triggers.
*/
protected function setup_triggers() {
$triggers = array(
'search_performed' => array(
'name' => __( 'Search Performed', 'echodash' ),
'description' => __( 'Triggered when a user performs a search using SearchWP.', 'echodash' ),
'has_global' => true,
'option_types' => array( 'search' ),
'enabled_by_default' => false,
'default_event' => array(
'name' => __( 'Search Query', 'echodash' ),
'mappings' => array(
'search_terms' => '{search:search_terms}',
'results_count' => '{search:results_count}',
'engine_name' => '{search:engine_name}',
),
),
),
'search_no_results' => array(
'name' => __( 'Search No Results', 'echodash' ),
'description' => __( 'Triggered when a user performs a search that returns zero results.', 'echodash' ),
'has_global' => true,
'option_types' => array( 'search' ),
'enabled_by_default' => true,
'default_event' => array(
'name' => __( 'Search No Results', 'echodash' ),
'mappings' => array(
'search_terms' => '{search:search_terms}',
'engine_name' => '{search:engine_name}',
),
),
),
);

return $triggers;
}

/**
* Gets the search options.
*
* @since 2.0.0
*
* @return array The search options.
*/
public function get_search_options() {
return array(
'name' => __( 'SearchWP Query', 'echodash' ),
'type' => 'search',
'options' => array(
array(
'meta' => 'search_terms',
'preview' => __( 'wordpress tutorial', 'echodash' ),
'placeholder' => __( 'The search terms entered by the user', 'echodash' ),
),
array(
'meta' => 'results_count',
'preview' => '42',
'placeholder' => __( 'The number of results found', 'echodash' ),
),
array(
'meta' => 'query_time',
'preview' => '0.125',
'placeholder' => __( 'Search execution time in seconds', 'echodash' ),
),
array(
'meta' => 'engine_name',
'preview' => __( 'default', 'echodash' ),
'placeholder' => __( 'The SearchWP engine used', 'echodash' ),
),
array(
'meta' => 'timestamp',
'preview' => gmdate( 'Y-m-d H:i:s' ),
'placeholder' => __( 'When the search was performed', 'echodash' ),
),
),
);
}

/**
* Handle search query performed event.
*
* @since 2.0.0
*
* @param object $query The SearchWP Query object.
*/
public function search_query_performed( $query ) {
if ( empty( $query ) || ! method_exists( $query, 'get_keywords' ) ) {
return;
}

Comment on lines +148 to +151

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Strengthen guard: use object check instead of empty()

empty( $query ) is ineffective for objects. Use is_object() to avoid edge cases.

-		if ( empty( $query ) || ! method_exists( $query, 'get_keywords' ) ) {
+		if ( ! is_object( $query ) || ! method_exists( $query, 'get_keywords' ) ) {
 			return;
 		}
🤖 Prompt for AI Agents
In includes/integrations/searchwp/class-echodash-searchwp.php around lines 148
to 151, replace the empty($query) check with is_object($query) to properly
verify that $query is an object before calling method_exists. This strengthens
the guard by ensuring $query is an object and prevents edge cases where empty()
does not behave as expected with objects.

// Get search data.
$search_terms = $query->get_keywords();
$results_count = isset( $query->found_results ) ? (int) $query->found_results : 0;
$query_time = isset( $query->query_time ) ? (float) $query->query_time : 0;
$engine_name = method_exists( $query, 'get_engine' ) && method_exists( $query->get_engine(), 'get_name' ) ? $query->get_engine()->get_name() : 'default';
Comment on lines +152 to +156

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Make result and engine extraction more robust

  • Prefer get_results() when available to compute results_count.
  • Avoid calling method_exists() on the result of a method call; fetch engine once and check it.
-		$search_terms  = $query->get_keywords();
-		$results_count = isset( $query->found_results ) ? (int) $query->found_results : 0;
-		$query_time    = isset( $query->query_time ) ? (float) $query->query_time : 0;
-		$engine_name   = method_exists( $query, 'get_engine' ) && method_exists( $query->get_engine(), 'get_name' ) ? $query->get_engine()->get_name() : 'default';
+		$search_terms  = $query->get_keywords();
+
+		// Derive results count.
+		$results_count = 0;
+		if ( method_exists( $query, 'get_results' ) ) {
+			$results = $query->get_results();
+			$results_count = is_array( $results ) ? count( $results ) : (int) $results;
+		} elseif ( isset( $query->found_results ) ) {
+			$results_count = (int) $query->found_results;
+		}
+
+		$query_time  = isset( $query->query_time ) ? (float) $query->query_time : 0;
+
+		// Resolve engine safely.
+		$engine_name = 'default';
+		if ( method_exists( $query, 'get_engine' ) ) {
+			$engine = $query->get_engine();
+			if ( is_object( $engine ) && method_exists( $engine, 'get_name' ) ) {
+				$engine_name = $engine->get_name();
+			}
+		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Get search data.
$search_terms = $query->get_keywords();
$results_count = isset( $query->found_results ) ? (int) $query->found_results : 0;
$query_time = isset( $query->query_time ) ? (float) $query->query_time : 0;
$engine_name = method_exists( $query, 'get_engine' ) && method_exists( $query->get_engine(), 'get_name' ) ? $query->get_engine()->get_name() : 'default';
// Get search data.
$search_terms = $query->get_keywords();
// Derive results count.
$results_count = 0;
if ( method_exists( $query, 'get_results' ) ) {
$results = $query->get_results();
$results_count = is_array( $results ) ? count( $results ) : (int) $results;
} elseif ( isset( $query->found_results ) ) {
$results_count = (int) $query->found_results;
}
$query_time = isset( $query->query_time ) ? (float) $query->query_time : 0;
// Resolve engine safely.
$engine_name = 'default';
if ( method_exists( $query, 'get_engine' ) ) {
$engine = $query->get_engine();
if ( is_object( $engine ) && method_exists( $engine, 'get_name' ) ) {
$engine_name = $engine->get_name();
}
}
🤖 Prompt for AI Agents
In includes/integrations/searchwp/class-echodash-searchwp.php around lines 152
to 156, improve robustness by first checking if the query object has a
get_results() method and using it to determine results_count instead of directly
accessing found_results. Also, assign the result of get_engine() to a variable
before checking if it exists and has a get_name() method, then use that variable
to get the engine name or default to 'default'. This avoids calling
method_exists() on the result of a method call.


// Create search data array.
$search_data = array(
'search_terms' => $search_terms,
'results_count' => $results_count,
'query_time' => $query_time,
'engine_name' => $engine_name,
'timestamp' => current_time( 'mysql' ),
);

// Determine which trigger to fire.
if ( $results_count > 0 ) {
// Track successful search.
$this->track_event(
'search_performed',
array(),
array(
'search' => $search_data,
)
);
} else {
// Track zero results search.
$this->track_event(
'search_no_results',
array(),
array(
'search' => $search_data,
)
);
}
}
}

new EchoDash_SearchWP();
Binary file added includes/integrations/searchwp/searchwp-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.