File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/AttributeMapping.tar
AttributeMappingHelper.php 0000644 00000010013 15154777263 0011710 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping;
use Automattic\WooCommerce\GoogleListingsAndAds\Infrastructure\Service;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Adult;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\AgeGroup;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Brand;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Color;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\AttributeInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Condition;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Gender;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\GTIN;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\IsBundle;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Material;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\MPN;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Multipack;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Pattern;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\Size;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\SizeSystem;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\SizeType;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\Attributes\WithMappingInterface;
defined( 'ABSPATH' ) || exit;
/**
* Helper Class for Attribute Mapping
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping
*/
class AttributeMappingHelper implements Service {
private const ATTRIBUTES_AVAILABLE_FOR_MAPPING = [
Adult::class,
AgeGroup::class,
Brand::class,
Color::class,
Condition::class,
Gender::class,
GTIN::class,
IsBundle::class,
Material::class,
MPN::class,
Multipack::class,
Pattern::class,
Size::class,
SizeSystem::class,
SizeType::class,
];
public const CATEGORY_CONDITION_TYPE_ALL = 'ALL';
public const CATEGORY_CONDITION_TYPE_ONLY = 'ONLY';
public const CATEGORY_CONDITION_TYPE_EXCEPT = 'EXCEPT';
/**
* Gets all the available attributes for mapping
*
* @return array
*/
public function get_attributes(): array {
$destinations = [];
/**
* @var WithMappingInterface $attribute
*/
foreach ( self::ATTRIBUTES_AVAILABLE_FOR_MAPPING as $attribute ) {
array_push(
$destinations,
[
'id' => $attribute::get_id(),
'label' => $attribute::get_name(),
'enum' => $attribute::is_enum(),
]
);
}
return $destinations;
}
/**
* Get the attribute class based on attribute ID.
*
* @param string $attribute_id The attribute ID to get the class
* @return string|null The attribute class path or null if it's not found
*/
public static function get_attribute_by_id( string $attribute_id ): ?string {
foreach ( self::ATTRIBUTES_AVAILABLE_FOR_MAPPING as $class ) {
if ( $class::get_id() === $attribute_id ) {
return $class;
}
}
return null;
}
/**
* Get the sources for an attribute
*
* @param string $attribute_id The attribute ID to get the sources from.
* @return array The sources for the attribute
*/
public function get_sources_for_attribute( string $attribute_id ): array {
/**
* @var AttributeInterface $attribute
*/
$attribute = self::get_attribute_by_id( $attribute_id );
$attribute_sources = [];
if ( is_null( $attribute ) ) {
return $attribute_sources;
}
foreach ( $attribute::get_sources() as $key => $value ) {
array_push(
$attribute_sources,
[
'id' => $key,
'label' => $value,
]
);
}
return $attribute_sources;
}
/**
* Get the available conditions for the category.
*
* @return string[] The list of available category conditions
*/
public function get_category_condition_types(): array {
return [
self::CATEGORY_CONDITION_TYPE_ALL,
self::CATEGORY_CONDITION_TYPE_EXCEPT,
self::CATEGORY_CONDITION_TYPE_ONLY,
];
}
}
Traits/IsEnumTrait.php 0000644 00000001104 15154777263 0010744 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\Traits;
defined( 'ABSPATH' ) || exit;
/**
* Trait for enums
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\Traits
*/
trait IsEnumTrait {
/**
* Returns true for the is_enum property
*
* @return true
*/
public static function is_enum(): bool {
return true;
}
/**
* Returns the attribute sources
*
* @return array
*/
public static function get_sources(): array {
return self::get_value_options();
}
}
Traits/IsFieldTrait.php 0000644 00000007572 15154777263 0011102 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\Traits;
defined( 'ABSPATH' ) || exit;
/**
* Trait for fields
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\Traits
*/
trait IsFieldTrait {
/**
* Returns false for the is_enum property
*
* @return false
*/
public static function is_enum(): bool {
return false;
}
/**
* Returns the attribute sources
*
* @return array The available sources
*/
public static function get_sources(): array {
return apply_filters(
'woocommerce_gla_attribute_mapping_sources',
array_merge(
self::get_source_product_fields(),
self::get_source_taxonomies(),
self::get_source_custom_attributes()
),
self::get_id()
);
}
/**
* Gets the taxonomies and global attributes to render them as options in the frontend.
*
* @return array An array with the taxonomies and global attributes
*/
public static function get_source_taxonomies(): array {
$object_taxonomies = get_object_taxonomies( 'product', 'objects' );
$taxonomies = [];
$attributes = [];
$sources = [];
foreach ( $object_taxonomies as $taxonomy ) {
if ( taxonomy_is_product_attribute( $taxonomy->name ) ) {
$attributes[ 'taxonomy:' . $taxonomy->name ] = $taxonomy->label;
continue;
}
$taxonomies[ 'taxonomy:' . $taxonomy->name ] = $taxonomy->label;
}
asort( $taxonomies );
asort( $attributes );
$attributes = apply_filters( 'woocommerce_gla_attribute_mapping_sources_global_attributes', $attributes );
$taxonomies = apply_filters( 'woocommerce_gla_attribute_mapping_sources_taxonomies', $taxonomies );
if ( ! empty( $attributes ) ) {
$sources = array_merge(
[
'disabled:attributes' => __( '- Global attributes -', 'google-listings-and-ads' ),
],
$attributes
);
}
if ( ! empty( $taxonomies ) ) {
$sources = array_merge(
$sources,
[
'disabled:taxonomies' => __( '- Taxonomies -', 'google-listings-and-ads' ),
],
$taxonomies
);
}
return $sources;
}
/**
* Get a list of the available product sources.
*
* @return array An array with the available product sources.
*/
public static function get_source_product_fields(): array {
$fields = [
'product:backorders' => __( 'Allow backorders setting', 'google-listings-and-ads' ),
'product:title' => __( 'Product title', 'google-listings-and-ads' ),
'product:sku' => __( 'SKU', 'google-listings-and-ads' ),
'product:stock_quantity' => __( 'Stock Qty', 'google-listings-and-ads' ),
'product:stock_status' => __( 'Stock Status', 'google-listings-and-ads' ),
'product:tax_class' => __( 'Tax class', 'google-listings-and-ads' ),
'product:name' => __( 'Variation title', 'google-listings-and-ads' ),
'product:weight' => __( 'Weight (raw value, no units)', 'google-listings-and-ads' ),
'product:weight_with_unit' => __( 'Weight (with units)', 'google-listings-and-ads' ),
];
asort( $fields );
$fields = array_merge(
[
'disabled:product' => __( '- Product fields -', 'google-listings-and-ads' ),
],
$fields
);
return apply_filters( 'woocommerce_gla_attribute_mapping_sources_product_fields', $fields );
}
/**
* Allowing to register custom attributes by using a filter.
*
* @return array The custom attributes
*/
public static function get_source_custom_attributes(): array {
$attributes = [];
$attribute_keys = apply_filters( 'woocommerce_gla_attribute_mapping_sources_custom_attributes', [] );
foreach ( $attribute_keys as $key ) {
$attributes[ 'attribute:' . $key ] = $key;
}
if ( ! empty( $attributes ) ) {
$attributes = array_merge(
[
'disabled:attribute' => __( '- Custom Attributes -', 'google-listings-and-ads' ),
],
$attributes
);
}
return $attributes;
}
}
AttributeMappingDataController.php 0000644 00000010200 15155527740 0013376 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\BaseOptionsController;
use Automattic\WooCommerce\GoogleListingsAndAds\API\TransportMethods;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\AttributeMappingHelper;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\RESTServer;
use WP_REST_Request as Request;
use WP_REST_Response as Response;
use Exception;
defined( 'ABSPATH' ) || exit;
/**
* Class for handling API requests for getting source and destination data for Attribute Mapping
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping
*/
class AttributeMappingDataController extends BaseOptionsController {
/**
* @var AttributeMappingHelper
*/
private AttributeMappingHelper $attribute_mapping_helper;
/**
* AttributeMappingDataController constructor.
*
* @param RESTServer $server
* @param AttributeMappingHelper $attribute_mapping_helper
*/
public function __construct( RESTServer $server, AttributeMappingHelper $attribute_mapping_helper ) {
parent::__construct( $server );
$this->attribute_mapping_helper = $attribute_mapping_helper;
}
/**
* Register rest routes with WordPress.
*/
public function register_routes(): void {
/**
* GET the destination fields for Google Shopping
*/
$this->register_route(
'mc/mapping/attributes',
[
[
'methods' => TransportMethods::READABLE,
'callback' => $this->get_mapping_attributes_read_callback(),
'permission_callback' => $this->get_permission_callback(),
],
'schema' => $this->get_api_response_schema_callback(),
],
);
/**
* GET for getting the source data for a specific destination
*/
$this->register_route(
'mc/mapping/sources',
[
[
'methods' => TransportMethods::READABLE,
'callback' => $this->get_mapping_sources_read_callback(),
'permission_callback' => $this->get_permission_callback(),
'args' => [
'attribute' => [
'description' => __( 'The attribute key to get the sources.', 'google-listings-and-ads' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
'required' => true,
],
],
],
'schema' => $this->get_api_response_schema_callback(),
],
);
}
/**
* Callback function for returning the attributes
*
* @return callable
*/
protected function get_mapping_attributes_read_callback(): callable {
return function ( Request $request ) {
try {
return $this->prepare_item_for_response( $this->get_attributes(), $request );
} catch ( Exception $e ) {
return new Response( [ 'message' => $e->getMessage() ], $e->getCode() ?: 400 );
}
};
}
/**
* Callback function for returning the sources.
*
* @return callable
*/
protected function get_mapping_sources_read_callback(): callable {
return function ( Request $request ) {
try {
$attribute = $request->get_param( 'attribute' );
return [
'data' => $this->attribute_mapping_helper->get_sources_for_attribute( $attribute ),
];
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Get the item schema properties for the controller.
*
* @return array
*/
protected function get_schema_properties(): array {
return [
'data' => [
'type' => 'array',
'description' => __( 'The list of attributes or attribute sources.', 'google-listings-and-ads' ),
'context' => [ 'view' ],
'readonly' => true,
],
];
}
/**
* Get the item schema name for the controller.
*
* Used for building the API response schema.
*
* @return string
*/
protected function get_schema_title(): string {
return 'attribute_mapping_data';
}
/**
* Attributes getter
*
* @return array The attributes available for mapping
*/
private function get_attributes(): array {
return [
'data' => $this->attribute_mapping_helper->get_attributes(),
];
}
}
AttributeMappingRulesController.php 0000644 00000021445 15155527740 0013634 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\BaseOptionsController;
use Automattic\WooCommerce\GoogleListingsAndAds\API\TransportMethods;
use Automattic\WooCommerce\GoogleListingsAndAds\DB\Query\AttributeMappingRulesQuery;
use Automattic\WooCommerce\GoogleListingsAndAds\Product\AttributeMapping\AttributeMappingHelper;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\RESTServer;
use WP_Error;
use WP_REST_Request as Request;
use WP_REST_Response as Response;
use Exception;
defined( 'ABSPATH' ) || exit;
/**
* Class for handling API requests for getting source and destination data for Attribute Mapping
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping
*/
class AttributeMappingRulesController extends BaseOptionsController {
/**
* @var AttributeMappingRulesQuery
*/
private AttributeMappingRulesQuery $attribute_mapping_rules_query;
/**
* @var AttributeMappingHelper
*/
private AttributeMappingHelper $attribute_mapping_helper;
/**
* AttributeMappingRulesController constructor.
*
* @param RESTServer $server
* @param AttributeMappingHelper $attribute_mapping_helper
* @param AttributeMappingRulesQuery $attribute_mapping_rules_query
*/
public function __construct( RESTServer $server, AttributeMappingHelper $attribute_mapping_helper, AttributeMappingRulesQuery $attribute_mapping_rules_query ) {
parent::__construct( $server );
$this->attribute_mapping_helper = $attribute_mapping_helper;
$this->attribute_mapping_rules_query = $attribute_mapping_rules_query;
}
/**
* Register rest routes with WordPress.
*/
public function register_routes(): void {
$this->register_route(
'mc/mapping/rules',
[
[
'methods' => TransportMethods::READABLE,
'callback' => $this->get_rule_callback(),
'permission_callback' => $this->get_permission_callback(),
'args' => $this->get_collection_params(),
],
[
'methods' => TransportMethods::CREATABLE,
'callback' => $this->create_rule_callback(),
'permission_callback' => $this->get_permission_callback(),
'args' => $this->get_schema_properties(),
],
'schema' => $this->get_api_response_schema_callback(),
],
);
$this->register_route(
'mc/mapping/rules/(?P<id>[\d]+)',
[
[
'methods' => TransportMethods::EDITABLE,
'callback' => $this->update_rule_callback(),
'permission_callback' => $this->get_permission_callback(),
'args' => $this->get_schema_properties(),
],
[
'methods' => TransportMethods::DELETABLE,
'callback' => $this->delete_rule_callback(),
'permission_callback' => $this->get_permission_callback(),
],
'schema' => $this->get_api_response_schema_callback(),
],
);
}
/**
* Callback function for getting the Attribute Mapping rules from DB
*
* @return callable
*/
protected function get_rule_callback(): callable {
return function ( Request $request ) {
try {
$page = $request->get_param( 'page' );
$per_page = $request->get_param( 'per_page' );
$this->attribute_mapping_rules_query->set_limit( $per_page );
$this->attribute_mapping_rules_query->set_offset( $per_page * ( $page - 1 ) );
$rules = $this->attribute_mapping_rules_query->get_results();
$total_rules = $this->attribute_mapping_rules_query->get_count();
$response_data = [];
foreach ( $rules as $rule ) {
$item_data = $this->prepare_item_for_response( $rule, $request );
$response_data[] = $this->prepare_response_for_collection( $item_data );
}
return new Response(
$response_data,
200,
[
'X-WP-Total' => $total_rules,
'X-WP-TotalPages' => ceil( $total_rules / $per_page ),
]
);
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Callback function for saving an Attribute Mapping rule in DB
*
* @return callable
*/
protected function create_rule_callback(): callable {
return function ( Request $request ) {
try {
if ( ! $this->attribute_mapping_rules_query->insert( $this->prepare_item_for_database( $request ) ) ) {
return $this->response_from_exception( new Exception( 'Unable to create the new rule.' ) );
}
$response = $this->prepare_item_for_response( $this->attribute_mapping_rules_query->get_rule( $this->attribute_mapping_rules_query->last_insert_id() ), $request );
do_action( 'woocommerce_gla_mapping_rules_change' );
return $response;
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Callback function for saving an Attribute Mapping rule in DB
*
* @return callable
*/
protected function update_rule_callback(): callable {
return function ( Request $request ) {
try {
$rule_id = $request->get_url_params()['id'];
if ( ! $this->attribute_mapping_rules_query->update( $this->prepare_item_for_database( $request ), [ 'id' => $rule_id ] ) ) {
return $this->response_from_exception( new Exception( 'Unable to update the new rule.' ) );
}
$response = $this->prepare_item_for_response( $this->attribute_mapping_rules_query->get_rule( $rule_id ), $request );
do_action( 'woocommerce_gla_mapping_rules_change' );
return $response;
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Callback function for deleting an Attribute Mapping rule in DB
*
* @return callable
*/
protected function delete_rule_callback(): callable {
return function ( Request $request ) {
try {
$rule_id = $request->get_url_params()['id'];
if ( ! $this->attribute_mapping_rules_query->delete( 'id', $rule_id ) ) {
return $this->response_from_exception( new Exception( 'Unable to delete the rule' ) );
}
do_action( 'woocommerce_gla_mapping_rules_change' );
return [
'id' => $rule_id,
];
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Get the item schema properties for the controller.
*
* @return array The Schema properties
*/
protected function get_schema_properties(): array {
return [
'id' => [
'description' => __( 'The Id for the rule.', 'google-listings-and-ads' ),
'type' => 'integer',
'validate_callback' => 'rest_validate_request_arg',
'readonly' => true,
],
'attribute' => [
'description' => __( 'The attribute value for the rule.', 'google-listings-and-ads' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
'required' => true,
'enum' => array_column( $this->attribute_mapping_helper->get_attributes(), 'id' ),
],
'source' => [
'description' => __( 'The source value for the rule.', 'google-listings-and-ads' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
'required' => true,
],
'category_condition_type' => [
'description' => __( 'The category condition type to apply for this rule.', 'google-listings-and-ads' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
'required' => true,
'enum' => $this->attribute_mapping_helper->get_category_condition_types(),
],
'categories' => [
'description' => __( 'List of category IDs, separated by commas.', 'google-listings-and-ads' ),
'type' => 'string',
'required' => false,
'validate_callback' => function ( $param ) {
return $this->validate_categories_param( $param );
},
],
];
}
/**
* Get the item schema name for the controller.
*
* Used for building the API response schema.
*
* @return string
*/
protected function get_schema_title(): string {
return 'attribute_mapping_rules';
}
/**
* @param string $categories Categories to validate
* @return bool|WP_Error True if it's validated
*
* @throw Exception when invalid categories are provided
*/
public function validate_categories_param( string $categories ) {
if ( $categories === '' ) {
return true;
}
$categories_array = explode( ',', $categories );
foreach ( $categories_array as $category ) {
if ( ! is_numeric( $category ) ) {
return new WP_Error(
'woocommerce_gla_attribute_mapping_invalid_categories_schema',
'categories should be a string of category IDs separated by commas.',
[
'categories' => $categories,
]
);
}
}
return true;
}
}
AttributeMappingSyncerController.php 0000644 00000006417 15155527740 0014007 0 ustar 00 <?php
declare( strict_types=1 );
namespace Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping;
use Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\BaseController;
use Automattic\WooCommerce\GoogleListingsAndAds\API\TransportMethods;
use Automattic\WooCommerce\GoogleListingsAndAds\Jobs\ProductSyncStats;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsAwareTrait;
use Automattic\WooCommerce\GoogleListingsAndAds\Options\OptionsInterface;
use Automattic\WooCommerce\GoogleListingsAndAds\Proxies\RESTServer;
use WP_REST_Request as Request;
use Exception;
defined( 'ABSPATH' ) || exit;
/**
* Class for handling API requests for getting the current Syncing state
*
* @package Automattic\WooCommerce\GoogleListingsAndAds\API\Site\Controllers\AttributeMapping
*/
class AttributeMappingSyncerController extends BaseController implements OptionsAwareInterface {
use OptionsAwareTrait;
/**
* @var ProductSyncStats
*/
protected $sync_stats;
/**
* AttributeMappingSyncerController constructor.
*
* @param RESTServer $server
* @param ProductSyncStats $sync_stats
*/
public function __construct( RESTServer $server, ProductSyncStats $sync_stats ) {
parent::__construct( $server );
$this->sync_stats = $sync_stats;
}
/**
* Register rest routes with WordPress.
*/
public function register_routes(): void {
$this->register_route(
'mc/mapping/sync',
[
[
'methods' => TransportMethods::READABLE,
'callback' => $this->get_sync_callback(),
'permission_callback' => $this->get_permission_callback(),
],
'schema' => $this->get_api_response_schema_callback(),
],
);
}
/**
* Callback function for getting the Attribute Mapping Sync State
*
* @return callable
*/
protected function get_sync_callback(): callable {
return function ( Request $request ) {
try {
$state = [
'is_scheduled' => (bool) $this->sync_stats->get_count(),
'last_sync' => $this->options->get( OptionsInterface::UPDATE_ALL_PRODUCTS_LAST_SYNC ),
];
return $this->prepare_item_for_response( $state, $request );
} catch ( Exception $e ) {
return $this->response_from_exception( $e );
}
};
}
/**
* Get the item schema properties for the controller.
*
* @return array The Schema properties
*/
protected function get_schema_properties(): array {
return [
'is_scheduled' => [
'description' => __( 'Indicates if the products are currently syncing', 'google-listings-and-ads' ),
'type' => 'boolean',
'validate_callback' => 'rest_validate_request_arg',
'readonly' => true,
'context' => [ 'view' ],
],
'last_sync' => [
'description' => __( 'Timestamp with the last sync.', 'google-listings-and-ads' ),
'type' => 'string',
'validate_callback' => 'rest_validate_request_arg',
'readonly' => true,
'context' => [ 'view' ],
],
];
}
/**
* Get the item schema name for the controller.
*
* Used for building the API response schema.
*
* @return string
*/
protected function get_schema_title(): string {
return 'attribute_mapping_syncer';
}
}