<?php
/**
 * Referrer assigned Segments
 *
 * @link       https://personalizewp.com/
 * @since      3.2.0 Merged into PWP
 * @since      1.0.0
 *
 * @package    PersonalizeWP
 * @subpackage PersonalizeWP/Segments
 */

namespace PersonalizeWP\Segments;

use PersonalizeWP\Segments\Base;
use PersonalizeWP\Model\Activity;

defined( 'ABSPATH' ) || exit; // Exit if accessed directly.

/**
 * Referrer Segments
 *
 * Handles Activities with any type
 */
class Referer extends Base {

	/**
	 * Types of Segment to process
	 *
	 * @var array
	 */
	protected $segment_types = array( 'referer' );

	/**
	 * Add hooks. Overriden from parent to use catchall action.
	 */
	public function setup() {
		add_action( 'personalizewp_activity_record', array( $this, 'process_activity' ), 10, 2 );
	}

	/**
	 * Process any type of Activity for Segments.
	 *
	 * Overridden to have two args, required for catchall action.
	 *
	 * @param string   $type     Activity type
	 * @param Activity $activity Activity object
	 *
	 * @return void
	 */
	public function process_activity( $type, $activity = '' ) {

		if ( empty( $activity ) || empty( $activity->referrer ) ) {
			return;
		}

		if ( ! isset( $this->segments ) ) {
			$this->segments = $this->get_segments();
		}

		if ( empty( $this->segments ) ) {
			return;
		}

		// Simplify the referrer, only interested in the hostname, i.e. www.example.com
		$referrer = strtolower( wp_parse_url( $activity->referrer, PHP_URL_HOST ) );

		foreach ( $this->segments as $segment ) {
			// Sanity check.
			if ( empty( $segment['conditions'] ) ) {
				continue;
			}

			$args = [
				'activity'   => $activity,
				'conditions' => json_decode( $segment['conditions'], true ),
				'operator'   => $segment['operator'],
				'referrer'   => $referrer,
			];
			if ( $this->activity_has_matched_conditions( $args ) ) {
				$this->assign_contact_to_segment( $segment['ID'], $activity->contact_id );
			}
		}
	}

	/**
	 * Test condition against Referrer criteria, matching URL as string/regex.
	 *
	 * @since 2.3.0
	 *
	 * @param array $args {
	 *     Array of args to use for matching the condition.
	 *
	 *     @type Activity $activity   Activity object - Unused
	 *     @type string   $condition  Referrer to match against
	 *     @type string   $options    Type of criteria, regex/url
	 *     @type string   $url        URL Path of Activity
	 * }
	 *
	 * @return boolean
	 */
	protected function condition_has_matched_criteria( $args ) {

		list( 'condition' => $condition, 'options' => $options, 'referrer' => $referrer ) = $args;

		$is_url   = empty( $options ) || 'url' === $options;
		$is_regex = 'regex' === $options;

		// Check for simplier partial match, i.e. condition `example.com` matches against `www.example.com`
		if ( $is_url && str_contains( $referrer, strtolower( $condition ) ) ) {
			return true;
		}
		// With sites having many subdomains or TLD, we need to use regex.
		if ( $is_regex && 1 === preg_match( '/' . $condition . '/i', $referrer ) ) {
			return true;
		}
		return false;
	}
}
