cid = $this->create_client_id(); $this->api_secret = $api_secret; $this->event_name = $event_name; } /** * Sets the custom event parameters * * @since 2.0.0 * * @param array $parameters The user's IP address. */ public function set_params( $parameters ) { $this->parameters = $parameters; } /** * Gets the custom event parameters. * * @since 2.3 * * @return array Returns the custom event parameters. */ public function get_params() { return $this->parameters; } /** * Sets the User's IP * * @since 1.0.0 * * @param string $user_ip The user's IP address. */ public function set_user_ip_address( $user_ip ) { $this->uip = $user_ip; } /** * Sets the document path * * @since 1.0.0 * * @param string $document_path The path of the document. */ public function set_document_path( $document_path ) { $this->dp = $document_path; } /** * Sets the document host * * @since 1.0.0 * * @param string $document_host The host of the document. */ public function set_document_host( $document_host ) { $this->dh = $document_host; } /** * Sets the document location * * @since 1.0.0 * * @param string $document_location The location of the document. */ public function set_document_location( $document_location ) { $this->dl = $document_location; } /** * Sets the document title * * @since 1.0.0 * * @param string $document_title The document title for the page being submitted. */ public function set_document_title( $document_title ) { $this->dt = $document_title; } /** * Sends the data to the measurement protocol * * @since 1.0.0 * * @param string $ua_code The UA code to send the event to. * @param string $event_name The event name to be used. */ public function send( $google_analytics_code ) { // Get variables in wp_remote_post body format. $user_properties_vars = array( 'dp', 'dl', 'dt', 'dh', 'uip' ); $user_properties = array(); foreach ( $user_properties_vars as $key => $user_properties_var ) { if ( empty( $this->{ $user_properties_vars[ $key ] } ) ) { // Empty params cause the payload to fail in testing. continue; } $user_properties[ $user_properties_var ] = $this->{$user_properties_vars[ $key ]}; } $session_id = $this->get_browser_session_id( $google_analytics_code ); if ( $session_id ) { $this->parameters['session_id'] = $session_id; } $url = $this->endpoint . 'measurement_id=' . $google_analytics_code . '&api_secret=' . $this->api_secret; $body = array( 'client_id' => $this->cid, 'events' => array( 'name' => $this->event_name, 'params' => $this->parameters, ), ); gf_google_analytics()->log_debug( __METHOD__ . '(): Sending data to Google Analytics Measurement Protocol. URL (last 4 of api_secret only): ' . substr( $url, 0, strpos( $url, 'api_secret=' ) + 11 ) . 'XXXXXXX' . substr( $url, -4 ) . ' - Body: ' . print_r( $body, true ) ); // Perform the POST. return wp_remote_post( $url, array( 'body' => wp_json_encode( $body ), ) ); } /** * Create a GUID on Client specific values * * @since 1.0.0 * * @return string New Client ID. */ private function create_client_id() { // collect user specific data. if ( isset( $_COOKIE['_ga'] ) ) { $ga_cookie = explode( '.', sanitize_text_field( wp_unslash( $_COOKIE['_ga'] ) ) ); if ( isset( $ga_cookie[2] ) ) { // check if uuid. if ( $this->check_uuid( $ga_cookie[2] ) ) { // uuid set in cookie. return $ga_cookie[2]; } elseif ( isset( $ga_cookie[2] ) && isset( $ga_cookie[3] ) ) { // google default client id. return $ga_cookie[2] . '.' . $ga_cookie[3]; } } } // nothing found - return random uuid client id. return GFFormsModel::get_uuid(); } /** * Get the session id. * * @since 2.3.0 * @since 2.4.0 added support for the GS2 cookie format. * * @param string $measurement_id The measurement id. * * @return string|null The session id. */ private function get_browser_session_id( $measurement_id ) { $session_id = null; // Cookie name example: '_ga_1YS1VWHG3V'. $cookie_name = '_ga_' . str_replace( 'G-', '', $measurement_id ); if ( isset( $_COOKIE[ $cookie_name ] ) ) { $cookie_value = sanitize_text_field( wp_unslash( $_COOKIE[ $cookie_name ] ) ); // Check for the new GS2 cookie format. if ( str_contains( $cookie_value, '$' ) && preg_match( '/s(\d+)/', $cookie_value, $matches ) ) { $session_id = $matches[1]; } // Fallback to the dot delimited GS1 format. if ( ! $session_id ) { $parts = explode( '.', $cookie_value ); if ( isset( $parts[3] ) && is_numeric( $parts[3] ) ) { $session_id = $parts[3]; } } } /** * Filter the GA4 session ID used in Measurement Protocol requests. * * @param string|null $session_id Parsed session ID or null if not found. * @param string $cookie_name Name of the GA cookie used. * @param string $measurement_id GA4 Measurement ID. */ $session_id = apply_filters( 'gform_googleanalytics_mp_session_id', $session_id, $cookie_name, $measurement_id ); return $session_id; } /** * Check if is a valid uuid v4 * * @since 1.0.0 * * @param string $uuid The UUID to check. * * @return bool If the UUID is valid */ private function check_uuid( $uuid ) { return preg_match( '#^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$#i', $uuid ); } }