diff --git a/src/Adapters/README.md b/src/Adapters/README.md index 8a67a0b..767bba1 100644 --- a/src/Adapters/README.md +++ b/src/Adapters/README.md @@ -375,22 +375,51 @@ $query = $builder->getQuery(); $variables = $builder->getVariables(); ``` -### Custom GraphQL Query +### GraphQL Query Templates + +The `MagentoProductQuery` class provides static methods to generate GraphQL queries with shared item body definitions, ensuring consistency across different query types. ```php use BradSearch\SyncSdk\Magento\MagentoProductQuery; -// Use the default query template -$query = MagentoProductQuery::DEFAULT_QUERY; +// Default paginated query with full item fields +$query = MagentoProductQuery::getDefaultQuery(); +$variables = [ + 'filter' => ['category_id' => ['eq' => '2']], + 'pageSize' => 100, + 'currentPage' => 1 +]; + +// Query by specific product IDs (uses same item fields as default) +$query = MagentoProductQuery::getByIdsQuery(); +$variables = ['ids' => ['325465', '1924192', '1924190']]; + +// Minimal query for faster fetching on large catalogs +$query = MagentoProductQuery::getMinimalQuery(); -// Or use minimal query for faster fetching -$query = MagentoProductQuery::MINIMAL_QUERY; +// Incremental sync query (id, sku, updated_at only) +$query = MagentoProductQuery::getIncrementalQuery(); -// Or set a custom query +// Use with query builder $builder = new MagentoQueryBuilder(); $builder->setQuery($customQuery); ``` +#### Available Query Methods + +| Method | Variables | Item Fields | Use Case | +|--------|-----------|-------------|----------| +| `getDefaultQuery()` | `$filter`, `$pageSize`, `$currentPage` | Full (all fields) | Standard product sync | +| `getByIdsQuery()` | `$ids: [String!]` | Full (all fields) | Fetch specific products by ID | +| `getMinimalQuery()` | `$filter`, `$pageSize`, `$currentPage` | Minimal (basic fields) | Fast sync for large catalogs | +| `getIncrementalQuery()` | `$filter`, `$pageSize`, `$currentPage` | Incremental (id, sku, updated_at) | Check for updates | + +#### Item Body Types + +- **Full**: All product fields including attributes, descriptions, categories, prices, stock status +- **Minimal**: Basic fields only (id, sku, name, url, stock, price, image, categories) +- **Incremental**: Sync-only fields (id, sku, updated_at) + ### Field Mapping The MagentoAdapter performs **minimal transformation**: @@ -455,7 +484,7 @@ foreach ($result['errors'] as $error) { | `MagentoConfig` | Connection configuration (URL, token, timeout, SSL) | | `MagentoGraphQLClient` | cURL-based GraphQL HTTP client | | `MagentoQueryBuilder` | Fluent filter and pagination builder | -| `MagentoProductQuery` | Static GraphQL query templates | +| `MagentoProductQuery` | GraphQL query builder with shared item bodies | | `MagentoPaginatedFetcher` | Automatic pagination with generator support | ## Shared Utilities (AdapterUtils) diff --git a/src/Magento/MagentoProductQuery.php b/src/Magento/MagentoProductQuery.php index fa248c3..91654e5 100644 --- a/src/Magento/MagentoProductQuery.php +++ b/src/Magento/MagentoProductQuery.php @@ -5,29 +5,45 @@ namespace BradSearch\SyncSdk\Magento; /** - * Static GraphQL query templates for Magento product fetching + * GraphQL query builder for Magento product fetching. + * + * Provides static methods to generate GraphQL queries with shared item body definitions + * to ensure consistency across different query types. + * + * Available query methods: + * - getDefaultQuery(): Paginated query with filter support and full item fields + * - getByIdsQuery(): Query by specific product IDs with full item fields + * - getMinimalQuery(): Paginated query with minimal item fields (faster for large catalogs) + * - getIncrementalQuery(): Paginated query for sync checks (id, sku, updated_at only) + * + * Item body types: + * - Full: All product fields including attributes, descriptions, categories + * - Minimal: Basic fields for performance (id, sku, name, url, stock, price, image, categories) + * - Incremental: Sync-only fields (id, sku, updated_at) + * + * @example Default paginated query + * ```php + * $query = MagentoProductQuery::getDefaultQuery(); + * $variables = [ + * 'filter' => ['category_id' => ['eq' => '2']], + * 'pageSize' => 100, + * 'currentPage' => 1 + * ]; + * ``` + * + * @example Query by product IDs + * ```php + * $query = MagentoProductQuery::getByIdsQuery(); + * $variables = ['ids' => ['325465', '1924192', '1924190']]; + * ``` */ final class MagentoProductQuery { /** - * Default GraphQL query for fetching products with all common fields - * - * This query uses variables for filter, pageSize, and currentPage. - * Variables should be passed as: - * - $filter: ProductAttributeFilterInput (e.g., {"category_id": {"eq": "2"}}) - * - $pageSize: Int (e.g., 100) - * - $currentPage: Int (e.g., 1) + * Full item body with all product fields. + * Used by getDefaultQuery() and getByIdsQuery(). */ - public const DEFAULT_QUERY = <<<'GRAPHQL' -query GetProducts($filter: ProductAttributeFilterInput, $pageSize: Int, $currentPage: Int) { - products(filter: $filter, pageSize: $pageSize, currentPage: $currentPage) { - total_count - page_info { - current_page - page_size - total_pages - } - items { + private const FULL_ITEMS_BODY = <<<'GRAPHQL' id sku name @@ -64,24 +80,13 @@ final class MagentoProductQuery path } stock_status - } - } -} GRAPHQL; /** - * Minimal query for basic product data (faster for large catalogs) + * Minimal item body for faster queries on large catalogs. + * Used by getMinimalQuery(). */ - public const MINIMAL_QUERY = <<<'GRAPHQL' -query GetProducts($filter: ProductAttributeFilterInput, $pageSize: Int, $currentPage: Int) { - products(filter: $filter, pageSize: $pageSize, currentPage: $currentPage) { - total_count - page_info { - current_page - page_size - total_pages - } - items { + private const MINIMAL_ITEMS_BODY = <<<'GRAPHQL' id sku name @@ -100,34 +105,118 @@ final class MagentoProductQuery level path } - } - } -} GRAPHQL; /** - * Query for incremental sync (check updated products) + * Incremental sync item body (minimal fields for checking updates). + * Used by getIncrementalQuery(). */ - public const INCREMENTAL_QUERY = <<<'GRAPHQL' -query GetProducts($filter: ProductAttributeFilterInput, $pageSize: Int, $currentPage: Int) { - products(filter: $filter, pageSize: $pageSize, currentPage: $currentPage) { - total_count + private const INCREMENTAL_ITEMS_BODY = <<<'GRAPHQL' + id + sku + updated_at +GRAPHQL; + + /** + * Page info fragment for paginated queries. + */ + private const PAGE_INFO = <<<'GRAPHQL' page_info { current_page page_size total_pages } +GRAPHQL; + + private function __construct() + { + // Prevent instantiation + } + + /** + * Get the default paginated query with full item fields. + * + * Variables: + * - $filter: ProductAttributeFilterInput (e.g., {"category_id": {"eq": "2"}}) + * - $pageSize: Int (e.g., 100) + * - $currentPage: Int (e.g., 1) + */ + public static function getDefaultQuery(): string + { + return self::buildPaginatedQuery(self::FULL_ITEMS_BODY); + } + + /** + * Get query for fetching products by their IDs with full item fields. + * + * Variables: + * - $ids: [String!] (e.g., ["325465", "1924192", "1924190"]) + */ + public static function getByIdsQuery(): string + { + return self::buildByIdsQuery(self::FULL_ITEMS_BODY); + } + + /** + * Get minimal paginated query for faster performance on large catalogs. + * + * Variables: + * - $filter: ProductAttributeFilterInput (e.g., {"category_id": {"eq": "2"}}) + * - $pageSize: Int (e.g., 100) + * - $currentPage: Int (e.g., 1) + */ + public static function getMinimalQuery(): string + { + return self::buildPaginatedQuery(self::MINIMAL_ITEMS_BODY); + } + + /** + * Get incremental sync query for checking updated products. + * + * Variables: + * - $filter: ProductAttributeFilterInput (e.g., {"category_id": {"eq": "2"}}) + * - $pageSize: Int (e.g., 100) + * - $currentPage: Int (e.g., 1) + */ + public static function getIncrementalQuery(): string + { + return self::buildPaginatedQuery(self::INCREMENTAL_ITEMS_BODY); + } + + /** + * Build a paginated query with the given items body. + */ + private static function buildPaginatedQuery(string $itemsBody): string + { + $pageInfo = self::PAGE_INFO; + + return <<