ad_impressions ) ) { $this->ad_impressions = array(); } $this->ad_impressions[] = $ad; if ( ProBridge::instance()->is_pro_loaded() && class_exists( '\ADCmdr\TrackingAmpPro' ) ) { TrackingAmpPro::instance()->queue_impression( $ad ); } } protected function priority() { if ( $this->priority ) { /** * Make sure amp-pixel runs after all inserts. */ $this->priority = apply_filters( 'adcmdr_amp_action_priority', absint( Options::instance()->get( 'filter_priority', 'general', false, Placement::placement_priority_default() ) ) + 10 ); } return $this->priority; } public function hooks_local_tracking() { if ( Options::instance()->get( 'disable_amp_pixel', 'tracking', true ) || ! is_ssl() ) { return; } $priority = $this->priority(); add_action( 'wp_footer', array( $this, 'amp_pixel' ), $priority ); // https://wordpress.org/plugins/amp/ // https://wordpress.org/plugins/accelerated-mobile-pages/ add_action( 'amp_post_template_footer', array( $this, 'amp_pixel' ), $priority ); } public function hooks_ga_tracking() { if ( ProBridge::instance()->is_pro_loaded() && class_exists( '\ADCmdr\TrackingAmpPro' ) ) { TrackingAmpPro::instance()->hooks_ga_tracking(); } } public function amp_pixel() { if ( ! $this->ad_impressions || empty( $this->ad_impressions ) || in_array( 'local', $this->tracking_complete, true ) ) { return; } $action = 'track-impression'; $frontend = new Frontend(); $action_string = $frontend->action_string( $action ); $security = $frontend->not_a_nonce( $action ); /** * AMP Pixel must be served over HTTPS. */ $url = admin_url( 'admin-ajax.php' ); if ( stripos( $url, 'http://', 0 ) !== false ) { $url = str_ireplace( 'http://', 'https://', $url ); } $amp_pixel = sprintf( '', esc_url( add_query_arg( array( 'ad_ids' => array_map( 'absint', wp_list_pluck( $this->ad_impressions, 'ad_id' ) ), 'action' => $action_string, 'security' => $security, 'referrer' => rawurlencode( $this->get_referrer() ), ), $url ) ) ); echo wp_kses( $amp_pixel, array( 'amp-pixel' => array( 'src' => array(), 'layout' => array(), 'class' => array(), ), ) ); $this->tracking_complete[] = 'local'; } /** * Get the canonical (non-AMP) referrer path for the current request. * * Strips AMP endpoint suffixes so that impressions are recorded * against the original page URL rather than the AMP variant. * * @return string The cleaned referrer path, always starting with '/'. */ private function get_referrer() { global $wp; $referrer = isset( $wp->request ) && ! is_null( $wp->request ) ? $wp->request : ''; if ( $referrer === '' && isset( $_SERVER['REQUEST_URI'] ) ) { $referrer = sanitize_url( wp_unslash( $_SERVER['REQUEST_URI'] ) ); } $referrer = $this->strip_amp_suffix( $referrer ); if ( strpos( $referrer, '/' ) !== 0 ) { $referrer = '/' . $referrer; } return $referrer; } /** * Remove AMP-related suffixes from a URL path. * * Handles the various ways AMP endpoints appear: * - /some-page/amp/ (path-based endpoint) * - /some-page/amp (path-based without trailing slash) * - /some-page?amp=1 (query-string based) * - /some-page?amp (query-string valueless) * * @param string $url_path The URL path or request URI to clean. * * @return string The path with AMP suffix removed. */ private function strip_amp_suffix( $url_path ) { // Split off query string if present. $parts = explode( '?', $url_path, 2 ); $path = $parts[0]; $query = isset( $parts[1] ) ? $parts[1] : ''; // Remove /amp or /amp/ from the end of the path segment. $path = preg_replace( '#/amp/?$#i', '', $path ); // Remove amp parameter from the query string. if ( $query !== '' ) { $query = preg_replace( '/(?:^|&)amp(?:=[^&]*)?/', '', $query ); $query = ltrim( $query, '&' ); } // Rebuild without unnecessary query separator. if ( $query !== '' ) { return $path . '?' . $query; } return $path; } }