<?php
/**
 * Created by PhpStorm.
 * User: maruyama
 * Date: 2022/08/27
 * Time: 16:01
 */

//return wp-setting.php at line141
define('SHORTINIT', true);
//IMPORTANT: Change with the correct path to wp-load.php in your installation
require_once '../../../wp-load.php' ;
require_once '../../../wp-settings.php' ;
require_once ABSPATH . WPINC . '/l10n.php';
//require( ABSPATH . WPINC . '/capabilities.php' );
//require( ABSPATH . WPINC . '/class-wp-user.php' );
//require( ABSPATH . WPINC . '/user.php' );
//require( ABSPATH . WPINC . '/kses.php' );
//require( ABSPATH . WPINC . '/rest-api.php' );


wp_plugin_directory_constants();

$GLOBALS['wp_plugin_paths'] = array();

//wp_cookie_constants();
//require_once ABSPATH . WPINC . '/pluggable.php';
//require_once ABSPATH . WPINC . '/pluggable-deprecated.php';

require_once ABSPATH . WPINC . '/link-template.php';


/**
 * [ ! ] DO NOT include the plugin main file since WP6.1
 */
//require_once 'qahm.php';//=ERROR

//call qahm files
require_once 'qahm-const.php';
require_once 'class-qahm-base.php';
$qahm_base = new QAHM_Base;
$qahm_base->init_wp_filesystem(); //<-Needed!
require_once 'class-qahm-time.php';
require_once 'class-qahm-log.php';
require_once 'class-qahm-file-base.php'; 
require_once 'class-qahm-file-data.php'; 
require_once 'class-qahm-behavioral-data.php'; 
//require_once 'class-qahm-db.php';

// work around for apache_request_headers
if( !function_exists('apache_request_headers') ) {
	function apache_request_headers() {
		$arh = array();
		$rx_http = '/\AHTTP_/';
		foreach ($_SERVER as $key => $val) {
			if ( preg_match( $rx_http, $key ) ) {
			  $arh_key = preg_replace( $rx_http, '', $key );
			  $rx_matches = array();
			  // do some nasty string manipulations to restore the original letter case
			  // this should work in most cases
			  $rx_matches = explode( '_', $arh_key );
			  if ( count($rx_matches) > 0 and strlen($arh_key) > 2 ) {
				foreach ( $rx_matches as $ak_key => $ak_val ) $rx_matches[$ak_key] = ucfirst( $ak_val );
				$arh_key = implode( '-', $rx_matches );
			  }
			  $arh[$arh_key] = $val;
			}
		}
		return( $arh );
	}
}


//qahm start
$behave         = new QAHM_Behavioral_Data;
$base           = new QAHM_Base;
$owndomain      = $_SERVER['SERVER_NAME'];
$allowed_origin = [ $owndomain ];

//QA ZERO start
//sitemanageテーブルより登録されているすべてのドメインを取得し、$allowed_originに追加
$other_domains = get_domains_with_cache();
$allowed_origin = array_merge( $allowed_origin, $other_domains );
//QA ZERO end

$req_headers    = apache_request_headers( );
$req_origin     = '';
if ( array_key_exists( 'Origin', $req_headers ) ) {
	$req_origin = $req_headers['Origin'];
}
if ( array_key_exists( 'ORIGIN', $req_headers ) ) {
	$req_origin = $req_headers['ORIGIN'];
}
if ( array_key_exists( 'origin', $req_headers ) ) {
	$req_origin = $req_headers['origin'];
}
$is_own_domain  = false;
$orgin          = '';
$action         = $base->wrap_filter_input( INPUT_POST, 'action' );

// allowed domain?
if ( $req_origin!== '' ) {
    $is_allowed = false;
    foreach ( $allowed_origin as $domain ) {
        $host = parse_url( $req_origin, PHP_URL_HOST );
        if ( $host === $domain ) {
            $orgin = $req_origin;
            if ($host === $owndomain ) {
                $is_own_domain = true;
            }
            $is_allowed = true;
            break;
        }
    }
    if ( ! $is_allowed ) {
        http_response_code(404);
        exit;
    }
}

