'calls', 'WEBSITE_CLICKS' => 'web', 'BUSINESS_DIRECTION_REQUESTS' => 'dirs', 'BUSINESS_IMPRESSIONS_DESKTOP_MAPS' => 'views', 'BUSINESS_IMPRESSIONS_DESKTOP_SEARCH' => 'views', 'BUSINESS_IMPRESSIONS_MOBILE_MAPS' => 'views', 'BUSINESS_IMPRESSIONS_MOBILE_SEARCH' => 'views', ); /** * HTTP client. * * @var HttpClient */ private $http; /** * Constructor. * * @param HttpClient $http HTTP client. */ public function __construct( HttpClient $http ) { $this->http = $http; } /** * Locations across every Business Profile account the user manages. * * @param int $ttl Cache lifetime. * @return array[] Items with id ("locations/123") and name. * @throws ApiException On failure. */ public function locations( $ttl ) { $accounts = $this->http->get( self::ACCOUNTS . '/accounts', $ttl ); $out = array(); foreach ( isset( $accounts['accounts'] ) ? (array) $accounts['accounts'] : array() as $account ) { if ( empty( $account['name'] ) ) { continue; } $token = ''; $pages = 0; do { $url = self::INFORMATION . '/' . $account['name'] . '/locations?readMask=name,title,storefrontAddress&pageSize=100' . ( '' !== $token ? '&pageToken=' . rawurlencode( $token ) : '' ); $data = $this->http->get( $url, $ttl ); foreach ( isset( $data['locations'] ) ? (array) $data['locations'] : array() as $loc ) { if ( empty( $loc['name'] ) ) { continue; } $city = isset( $loc['storefrontAddress']['locality'] ) ? $loc['storefrontAddress']['locality'] : ''; $title = isset( $loc['title'] ) ? $loc['title'] : $loc['name']; $out[] = array( 'id' => (string) $loc['name'], 'name' => $title . ( $city ? ' ยท ' . $city : '' ), ); } $token = isset( $data['nextPageToken'] ) ? (string) $data['nextPageToken'] : ''; ++$pages; } while ( '' !== $token && $pages < 20 ); } return $out; } /** * Daily calls, website clicks, direction requests and profile views. * * @param string $location Location resource name. * @param string $start Start date (Y-m-d). * @param string $end End date (Y-m-d). * @param int $ttl Cache lifetime. * @return array Keyed by date, each with calls, web, dirs and views. * @throws ApiException On failure. */ public function daily_metrics( $location, $start, $end, $ttl ) { if ( ! preg_match( '#^locations/\d+$#', $location ) ) { throw new ApiException( __( 'The Business Profile location for this site is invalid. Choose it again in the site\'s settings.', 'turtlereport' ), ApiException::NOT_CONFIGURED ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Caught by the plugin; escaped where the message is shown. } list( $sy, $sm, $sd ) = array_map( 'intval', explode( '-', $start ) ); list( $ey, $em, $ed ) = array_map( 'intval', explode( '-', $end ) ); $query = array(); foreach ( array_keys( self::METRICS ) as $metric ) { $query[] = 'dailyMetrics=' . $metric; } $query[] = 'dailyRange.start_date.year=' . $sy; $query[] = 'dailyRange.start_date.month=' . $sm; $query[] = 'dailyRange.start_date.day=' . $sd; $query[] = 'dailyRange.end_date.year=' . $ey; $query[] = 'dailyRange.end_date.month=' . $em; $query[] = 'dailyRange.end_date.day=' . $ed; $data = $this->http->get( self::PERFORMANCE . '/' . $location . ':fetchMultiDailyMetricsTimeSeries?' . implode( '&', $query ), $ttl ); $out = array(); foreach ( isset( $data['multiDailyMetricTimeSeries'] ) ? (array) $data['multiDailyMetricTimeSeries'] : array() as $group ) { foreach ( isset( $group['dailyMetricTimeSeries'] ) ? (array) $group['dailyMetricTimeSeries'] : array() as $series ) { $metric = isset( $series['dailyMetric'] ) ? $series['dailyMetric'] : ''; if ( ! isset( self::METRICS[ $metric ] ) ) { continue; } $key = self::METRICS[ $metric ]; foreach ( isset( $series['timeSeries']['datedValues'] ) ? (array) $series['timeSeries']['datedValues'] : array() as $point ) { if ( empty( $point['date']['year'] ) ) { continue; } $date = sprintf( '%04d-%02d-%02d', $point['date']['year'], $point['date']['month'], $point['date']['day'] ); if ( ! isset( $out[ $date ] ) ) { $out[ $date ] = array( 'calls' => 0, 'web' => 0, 'dirs' => 0, 'views' => 0, ); } $out[ $date ][ $key ] += isset( $point['value'] ) ? (int) $point['value'] : 0; } } } ksort( $out ); return $out; } }