File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/Query.tar
AttributeMappingRulesQuery.php 0000644 00000002727 15154744300 0012610 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\AttributeMappingRulesTable;
use wpdb;
defined( 'ABSPATH' ) || exit;
/**
* Class defining the queries for the Attribute Mapping Rules Table
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Query
*/
class AttributeMappingRulesQuery extends Query {
/**
* AttributeMappingRulesQuery constructor.
*
* @param wpdb $wpdb
* @param AttributeMappingRulesTable $table
*/
public function __construct( wpdb $wpdb, AttributeMappingRulesTable $table ) {
parent::__construct( $wpdb, $table );
}
/**
* Sanitize a value for a given column before inserting it into the DB.
*
* @param string $column The column name.
* @param mixed $value The value to sanitize.
*
* @return mixed The sanitized value.
*/
protected function sanitize_value( string $column, $value ) {
if ( $column === 'attribute' || $column === 'source' ) {
return sanitize_text_field( $value );
}
if ( $column === 'categories' && is_null( $value ) ) {
return '';
}
return $value;
}
/**
* Gets a specific rule from Database
*
* @param int $rule_id The rule ID to get from Database
* @return array The rule from database
*/
public function get_rule( int $rule_id ): array {
return $this->where( 'id', $rule_id )->get_row();
}
}
BudgetRecommendationQuery.php 0000644 00000002355 15154744300 0012412 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\BudgetRecommendationTable;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidQuery;
use wpdb;
defined( 'ABSPATH' ) || exit;
/**
* Class BudgetRecommendationQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Query
*/
class BudgetRecommendationQuery extends Query {
/**
* BudgetRecommendationQuery constructor.
*
* @param wpdb $wpdb
* @param BudgetRecommendationTable $table
*/
public function __construct( wpdb $wpdb, BudgetRecommendationTable $table ) {
parent::__construct( $wpdb, $table );
}
/**
* Sanitize a value for a given column before inserting it into the DB.
*
* @param string $column The column name.
* @param mixed $value The value to sanitize.
*
* @return mixed The sanitized value.
* @throws InvalidQuery When the code tries to set the ID column.
*/
protected function sanitize_value( string $column, $value ) {
if ( 'id' === $column ) {
throw InvalidQuery::cant_set_id( BudgetRecommendationTable::class );
}
return $value;
}
}
MerchantIssueQuery.php 0000644 00000001710 15154744300 0011057 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\MerchantIssueTable;
use wpdb;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantIssueQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Query
*/
class MerchantIssueQuery extends Query {
/**
* MerchantIssueQuery constructor.
*
* @param wpdb $wpdb
* @param MerchantIssueTable $table
*/
public function __construct( wpdb $wpdb, MerchantIssueTable $table ) {
parent::__construct( $wpdb, $table );
}
/**
* Sanitize a value for a given column before inserting it into the DB.
*
* @param string $column The column name.
* @param mixed $value The value to sanitize.
*
* @return mixed The sanitized value.
*/
protected function sanitize_value( string $column, $value ) {
return $value;
}
}
ShippingRateQuery.php 0000644 00000003243 15154744300 0010705 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\ShippingRateTable;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidQuery;
use wpdb;
defined( 'ABSPATH' ) || exit;
/**
* Class ShippingRateQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Query
*/
class ShippingRateQuery extends Query {
/**
* ShippingRateQuery constructor.
*
* @param wpdb $wpdb
* @param ShippingRateTable $table
*/
public function __construct( wpdb $wpdb, ShippingRateTable $table ) {
parent::__construct( $wpdb, $table );
}
/**
* Sanitize a value for a given column before inserting it into the DB.
*
* @param string $column The column name.
* @param mixed $value The value to sanitize.
*
* @return mixed The sanitized value.
* @throws InvalidQuery When the code tries to set the ID column.
*/
protected function sanitize_value( string $column, $value ) {
if ( 'id' === $column ) {
throw InvalidQuery::cant_set_id( ShippingRateTable::class );
}
if ( 'options' === $column ) {
if ( ! is_array( $value ) ) {
throw InvalidQuery::invalid_value( $column );
}
$value = wp_json_encode( $value );
}
return $value;
}
/**
* Perform the query and save it to the results.
*/
protected function query_results() {
parent::query_results();
$this->results = array_map(
function ( $row ) {
$row['options'] = ! empty( $row['options'] ) ? json_decode( $row['options'], true ) : $row['options'];
return $row;
},
$this->results
);
}
}
ShippingTimeQuery.php 0000644 00000003126 15154744300 0010710 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Table\ShippingTimeTable;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidQuery;
use wpdb;
defined( 'ABSPATH' ) || exit;
/**
* Class ShippingTimeQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\DB\Query
*/
class ShippingTimeQuery extends Query {
/**
* ShippingTimeQuery constructor.
*
* @param wpdb $wpdb
* @param ShippingTimeTable $table
*/
public function __construct( wpdb $wpdb, ShippingTimeTable $table ) {
parent::__construct( $wpdb, $table );
}
/**
* Sanitize a value for a given column before inserting it into the DB.
*
* @param string $column The column name.
* @param mixed $value The value to sanitize.
*
* @return mixed The sanitized value.
* @throws InvalidQuery When the code tries to set the ID column.
*/
protected function sanitize_value( string $column, $value ) {
if ( 'id' === $column ) {
throw InvalidQuery::cant_set_id( ShippingTimeTable::class );
}
return $value;
}
/**
* Get all shipping times.
*
* @since 2.8.0
*
* @return array
*/
public function get_all_shipping_times() {
$times = $this->get_results();
$items = [];
foreach ( $times as $time ) {
$data = [
'country_code' => $time['country'],
'time' => $time['time'],
'max_time' => $time['max_time'] ?: $time['time'],
];
$items[ $time['country'] ] = $data;
}
return $items;
}
}
AdsAccountAccessQuery.php 0000644 00000001027 15155407217 0011460 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsAccountAccessQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsAccountAccessQuery extends AdsQuery {
/**
* AdsAccountAccessQuery constructor.
*/
public function __construct() {
parent::__construct( 'customer_user_access' );
$this->columns( [ 'customer_user_access.resource_name', 'customer_user_access.access_role' ] );
}
}
AdsAccountQuery.php 0000644 00000001010 15155407217 0010326 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsAccountQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsAccountQuery extends AdsQuery {
/**
* AdsAccountQuery constructor.
*/
public function __construct() {
parent::__construct( 'customer' );
$this->columns( [ 'customer.id', 'customer.descriptive_name', 'customer.manager', 'customer.test_account' ] );
}
}
AdsAssetGroupAssetQuery.php 0000644 00000001201 15155407217 0012030 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsAssetGroupAssetQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsAssetGroupAssetQuery extends AdsQuery {
/**
* AdsAssetGroupAssetQuery constructor.
*/
public function __construct() {
parent::__construct( 'asset_group_asset' );
$this->columns( [ 'asset.id', 'asset.name', 'asset.type', 'asset.text_asset.text', 'asset.image_asset.full_size.url', 'asset.call_to_action_asset.call_to_action', 'asset_group_asset.field_type' ] );
}
}
AdsAssetGroupQuery.php 0000644 00000001163 15155407217 0011037 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsAssetGroupQuery
*
* @since 1.12.2
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsAssetGroupQuery extends AdsQuery {
/**
* AdsAssetGroupQuery constructor.
*
* @param array $search_args List of search args, such as pageSize.
*/
public function __construct( array $search_args = [] ) {
parent::__construct( 'asset_group' );
$this->columns( [ 'asset_group.resource_name' ] );
$this->search_args = $search_args;
}
}
AdsBillingStatusQuery.php 0000644 00000001153 15155407217 0011526 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsBillingStatusQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsBillingStatusQuery extends AdsQuery {
/**
* AdsBillingStatusQuery constructor.
*/
public function __construct() {
parent::__construct( 'billing_setup' );
$this->columns(
[
'status' => 'billing_setup.status',
'start_date_time' => 'billing_setup.start_date_time',
]
);
$this->set_order( 'start_date_time', 'DESC' );
}
}
AdsCampaignBudgetQuery.php 0000644 00000000740 15155407217 0011615 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsCampaignBudgetQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsCampaignBudgetQuery extends AdsQuery {
/**
* AdsCampaignBudgetQuery constructor.
*/
public function __construct() {
parent::__construct( 'campaign' );
$this->columns( [ 'campaign.campaign_budget' ] );
}
}
AdsCampaignCriterionQuery.php 0000644 00000001052 15155407217 0012336 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsCampaignCriterionQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsCampaignCriterionQuery extends AdsQuery {
/**
* AdsCampaignCriterionQuery constructor.
*/
public function __construct() {
parent::__construct( 'campaign_criterion' );
$this->columns(
[
'campaign.id',
'campaign_criterion.location.geo_target_constant',
]
);
}
}
AdsCampaignLabelQuery.php 0000644 00000000727 15155407217 0011427 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsCampaignLabelQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsCampaignLabelQuery extends AdsQuery {
/**
* AdsCampaignLabelQuery constructor.
*/
public function __construct() {
parent::__construct( 'label' );
$this->columns(
[
'label.id',
]
);
}
}
AdsCampaignQuery.php 0000644 00000001164 15155407217 0010463 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsCampaignQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsCampaignQuery extends AdsQuery {
/**
* AdsCampaignQuery constructor.
*/
public function __construct() {
parent::__construct( 'campaign' );
$this->columns(
[
'campaign.id',
'campaign.name',
'campaign.status',
'campaign.advertising_channel_type',
'campaign.shopping_setting.feed_label',
'campaign_budget.amount_micros',
]
);
}
}
AdsCampaignReportQuery.php 0000644 00000001561 15155407217 0011660 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsCampaignReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsCampaignReportQuery extends AdsReportQuery {
/**
* Set the initial columns for this query.
*/
protected function set_initial_columns() {
$this->columns(
[
'id' => 'campaign.id',
'name' => 'campaign.name',
'status' => 'campaign.status',
'type' => 'campaign.advertising_channel_type',
]
);
}
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
public function filter( array $ids ): QueryInterface {
if ( empty( $ids ) ) {
return $this;
}
return $this->where( 'campaign.id', $ids, 'IN' );
}
}
AdsConversionActionQuery.php 0000644 00000001244 15155407217 0012226 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsConversionActionQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsConversionActionQuery extends AdsQuery {
/**
* AdsConversionActionQuery constructor.
*/
public function __construct() {
parent::__construct( 'conversion_action' );
$this->columns(
[
'id' => 'conversion_action.id',
'name' => 'conversion_action.name',
'status' => 'conversion_action.status',
'tag_snippets' => 'conversion_action.tag_snippets',
]
);
}
}
AdsProductLinkInvitationQuery.php 0000644 00000001110 15155407217 0013236 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsProductLinkInvitationQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsProductLinkInvitationQuery extends AdsQuery {
/**
* AdsProductLinkInvitationQuery constructor.
*/
public function __construct() {
parent::__construct( 'product_link_invitation' );
$this->columns( [ 'product_link_invitation.merchant_center.merchant_center_id', 'product_link_invitation.status' ] );
}
}
AdsProductReportQuery.php 0000644 00000001466 15155407217 0011565 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsProductReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class AdsProductReportQuery extends AdsReportQuery {
/**
* Set the initial columns for this query.
*/
protected function set_initial_columns() {
$this->columns(
[
'id' => 'segments.product_item_id',
'name' => 'segments.product_title',
]
);
}
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
public function filter( array $ids ): QueryInterface {
if ( empty( $ids ) ) {
return $this;
}
return $this->where( 'segments.product_item_id', $ids, 'IN' );
}
}
AdsQuery.php 0000644 00000005405 15155407217 0007025 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidProperty;
use Automattic\WooCommerce\GoogleListingsAndAds\Google\Ads\GoogleAdsClient;
use Google\Ads\GoogleAds\V18\Services\GoogleAdsRow;
use Google\Ads\GoogleAds\V18\Services\SearchGoogleAdsRequest;
use Google\Ads\GoogleAds\V18\Services\SearchSettings;
use Google\ApiCore\ApiException;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
abstract class AdsQuery extends Query {
/**
* Client which handles the query.
*
* @var GoogleAdsClient
*/
protected $client = null;
/**
* Ads Account ID.
*
* @var int
*/
protected $id = null;
/**
* Arguments to add to the search query.
*
* Note: While we allow pageSize to be set, we do not pass it to the API.
* pageSize has been deprecated in the API since V17 and is fixed to 10000 rows.
*
* @var array
*/
protected $search_args = [];
/**
* Set the client which will handle the query.
*
* @param GoogleAdsClient $client Client instance.
* @param int $id Account ID.
*
* @return QueryInterface
* @throws InvalidProperty If the ID is empty.
*/
public function set_client( GoogleAdsClient $client, int $id ): QueryInterface {
if ( empty( $id ) ) {
throw InvalidProperty::not_null( get_class( $this ), 'id' );
}
$this->client = $client;
$this->id = $id;
return $this;
}
/**
* Get the first row from the results.
*
* @return GoogleAdsRow
* @throws ApiException When no results returned or an error occurs.
*/
public function get_result(): GoogleAdsRow {
$results = $this->get_results();
if ( $results ) {
foreach ( $results->iterateAllElements() as $row ) {
return $row;
}
}
throw new ApiException( __( 'No result from query', 'google-listings-and-ads' ), 404, '' );
}
/**
* Perform the query and save it to the results.
*
* @throws ApiException If the search call fails.
* @throws InvalidProperty If the client is not set.
*/
protected function query_results() {
if ( ! $this->client || ! $this->id ) {
throw InvalidProperty::not_null( get_class( $this ), 'client' );
}
$request = new SearchGoogleAdsRequest();
if ( ! empty( $this->search_args['pageToken'] ) ) {
$request->setPageToken( $this->search_args['pageToken'] );
}
// Allow us to get the total number of results.
$request->setSearchSettings(
new SearchSettings(
[
'return_total_results_count' => true,
]
)
);
$request->setQuery( $this->build_query() );
$request->setCustomerId( $this->id );
$this->results = $this->client->getGoogleAdsServiceClient()->search( $request );
}
}
AdsReportQuery.php 0000644 00000003713 15155407217 0010221 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
use Google\Ads\GoogleAds\V18\Resources\ShoppingPerformanceView;
defined( 'ABSPATH' ) || exit;
/**
* Class AdsReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
abstract class AdsReportQuery extends AdsQuery {
use ReportQueryTrait;
/**
* AdsReportQuery constructor.
* Uses the resource ShoppingPerformanceView.
*
* @param array $args Query arguments.
*/
public function __construct( array $args ) {
parent::__construct( 'shopping_performance_view' );
$this->set_initial_columns();
$this->handle_query_args( $args );
}
/**
* Add all the requested fields.
*
* @param array $fields List of fields.
*
* @return $this
*/
public function fields( array $fields ): QueryInterface {
$map = [
'clicks' => 'metrics.clicks',
'impressions' => 'metrics.impressions',
'spend' => 'metrics.cost_micros',
'sales' => 'metrics.conversions_value',
'conversions' => 'metrics.conversions',
];
$this->add_columns( array_intersect_key( $map, array_flip( $fields ) ) );
return $this;
}
/**
* Add a segment interval to the query.
*
* @param string $interval Type of interval.
*
* @return $this
*/
public function segment_interval( string $interval ): QueryInterface {
$map = [
'day' => 'segments.date',
'week' => 'segments.week',
'month' => 'segments.month',
'quarter' => 'segments.quarter',
'year' => 'segments.year',
];
if ( isset( $map[ $interval ] ) ) {
$this->add_columns( [ $interval => $map[ $interval ] ] );
}
return $this;
}
/**
* Set the initial columns for this query.
*/
abstract protected function set_initial_columns();
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
abstract public function filter( array $ids ): QueryInterface;
}
MerchantFreeListingReportQuery.php 0000644 00000001247 15155407217 0013407 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantFreeListingReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class MerchantFreeListingReportQuery extends MerchantReportQuery {
/**
* Set the initial columns for this query.
*/
protected function set_initial_columns() {}
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
public function filter( array $ids ): QueryInterface {
// No filtering available for free listings.
return $this;
}
}
MerchantProductReportQuery.php 0000644 00000001415 15155407217 0012611 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantProductReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class MerchantProductReportQuery extends MerchantReportQuery {
/**
* Set the initial columns for this query.
*/
protected function set_initial_columns() {
$this->columns(
[
'id' => 'segments.offer_id',
]
);
}
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
public function filter( array $ids ): QueryInterface {
if ( empty( $ids ) ) {
return $this;
}
return $this->where( 'segments.offer_id', $ids, 'IN' );
}
}
MerchantProductViewReportQuery.php 0000644 00000002217 15155407217 0013445 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantProductViewReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
class MerchantProductViewReportQuery extends MerchantQuery {
use ReportQueryTrait;
/**
* MerchantProductViewReportQuery constructor.
*
* @param array $args Query arguments.
*/
public function __construct( array $args ) {
parent::__construct( 'ProductView' );
$this->set_initial_columns();
$this->handle_query_args( $args );
}
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
public function filter( array $ids ): QueryInterface {
// No filtering used for product view report.
return $this;
}
/**
* Set the initial columns for this query.
*/
protected function set_initial_columns() {
$this->columns(
[
'id' => 'product_view.id',
'expiration_date' => 'product_view.expiration_date',
'status' => 'product_view.aggregated_destination_status',
]
);
}
}
MerchantQuery.php 0000644 00000004137 15155407217 0010060 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidProperty;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Exception as GoogleException;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\ShoppingContent;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\ShoppingContent\SearchRequest;
use Automattic\WooCommerce\GoogleListingsAndAds\Vendor\Google\Service\ShoppingContent\SearchResponse;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
abstract class MerchantQuery extends Query {
/**
* Client which handles the query.
*
* @var ShoppingContent
*/
protected $client = null;
/**
* Merchant Account ID.
*
* @var int
*/
protected $id = null;
/**
* Arguments to add to the search query.
*
* @var array
*/
protected $search_args = [];
/**
* Set the client which will handle the query.
*
* @param ShoppingContent $client Client instance.
* @param int $id Account ID.
*
* @return QueryInterface
*/
public function set_client( ShoppingContent $client, int $id ): QueryInterface {
$this->client = $client;
$this->id = $id;
return $this;
}
/**
* Perform the query and save it to the results.
*
* @throws GoogleException If the search call fails.
* @throws InvalidProperty If the client is not set.
*/
protected function query_results() {
if ( ! $this->client || ! $this->id ) {
throw InvalidProperty::not_null( get_class( $this ), 'client' );
}
$request = new SearchRequest();
$request->setQuery( $this->build_query() );
if ( ! empty( $this->search_args['pageSize'] ) ) {
$request->setPageSize( $this->search_args['pageSize'] );
}
if ( ! empty( $this->search_args['pageToken'] ) ) {
$request->setPageToken( $this->search_args['pageToken'] );
}
/** @var SearchResponse $this->results */
$this->results = $this->client->reports->search( $this->id, $request );
}
}
MerchantReportQuery.php 0000644 00000003444 15155407217 0011254 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Class MerchantReportQuery
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
abstract class MerchantReportQuery extends MerchantQuery {
use ReportQueryTrait;
/**
* MerchantReportQuery constructor.
*
* @param array $args Query arguments.
*/
public function __construct( array $args ) {
parent::__construct( 'MerchantPerformanceView' );
$this->set_initial_columns();
$this->handle_query_args( $args );
$this->where( 'segments.program', 'FREE_PRODUCT_LISTING' );
}
/**
* Add all the requested fields.
*
* @param array $fields List of fields.
*
* @return $this
*/
public function fields( array $fields ): QueryInterface {
$map = [
'clicks' => 'metrics.clicks',
'impressions' => 'metrics.impressions',
];
$this->add_columns( array_intersect_key( $map, array_flip( $fields ) ) );
return $this;
}
/**
* Add a segment interval to the query.
*
* @param string $interval Type of interval.
*
* @return $this
*/
public function segment_interval( string $interval ): QueryInterface {
$map = [
'day' => 'segments.date',
'week' => 'segments.week',
'month' => 'segments.month',
'quarter' => 'segments.quarter',
'year' => 'segments.year',
];
if ( isset( $map[ $interval ] ) ) {
$this->add_columns( [ $interval => $map[ $interval ] ] );
}
return $this;
}
/**
* Set the initial columns for this query.
*/
abstract protected function set_initial_columns();
/**
* Filter the query by a list of ID's.
*
* @param array $ids list of ID's to filter by.
*
* @return $this
*/
abstract public function filter( array $ids ): QueryInterface;
}
Query.php 0000644 00000017526 15155407217 0006404 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
use Automattic\WooCommerce\GoogleListingsAndAds\Exception\InvalidQuery;
use DateTime;
defined( 'ABSPATH' ) || exit;
/**
* Google Ads Query Language (GAQL)
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
abstract class Query implements QueryInterface {
/**
* Resource name.
*
* @var string
*/
protected $resource;
/**
* Set of columns to retrieve in the query.
*
* @var array
*/
protected $columns = [];
/**
* Where clauses for the query.
*
* @var array
*/
protected $where = [];
/**
* Where relation for multiple clauses.
*
* @var string
*/
protected $where_relation;
/**
* Order sort attribute.
*
* @var string
*/
protected $order = 'ASC';
/**
* Column to order by.
*
* @var string
*/
protected $orderby;
/**
* The result of the query.
*
* @var mixed
*/
protected $results = null;
/**
* Query constructor.
*
* @param string $resource_name
*
* @throws InvalidQuery When the resource name is not valid.
*/
public function __construct( string $resource_name ) {
if ( ! preg_match( '/^[a-zA-Z_]+$/', $resource_name ) ) {
throw InvalidQuery::resource_name();
}
$this->resource = $resource_name;
}
/**
* Set columns to retrieve in the query.
*
* @param array $columns List of column names.
*
* @return QueryInterface
*/
public function columns( array $columns ): QueryInterface {
$this->validate_columns( $columns );
$this->columns = $columns;
return $this;
}
/**
* Add a set columns to retrieve in the query.
*
* @param array $columns List of column names.
*
* @return QueryInterface
*/
public function add_columns( array $columns ): QueryInterface {
$this->validate_columns( $columns );
$this->columns = array_merge( $this->columns, array_filter( $columns ) );
return $this;
}
/**
* Add a where clause to the query.
*
* @param string $column The column name.
* @param mixed $value The where value.
* @param string $compare The comparison to use. Valid values are =, <, >, IN, NOT IN.
*
* @return QueryInterface
*/
public function where( string $column, $value, string $compare = '=' ): QueryInterface {
$this->validate_compare( $compare );
$this->where[] = [
'column' => $column,
'value' => $value,
'compare' => $compare,
];
return $this;
}
/**
* Add a where date between clause to the query.
*
* @since 1.7.0
*
* @link https://developers.google.com/shopping-content/guides/reports/query-language/date-ranges
*
* @param string $after Start of date range. In ISO 8601(YYYY-MM-DD) format.
* @param string $before End of date range. In ISO 8601(YYYY-MM-DD) format.
*
* @return QueryInterface
*/
public function where_date_between( string $after, string $before ): QueryInterface {
return $this->where( 'segments.date', [ $after, $before ], 'BETWEEN' );
}
/**
* Set the where relation for the query.
*
* @param string $relation
*
* @return QueryInterface
*/
public function set_where_relation( string $relation ): QueryInterface {
$this->validate_where_relation( $relation );
$this->where_relation = $relation;
return $this;
}
/**
* Set ordering information for the query.
*
* @param string $column
* @param string $order
*
* @return QueryInterface
* @throws InvalidQuery When the given column is not in the list of included columns.
*/
public function set_order( string $column, string $order = 'ASC' ): QueryInterface {
if ( ! array_key_exists( $column, $this->columns ) ) {
throw InvalidQuery::invalid_order_column( $column );
}
$this->orderby = $this->columns[ $column ];
$this->order = $this->normalize_order( $order );
return $this;
}
/**
* Get the results of the query.
*
* @return mixed
*/
public function get_results() {
if ( null === $this->results ) {
$this->query_results();
}
return $this->results;
}
/**
* Perform the query and save it to the results.
*/
protected function query_results() {
$this->results = [];
}
/**
* Validate a set of columns.
*
* @param array $columns
*
* @throws InvalidQuery When one of columns in the set is not valid.
*/
protected function validate_columns( array $columns ) {
array_walk( $columns, [ $this, 'validate_column' ] );
}
/**
* Validate that a given column is using a valid name.
*
* @param string $column
*
* @throws InvalidQuery When the given column is not valid.
*/
protected function validate_column( string $column ) {
if ( ! preg_match( '/^[a-zA-Z0-9\._]+$/', $column ) ) {
throw InvalidQuery::invalid_column( $column );
}
}
/**
* Validate that a compare operator is valid.
*
* @param string $compare
*
* @throws InvalidQuery When the compare value is not valid.
*/
protected function validate_compare( string $compare ) {
switch ( $compare ) {
case '=':
case '>':
case '<':
case '!=':
case 'IN':
case 'NOT IN':
case 'BETWEEN':
case 'IS NOT NULL':
case 'CONTAINS ANY':
// These are all valid.
return;
default:
throw InvalidQuery::from_compare( $compare );
}
}
/**
* Validate that a where relation is valid.
*
* @param string $relation
*
* @throws InvalidQuery When the relation value is not valid.
*/
protected function validate_where_relation( string $relation ) {
switch ( $relation ) {
case 'AND':
case 'OR':
// These are all valid.
return;
default:
throw InvalidQuery::where_relation( $relation );
}
}
/**
* Normalize the string for the order.
*
* Converts the string to uppercase, and will return only DESC or ASC.
*
* @param string $order
*
* @return string
*/
protected function normalize_order( string $order ): string {
$order = strtoupper( $order );
return 'DESC' === $order ? $order : 'ASC';
}
/**
* Build the query and return the query string.
*
* @return string
*
* @throws InvalidQuery When the set of columns is empty.
*/
protected function build_query(): string {
if ( empty( $this->columns ) ) {
throw InvalidQuery::empty_columns();
}
$columns = join( ',', $this->columns );
$pieces = [ "SELECT {$columns} FROM {$this->resource}" ];
$pieces = array_merge( $pieces, $this->generate_where_pieces() );
if ( $this->orderby ) {
$pieces[] = "ORDER BY {$this->orderby} {$this->order}";
}
return join( ' ', $pieces );
}
/**
* Generate the pieces for the WHERE part of the query.
*
* @return string[]
*/
protected function generate_where_pieces(): array {
if ( empty( $this->where ) ) {
return [];
}
$where_pieces = [ 'WHERE' ];
foreach ( $this->where as $where ) {
$column = $where['column'];
$compare = $where['compare'];
if ( 'IN' === $compare || 'NOT_IN' === $compare || 'CONTAINS ANY' === $compare ) {
$value = sprintf(
"('%s')",
join(
"','",
array_map(
function ( $value ) {
return $this->escape( $value );
},
$where['value']
)
)
);
} elseif ( 'BETWEEN' === $compare ) {
$value = "'{$this->escape( $where['value'][0] )}' AND '{$this->escape( $where['value'][1] )}'";
} elseif ( 'IS NOT NULL' === $compare ) {
$value = '';
} else {
$value = "'{$this->escape( $where['value'] )}'";
}
if ( count( $where_pieces ) > 1 ) {
$where_pieces[] = $this->where_relation ?? 'AND';
}
$where_pieces[] = "{$column} {$compare} {$value}";
}
return $where_pieces;
}
/**
* Escape the value to a string which can be used in a query.
*
* @param mixed $value Original value to escape.
*
* @return string
*/
protected function escape( $value ): string {
if ( $value instanceof DateTime ) {
return $value->format( 'Y-m-d' );
}
if ( ! is_numeric( $value ) ) {
return (string) $value;
}
return addslashes( (string) $value );
}
}
QueryInterface.php 0000644 00000002406 15155407217 0010214 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
defined( 'ABSPATH' ) || exit;
/**
* Interface QueryInterface
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
interface QueryInterface {
/**
* Set columns to retrieve in the query.
*
* @param array $columns List of column names.
*
* @return $this
*/
public function columns( array $columns ): QueryInterface;
/**
* Add a set columns to retrieve in the query.
*
* @param array $columns List of column names.
*
* @return $this
*/
public function add_columns( array $columns ): QueryInterface;
/**
* Set a where clause to query.
*
* @param string $column The column name.
* @param mixed $value The where value.
* @param string $compare The comparison to use. Valid values are =, <, >, IN, NOT IN.
*
* @return $this
*/
public function where( string $column, $value, string $compare = '=' ): QueryInterface;
/**
* Set the where relation for the query.
*
* @param string $relation
*
* @return QueryInterface
*/
public function set_where_relation( string $relation ): QueryInterface;
/**
* Get the results of the query.
*
* @return mixed
*/
public function get_results();
}
ReportQueryTrait.php 0000644 00000002477 15155407217 0010603 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query;
use DateTime;
defined( 'ABSPATH' ) || exit;
/**
* Trait ReportQueryTrait
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Google\Query
*/
trait ReportQueryTrait {
/**
* Handle the common arguments for this query.
*
* @param array $args List of arguments which were passed to the query.
*/
protected function handle_query_args( array $args ) {
if ( ! empty( $args['fields'] ) ) {
$this->fields( $args['fields'] );
}
if ( ! empty( $args['interval'] ) ) {
$this->segment_interval( $args['interval'] );
}
if ( ! empty( $args['after'] ) && ! empty( $args['before'] ) ) {
$after = $args['after'];
$before = $args['before'];
$this->where_date_between(
$after instanceof DateTime ? $after->format( 'Y-m-d' ) : $after,
$before instanceof DateTime ? $before->format( 'Y-m-d' ) : $before
);
}
if ( ! empty( $args['ids'] ) ) {
$this->filter( $args['ids'] );
}
if ( ! empty( $args['orderby'] ) ) {
$this->set_order( $args['orderby'], $args['order'] );
}
if ( ! empty( $args['per_page'] ) ) {
$this->search_args['pageSize'] = $args['per_page'];
}
if ( ! empty( $args['next_page'] ) ) {
$this->search_args['pageToken'] = $args['next_page'];
}
}
}