//QA ZERO start
$url       = $base->wrap_filter_input( INPUT_POST, 'url' , FILTER_VALIDATE_URL );

if ( !$url ){
    http_response_code(404);
    exit;
}

$parse_url      = parse_url( $url );
$tracking_id    = $base->wrap_filter_input( INPUT_POST, 'tracking_id' );

//IPアドレスのチェック
$ip_address = $_SERVER['REMOTE_ADDR'];

if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    $ip_addresses = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $ip_address = trim($ip_addresses[0]);
}


$sitemanage = get_option( 'qahm_sitemanage' );
$sitemanage = array_filter($sitemanage, function ($item) {
	return isset($item['status']) && $item['status'] !== 255;
});
// インデックス番号を0から順に再構築
$sitemanage = array_values($sitemanage);
if ( ! $sitemanage ) {
    http_response_code(404);
    exit;
}

$site = array_values(array_filter($sitemanage, function($item) use ($tracking_id) {
    return $item['tracking_id'] === $tracking_id;
}));
if ( empty($site) ) {
    http_response_code(404);
    exit;
}

$ignore_ips_str = $site[0]['ignore_ips'];
$ignore_ips = ( empty( $ignore_ips_str ) ) ? array() : explode(',', $ignore_ips_str );

if (in_array($ip_address, $ignore_ips)) {
    http_response_code(404);
    exit;
}

$ignore_params_str = $site[0]['ignore_params'];
$ignore_params = ( empty( $ignore_params_str ) ) ? array() : explode(',', $ignore_params_str );
$c_url          = $behave->url_cleansing( $url, $ignore_params );

$url_case_sensitivity = $site[0]['url_case_sensitivity'];

//URLの大文字小文字を区別するか？
if ( $url_case_sensitivity != 1 ){
    $c_url = mb_strtolower( $c_url );
}
$url_hash       = hash( 'fnv164', $c_url );
//QA ZERO end

//check tracking_hash
$tracking_hash  = $base->wrap_filter_input( INPUT_POST, 'tracking_hash' );
//if ( ! $behave->check_tracking_hash( $tracking_hash ) ) { QA ZERO del
if ( ! $behave->check_tracking_hash( $tracking_hash, $tracking_id ) ) { //QA ZERO add
    http_response_code(404);
    exit;
}

// ok, start behavioral data
$errmsg = '';

if ( !$is_own_domain ){
    return_access_control_header( $orgin );
}

