| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- <?php
- /*******************************************************************************
- * Copyright (c) 2019, Code Atlantic LLC
- ******************************************************************************/
- if ( ! defined( 'ABSPATH' ) ) {
- exit;
- }
- /**
- * Controls the basic analytics methods for Popup Maker
- */
- class PUM_Analytics {
- /**
- * Initializes analytics endpoints and data
- */
- public static function init() {
- if ( ! self::analytics_enabled() ) {
- return;
- }
- add_action( 'rest_api_init', array( __CLASS__, 'register_endpoints' ) );
- add_action( 'wp_ajax_pum_analytics', array( __CLASS__, 'ajax_request' ) );
- add_action( 'wp_ajax_nopriv_pum_analytics', array( __CLASS__, 'ajax_request' ) );
- add_filter( 'pum_vars', array( __CLASS__, 'pum_vars' ) );
- }
- /**
- * Checks whether analytics is enabled.
- *
- * @return bool
- */
- public static function analytics_enabled() {
- $disabled = pum_get_option( 'disable_analytics' ) || popmake_get_option( 'disable_popup_open_tracking' );
- return (bool) apply_filters( 'pum_analytics_enabled', ! $disabled );
- }
- /**
- * Get a list of key pairs for each event type.
- * Internally used only for meta keys.
- *
- * Example returns [[open,opened],[conversion,conversion]].
- *
- * Usage examples:
- * - popup_open_count, popup_last_opened
- * - popup_conversion_count, popup_last_conversion
- *
- * @param string $event Event key.
- *
- * @return mixed
- */
- public static function event_keys( $event ) {
- $keys = array( $event, rtrim( $event, 'e' ) . 'ed' );
- if ( 'conversion' === $event ) {
- $keys[1] = 'conversion';
- }
- return apply_filters( 'pum_analytics_event_keys', $keys, $event );
- }
- /**
- * Returns an array of valid event types.
- *
- * @return string[]
- */
- public static function valid_events() {
- return apply_filters( 'pum_analytics_valid_events', array( 'open', 'conversion' ) );
- }
- /**
- * Track an event.
- *
- * This is called by various methods including the ajax & rest api requests.
- *
- * Can be used externally such as after purchase tracking.
- *
- * @param array $args
- */
- public static function track( $args = array() ) {
- if ( empty ( $args['pid'] ) || $args['pid'] <= 0 ) {
- return;
- }
- // $uuid = isset( $_COOKIE['__pum'] ) ? sanitize_text_field( $_COOKIE['__pum'] ) : false;
- // $session = $uuid && isset( $_COOKIE[ $uuid ] ) ? PUM_Utils_Array::safe_json_decode( $_COOKIE[ $uuid ] ) : false;
- $event = sanitize_text_field( $args['event'] );
- $popup = pum_get_popup( $args['pid'] );
- if ( ! pum_is_popup( $popup ) || ! in_array( $event, self::valid_events(), true ) ) {
- return;
- }
- $popup->increase_event_count( $event );
- if ( has_action( 'pum_analytics_' . $event ) ) {
- do_action( 'pum_analytics_' . $event, $popup->ID, $args );
- }
- do_action( 'pum_analytics_event', $args );
- }
- /**
- * Process ajax requests.
- *
- * Only used when WP-JSON Restful API is not available.
- */
- public static function ajax_request() {
- $args = wp_parse_args( $_REQUEST, array(
- 'event' => null,
- 'pid' => null,
- 'method' => null,
- ) );
- self::track( $args );
- switch ( $args['method'] ) {
- case 'image':
- self::serve_pixel();
- break;
- case 'json':
- self::serve_json();
- break;
- default:
- self::serve_no_content();
- break;
- }
- }
- /**
- * @param WP_REST_Request $request
- *
- * @return WP_Error|mixed
- */
- public static function analytics_endpoint( WP_REST_Request $request ) {
- $args = $request->get_params();
- if ( ! $args || empty( $args['pid'] ) ) {
- return new WP_Error( 'missing_params', __( 'Missing Parameters.' ), array( 'status' => 404 ) );
- }
- self::track( $args );
- self::serve_no_content();
- return true;
- }
- /**
- * @param $param
- *
- * @return bool
- */
- public static function endpoint_absint( $param ) {
- return is_numeric( $param );
- }
- /**
- * Registers the analytics endpoints
- */
- public static function register_endpoints() {
- register_rest_route( self::get_analytics_namespace(), self::get_analytics_route(), apply_filters( 'pum_analytics_rest_route_args', array(
- 'methods' => 'GET',
- 'callback' => array( __CLASS__, 'analytics_endpoint' ),
- 'permission_callback' => '__return_true',
- 'args' => array(
- 'event' => array(
- 'required' => true,
- 'description' => __( 'Event Type', 'popup-maker' ),
- 'type' => 'string',
- ),
- 'pid' => array(
- 'required' => true,
- 'description' => __( 'Popup ID', 'popup-maker' ),
- 'type' => 'integer',
- 'validation_callback' => array( __CLASS__, 'endpoint_absint' ),
- 'sanitize_callback' => 'absint',
- ),
- ),
- ) ) );
- }
- /**
- * Adds our analytics endpoint to pum_vars
- *
- * @param array $vars The current pum_vars.
- * @return array The updates pum_vars
- */
- public static function pum_vars( $vars = array() ) {
- $vars['analytics_route'] = self::get_analytics_route();
- if ( function_exists( 'rest_url' ) ) {
- $vars['analytics_api'] = esc_url_raw( rest_url( self::get_analytics_namespace() ) );
- } else {
- $vars['analytics_api'] = false;
- }
- return $vars;
- }
- /**
- * Gets the analytics namespace
- *
- * If bypass adblockers is enabled, will return random or custom string. If not, returns 'pum/v1'.
- *
- * @return string The analytics namespce
- * @since 1.13.0
- */
- public static function get_analytics_namespace() {
- $version = 1;
- $namespace = self::customize_endpoint_value( 'pum' );
- return "$namespace/v$version";
- }
- /**
- * Gets the analytics route
- *
- * If bypass adblockers is enabled, will return random or custom string. If not, returns 'analytics'.
- *
- * @return string The analytics route
- * @since 1.13.0
- */
- public static function get_analytics_route() {
- $route = 'analytics';
- return self::customize_endpoint_value( $route );
- }
- /**
- * Customizes the endpoint value given to it
- *
- * If bypass adblockers is enabled, will return random or custom string. If not, returns the value given to it.
- *
- * @param string $value The value to, potentially, customize.
- * @return string
- * @since 1.13.0
- */
- public static function customize_endpoint_value( $value = '' ) {
- $bypass_adblockers = pum_get_option( 'bypass_adblockers', false );
- if ( true === $bypass_adblockers || 1 === intval( $bypass_adblockers ) ) {
- switch ( pum_get_option( 'adblock_bypass_url_method', 'random' ) ) {
- case 'custom':
- $value = preg_replace( '/[^a-z0-9]+/', '-', pum_get_option( 'adblock_bypass_custom_filename', $value ) );
- break;
- case 'random':
- default:
- $site_url = get_site_url();
- $value = md5( $site_url . $value );
- break;
- }
- }
- return $value;
- }
- /**
- * Creates and returns a 1x1 tracking gif to the browser.
- */
- public static function serve_pixel() {
- $gif = self::get_file( Popup_Maker::$DIR . 'assets/images/beacon.gif' );
- header( 'Content-Type: image/gif' );
- header( 'Content-Length: ' . strlen( $gif ) );
- exit( $gif );
- }
- /**
- * @param $path
- *
- * @return bool|string
- */
- public static function get_file( $path ) {
- if ( function_exists( 'realpath' ) ) {
- $path = realpath( $path );
- }
- if ( ! $path || ! @is_file( $path ) ) {
- return '';
- }
- return @file_get_contents( $path );
- }
- /**
- * Returns a 204 no content header.
- */
- public static function serve_no_content() {
- header( "HTTP/1.0 204 No Content" );
- header( 'Content-Type: image/gif' );
- header( 'Content-Length: 0' );
- exit;
- }
- /**
- * Serves a proper json response.
- *
- * @param mixed $data
- */
- public static function serve_json( $data = 0 ) {
- header( 'Content-Type: application/json' );
- echo PUM_Utils_Array::safe_json_encode( $data );
- exit;
- }
- }
|