in my product.blade.php
@php
// Prepare sizes for sorting
$uniqueSizes = [];
foreach ($filteredProducts as $product) {
$variants = $product['variants']['edges'] ?? [];
foreach ($variants as $variantEdge) {
$variant = $variantEdge['node'];
$selectedOptions = $variant['selectedOptions'] ?? [];
foreach ($selectedOptions as $option) {
if ($option['name'] === 'Size') {
$sizeValue = $option['value'];
if (strpos($sizeValue, 'x') !== false) {
preg_match('/(\d+)x(\d+)/', $sizeValue, $matches);
if (count($matches) == 3) {
$uniqueSizes[$sizeValue] = $matches[1] * $matches[2]; // Store size and area
}
}
}
}
}
}
// Define sorting function
$sortFunction = function($a, $b) use ($uniqueSizes, $sortOrder) {
$aSizeValue = '';
$bSizeValue = '';
if (isset($a['variants']['edges'][0]['node'])) {
$selectedOptions = $a['variants']['edges'][0]['node']['selectedOptions'] ?? [];
foreach ($selectedOptions as $option) {
if ($option['name'] === 'Size') {
$aSizeValue = $option['value'];
break;
}
}
}
if (isset($b['variants']['edges'][0]['node'])) {
$selectedOptions = $b['variants']['edges'][0]['node']['selectedOptions'] ?? [];
foreach ($selectedOptions as $option) {
if ($option['name'] === 'Size') {
$bSizeValue = $option['value'];
break;
}
}
}
$aSize = $uniqueSizes[$aSizeValue] ?? 0;
$bSize = $uniqueSizes[$bSizeValue] ?? 0;
switch ($sortOrder) {
case 'size_small_big':
return $aSize <=> $bSize; // Small to big
case 'size_big_small':
return $bSize <=> $aSize; // Big to small
case 'price_low_high':
$aPrice = $a['variants']['edges'][0]['node']['price']['amount'] ?? 0;
$bPrice = $b['variants']['edges'][0]['node']['price']['amount'] ?? 0;
return $aPrice <=> $bPrice; // Low to high
case 'price_high_low':
$aPrice = $a['variants']['edges'][0]['node']['price']['amount'] ?? 0;
$bPrice = $b['variants']['edges'][0]['node']['price']['amount'] ?? 0;
return $bPrice <=> $aPrice; // High to low
// Add cases for other sorting options here if needed
default:
return 0; // No sorting
}
};
// Sort the products array
usort($filteredProducts, $sortFunction);
@endphp
<!-- Sort Order Dropdown -->
<label for="sortOrder" class="sr-only">Sort Order</label>
<select name="sortOrder" id="sortOrder" onchange="this.form.submit()" class="tw-h-12 tw-mr-1 tw-bg-gray-100 tw-rounded-lg tw-w-52 tw-border-gray-50">
<option value="" disabled selected>Select sort order</option>
<option value="date_new_old" @IF($sortOrder === 'date_new_old') selected @endif>Date: New to Old</option> <option value="date_old_new" @IF($sortOrder === 'date_old_new') selected @endif>Date: Old to New</option> <option value="price_low_high" @IF($sortOrder === 'price_low_high') selected @endif>Price: Low to High</option> <option value="price_high_low" @IF($sortOrder === 'price_high_low') selected @endif>Price: High to Low</option> <option value="size_small_big" @IF($sortOrder === 'size_small_big') selected @endif>Size: Small to Big</option> <option value="size_big_small" @IF($sortOrder === 'size_big_small') selected @endif>Size: Big to Small</option> </select>
and this is my controller using graphql
$sortOrder = $request->input('sortOrder'); // Default to ascending order
if ($sortOrder === 'desc') {
$reverse = true; // Set to true for descending order
} elseif ($sortOrder === 'date_old_new') {
$sortKey = 'CREATED'; // Sort by Date: Old-New
$reverse = false; // Ensure ascending order for date_old_new
} elseif ($sortOrder === 'date_new_old') {
$sortKey = 'CREATED'; // Sort by Date: New-Old
$reverse = true; // Set to true for descending order for date_new_old
} elseif ($sortOrder === 'price_low_high') {
$sortKey = 'PRICE'; // Sort by Price: Low-High
} elseif ($sortOrder === 'price_high_low') {
$sortKey = 'PRICE'; // Sort by Price: High-Low
$reverse = !$reverse; // Reverse the order for Price: High-Low
}
// Define your GraphQL query
$query = <<<GRAPHQL
query(\$collectionId: ID!, \$cursor: String, \$sortKey: ProductCollectionSortKeys, \$reverse: Boolean) {
collection(id: \$collectionId) {
products(first: 250, after: \$cursor, sortKey: \$sortKey, reverse: \$reverse) {
pageInfo {
hasNextPage
endCursor
}
edges {
cursor
node {
id
title
tags
createdAt
images(first: 1) {
edges {
node {
src
}
}
}
variants(first: 1) {
edges {
node {
id
quantityAvailable
compareAtPrice {
amount
currencyCode
}
price {
amount
currencyCode
}
availableForSale
selectedOptions {
name
value
}
}
}
}
}
}
}
}
}
GRAPHQL;
// Function to fetch products from Shopify using GraphQL
function fetchProductsFromShopify($accessToken, $graphqlEndpoint, $query, $variables)
{
$allProducts = [];
$cursor = null;
do {
// Set cursor variable in variables array
$variables['cursor'] = $cursor;
// Prepare payload for GraphQL request
$payload = [
'query' => $query,
'variables' => $variables,
];
// Make GraphQL API request to Shopify
$response = Http::withHeaders([
'X-Shopify-Storefront-Access-Token' => $accessToken,
])->post($graphqlEndpoint, $payload);
// Process response data
$data = $response->json();
if (isset($data['data']['collection']['products']['edges'])) {
foreach ($data['data']['collection']['products']['edges'] as $productEdge) {
$allProducts[] = $productEdge['node'];
}
}
// Update cursor for pagination
if (isset($data['data']['collection']['products']['pageInfo'])) {
$pageInfo = $data['data']['collection']['products']['pageInfo'];
$cursor = $pageInfo['endCursor']; // Update cursor
$hasNextPage = $pageInfo['hasNextPage'];
} else {
// No more pages, exit loop
$hasNextPage = false;
}
} while ($hasNextPage);
return $allProducts;
}