switch ( $action ) {
    case 'init_session_data':

        $qa_id       = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'qa_id' ) ); 
        $title       = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'title' ) );
        $ref         = $base->wrap_filter_input( INPUT_POST, 'referrer' ); 
        $country     = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'country' ) );
        $ua          = $base->serialize_escape( $base->wrap_filter_input( INPUT_SERVER, 'HTTP_USER_AGENT' ) ); 
        $is_new_user = (int)$base->wrap_filter_input( INPUT_POST, 'is_new_user' ); 

        $posted_qa_id = $base->wrap_filter_input( INPUT_POST, 'qa_id' );
        if ( empty( $posted_qa_id ) ){

			$anontrack = false;
			if( isset( $site[0]['anontrack'] ) ){
				$anontrack = $site[0]['anontrack'];
			}
            if( $anontrack == 1 ){
                $qa_id = $base->create_qa_id( $ip_address, $ua, $tracking_hash );
            }else{
                $qa_id = $base->create_qa_id( $ip_address, $ua, '' );
            }
            
        }else{
            $qa_id = $base->serialize_escape( $posted_qa_id );
        }

        if ( empty( $ref ) ) {
            $ref = 'direct';
        }else{
            if ( !filter_var( $ref, FILTER_VALIDATE_URL ) ){
                http_response_code(404);
                exit;
            }
        }
        // $url = mb_strtolower( $url ); QA ZERO del
        $ref = mb_strtolower( $ref );

        //is cookie reject?
        $is_reject = $base->wrap_filter_input( INPUT_POST, 'is_reject' );
        $is_reject = ( $is_reject === 'true' ) ? true : false;

        //init
        $data = $behave->init_session_data( $qa_id, $title, $url, $c_url, $url_hash, $ref, $country, $ua, $tracking_id, $is_new_user, $is_reject, $ip_address ) ;
        
        if( !$data ){ //クローラー判定されたときfalseを返す
            http_response_code(404);
            exit;
        }

        return_json( $data );
        break;

    case 'update_msec':
        //readers_name       = $base->wrap_filter_input( INPUT_POST, 'readers_name' ); QA ZERO del
        $readers_name       = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'readers_name' ) ); //QA ZERO add
        $readers_body_index = (int) $base->wrap_filter_input( INPUT_POST, 'readers_body_index' );
        $speed_msec         = (int) $base->wrap_filter_input( INPUT_POST, 'speed_msec' );
        $behave->update_msec( $readers_name, $readers_body_index, $speed_msec );
        break;

    case 'record_behavioral_data':
        if ( $behave->is_maintenance() ) {
            http_response_code(500);
            exit;
        }
        $is_pos   = $base->wrap_filter_input( INPUT_POST, 'is_pos' );
        $is_pos   = ( $is_pos === 'true' ) ? true : false;
        $is_click = $base->wrap_filter_input( INPUT_POST, 'is_click' );
        $is_click = ( $is_click === 'true' ) ? true : false;
        $is_event = $base->wrap_filter_input( INPUT_POST, 'is_event' );
        $is_event = ( $is_event === 'true' ) ? true : false;
        $is_dLevent = $base->wrap_filter_input( INPUT_POST, 'is_dLevent' );
        $is_dLevent = ( $is_dLevent === 'true' ) ? true : false;

        //QA ZERO start
        $raw_name       = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'raw_name' ) );
        $readers_name   = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'readers_name' ) );
        $ua             = $base->serialize_escape( $base->wrap_filter_input( INPUT_POST, 'ua' ) );
        $is_reject = $base->wrap_filter_input( INPUT_POST, 'is_reject' );
        $is_reject = ( $is_reject === 'true' ) ? true : false;
        //QA ZERO end

        if( ! $ua ) {
            $ua = $_SERVER['HTTP_USER_AGENT'];
        }
        $output = $behave->record_behavioral_data( $is_pos, $is_click, $is_event, $is_dLevent, $raw_name, $readers_name, $ua, $tracking_id, $url_hash, $is_reject ); //QA ZERO add
        echo $output;
        break;

    default:
        http_response_code(404);
        exit;
}


exit;



function return_json ( $data ) {
    header("Content-Type: application/json; charset=utf-8");
    echo json_encode($data);
    exit;
}

function return_access_control_header( $origin = '' ){
    header("Access-Control-Allow-Origin: {$origin}");
}

//APCuを利用してDBアクセス数を減らす
function get_domains_with_cache() {
    global $wpdb;
    $cache_key = $wpdb->prefix . 'qa_domains_cache';
    $cache_expiration = 5 * MINUTE_IN_SECONDS; // キャッシュ有効期間を5分に設定。設定変更時も5分で反映される。

    // APCuが有効かをチェック
    $is_apcu_enabled = function_exists('apcu_fetch');

    // キャッシュをAPCuから取得（APCuが有効な場合のみ）
    $domains = $is_apcu_enabled ? apcu_fetch($cache_key) : false;

    if ($domains === false) {
        // キャッシュがない場合のみクエリを実行
		$sitemanage = get_option( 'qahm_sitemanage' );
		$sitemanage = array_filter($sitemanage, function ($item) {
			return isset($item['status']) && $item['status'] !== 255;
		});
		// インデックス番号を0から順に再構築
		$sitemanage = array_values($sitemanage);
		if ( $sitemanage ) {
	        $domains = array_column($sitemanage, 'domain');
		}

        // 結果をAPCuキャッシュに保存（APCuが有効な場合のみ）
        if ($is_apcu_enabled) {
            apcu_store($cache_key, $domains, $cache_expiration);
        }
    }

    return $domains;
}

