### Generate Complete End-to-End Feed Example
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
This example shows how to create a multi-product feed with various attribute types and write it to an XML file. It includes setting up the feed, building individual products with detailed attributes, attaching shipping rules, and finally generating and saving the XML output. Ensure the 'vendor/autoload.php' is correctly included.
```php
setId('SHOE-BLU-10')
->setTitle('Acme Running Shoes — Blue, Size 10')
->setDescription('Lightweight road-running shoe with cushioned midsole and breathable mesh upper.')
->setLink('https://acmesports.example.com/shoes/acme-run-blue-10')
->setMobileLink('https://m.acmesports.example.com/shoes/acme-run-blue-10')
->setImage('https://cdn.acmesports.example.com/shoes/acme-run-blue-main.jpg')
->setPrice('89.99 USD')
->setSalePrice('74.99 USD')
->setBrand('Acme')
->setGtin('00012345678905')
->setMpn('ACME-RUN-BLU-10')
->setGoogleCategory('Apparel & Accessories > Shoes')
->setProductType('Running > Road Running')
->setColor('Blue')
->setSize('10 US')
->setMaterial('Mesh')
->setCondition(Condition::NEW_PRODUCT)
->setAvailability(Availability::IN_STOCK)
->setAdult(false)
->setShippingWeight('0.8 kg')
->setCustomLabel('summer-promo', 0)
->setCustomLabel('high-margin', 1);
// Add multiple product images
$item->addAdditionalImage('https://cdn.acmesports.example.com/shoes/acme-run-blue-side.jpg');
$item->addAdditionalImage('https://cdn.acmesports.example.com/shoes/acme-run-blue-sole.jpg');
// Attach a shipping rule
$shipping = new Shipping();
$shipping->setCountry('US')
->setService('UPS Ground')
->setPrice('0 USD');
$item->setShipping($shipping);
// Add a second shipping zone
$intlShipping = new Shipping();
$intlShipping->setCountry('CA')
->setService('Canada Post')
->setPrice('12.99 USD');
$item->addShipping($intlShipping);
// Add an attribute not covered by a named setter
$item->setAttribute('loyalty_points', '45');
$feed->addProduct($item);
// 3. Build a second product (out of stock / used condition)
$item2 = new Product();
$item2->setId('SHOE-RED-09-USED')
->setTitle('Acme Running Shoes — Red, Size 9 (Used)')
->setDescription('Pre-owned pair, excellent condition, worn fewer than 10 times.')
->setLink('https://acmesports.example.com/shoes/acme-run-red-9-used')
->setImage('https://cdn.acmesports.example.com/shoes/acme-run-red-used-main.jpg')
->setPrice('39.99 USD')
->setBrand('Acme')
->setGtin('00012345678912')
->setCondition(Condition::USED)
->setAvailability(Availability::IN_STOCK)
->setColor('Red')
->setSize('9 US');
$feed->addProduct($item2);
// 4. Generate and save the XML
$xml = $feed->build();
file_put_contents(__DIR__ . '/google-merchant-feed.xml', $xml);
echo "Feed written: " . strlen($xml) . " bytes\n";
```
--------------------------------
### Install Google Merchant Feed Generator via Composer
Source: https://github.com/vitalybaev/php-google-merchant-feed/blob/master/readme.md
Use this Composer command to add the library to your PHP project. Ensure Composer is installed and accessible in your terminal.
```bash
composer require vitalybaev/google-merchant-feed
```
--------------------------------
### Generate Google Merchant Feed XML
Source: https://github.com/vitalybaev/php-google-merchant-feed/blob/master/readme.md
This example demonstrates how to create a new feed, add products with various attributes (ID, title, description, link, image, availability, price, category, brand, GTIN, condition, color, size), and configure shipping details. The feed is then built into an XML string.
```php
use Vitalybaev\GoogleMerchant\Feed;
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Shipping;
use Vitalybaev\GoogleMerchant\Product\Availability\Availability;
// Create feed object
$feed = new Feed("My awesome store", "https://example.com", "My awesome description");
// Put products to the feed ($products - some data from database for example)
foreach ($products as $product) {
$item = new Product();
// Set common product properties
$item->setId($product->id);
$item->setTitle($product->title);
$item->setDescription($product->description);
$item->setLink($product->getUrl());
$item->setImage($product->getImage());
if ($product->isAvailable()) {
$item->setAvailability(Availability::IN_STOCK);
} else {
$item->setAvailability(Availability::OUT_OF_STOCK);
}
$item->setPrice("{$product->price} USD");
$item->setGoogleCategory($product->category_name);
$item->setBrand($product->brand->name);
$item->setGtin($product->barcode);
$item->setCondition('new');
// Some additional properties
$item->setColor($product->color);
$item->setSize($product->size);
// Shipping info
$shipping = new Shipping();
$shipping->setCountry('US');
$shipping->setRegion('CA, NSW, 03');
$shipping->setPostalCode('94043');
$shipping->setLocationId('21137');
$shipping->setService('UPS Express');
$shipping->setPrice('1300 USD');
$item->setShipping($shipping);
// Set a custom shipping label and weight (optional)
$item->setShippingLabel('ups-ground');
$item->setShippingWeight('2.14');
// Set a custom label (optional)
$item->setCustomLabel('Some Label 1', 0);
$item->setCustomLabel('Some Label 2', 1);
// Add this product to the feed
$feed->addProduct($item);
}
// Here we get complete XML of the feed, that we could write to file or send directly
$feedXml = $feed->build();
```
--------------------------------
### Set Core Product Identity and Listing Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Configure essential product details like ID, title, description, and URLs. Note that title and description are wrapped in CDATA.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setId('SKU-42') // g:id
->setTitle('Acme Running Shoes — Blue, Size 10') // g:title (wrapped in CDATA)
->setDescription('Lightweight mesh upper...') // g:description (CDATA)
->setLink('https://example.com/products/sku-42') // g:link
->setMobileLink('https://m.example.com/p/sku-42'); // g:mobile_link
```
--------------------------------
### Set Product Images
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Assign the primary image using `setImage()` and add supplementary images with `addAdditionalImage()`. `addAdditionalImage()` allows for multiple images, up to 10.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setImage('https://example.com/images/sku-42-main.jpg');
// Add multiple additional images
$item->addAdditionalImage('https://example.com/images/sku-42-side.jpg');
$item->addAdditionalImage('https://example.com/images/sku-42-back.jpg');
/*
Produces:
https://example.com/images/sku-42-side.jpghttps://example.com/images/sku-42-back.jpg
*/
```
--------------------------------
### Set Product Pricing
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the regular and sale prices for a product. The currency code must be appended to the numeric value.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setPrice('49.99 USD'); // g:price
$item->setSalePrice('34.99 USD'); // g:sale_price
```
--------------------------------
### Set Product Category and Type
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Assigns Google's taxonomy category and the merchant's own product type path to the product.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setGoogleCategory('Apparel & Accessories > Shoes'); // g:google_product_category
$item->setProductType('Running > Road Running > Neutral'); // g:product_type
```
--------------------------------
### Set and Add Product Shipping Rules
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Use `setShipping` to define a single shipping rule, overwriting any previous ones. Use `addShipping` to append additional shipping rules for different regions or services. Ensure the `Shipping` object is properly constructed with country, region, service, and price details.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Shipping;
$item = new Product();
// Build a shipping rule
$shipping = new Shipping();
$shipping->setCountry('US') // ISO 3166-1 country code
->setRegion('CA, NSW, 03')
->setPostalCode('94043')
->setLocationId('21137')
->setLocationGroupName('West Coast')
->setService('UPS Express')
->setPrice('5.99 USD');
$item->setShipping($shipping);
// Add a second shipping rule for a different region
$shipping2 = new Shipping();
$shipping2->setCountry('US')
->setRegion('NY')
->setService('FedEx Ground')
->setPrice('7.99 USD');
$item->addShipping($shipping2);
/*
Produces:
USCA, NSW, 03
...
USNY
...
*/
```
--------------------------------
### Product Condition
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the condition of the product. Accepts only 'new', 'refurbished', or 'used', and uses constants to prevent typos.
```APIDOC
## `Product::setCondition(string $condition)`
Sets the product condition. Accepts only `'new'`, `'refurbished'`, or `'used'`; throws `InvalidArgumentException` otherwise. Use the `Condition` constants to avoid typos.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Condition;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
try {
$item->setCondition(Condition::NEW_PRODUCT); // 'new'
// $item->setCondition(Condition::REFURBISHED); // 'refurbished'
// $item->setCondition(Condition::USED); // 'used'
} catch (InvalidArgumentException $e) {
error_log($e->getMessage());
}
```
```
--------------------------------
### Build and Output the XML Feed
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Serialize the feed to an XML string. This can be saved to a file or streamed as an HTTP response.
```php
use Vitalybaev\GoogleMerchant\Feed;
use Vitalybaev\GoogleMerchant\Product;
$feed = new Feed("My Store", "https://example.com", "Great deals", "2.0");
$item = new Product();
$item->setId('1')->setTitle('Widget')->setPrice('4.99 USD');
$feed->addProduct($item);
$xml = $feed->build();
// Write to file
file_put_contents('/var/www/feeds/google-merchant.xml', $xml);
// Or stream as HTTP response
header('Content-Type: application/xml; charset=utf-8');
echo $xml;
/*
Expected output:
My Store
https://example.com
Great deals14.99 USD
*/
```
--------------------------------
### Product Availability
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the availability status of a product. It validates against predefined constants and throws an exception for invalid values.
```APIDOC
## `Product::setAvailability(string $availability)`
Sets product availability. Validates against the four allowed constants in `Availability` and throws `InvalidArgumentException` on an invalid value.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Availability\Availability;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
// Constants: IN_STOCK | OUT_OF_STOCK | PREORDER | BACKORDER
$item->setAvailability(Availability::IN_STOCK);
// Dynamic example based on stock level
try {
$item->setAvailability($product->stock > 0 ? Availability::IN_STOCK : Availability::OUT_OF_STOCK);
} catch (InvalidArgumentException $e) {
error_log('Bad availability value: ' . $e->getMessage());
}
```
```
--------------------------------
### Pricing Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the regular and sale prices for a product. The currency code must be appended to the numeric value.
```APIDOC
## `Product` — Pricing Attributes
Sets regular and sale prices. Google requires the currency code appended to the numeric value (e.g., `"19.99 USD"`).
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setPrice('49.99 USD'); // g:price
$item->setSalePrice('34.99 USD'); // g:sale_price
```
```
--------------------------------
### Feed Constructor
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Creates the top-level feed container. An optional RSS version string can be passed as the fourth argument. If omitted, the `` element will not have a `version` attribute.
```APIDOC
## `new Feed($title, $link, $description, $rssVersion = "")`
Creates the top-level feed container. Pass an optional RSS version string (`"2.0"` is most common) as the fourth argument; omitting it produces a `` element with no `version` attribute.
```php
use Vitalybaev\GoogleMerchant\Feed;
// Without RSS version attribute
$feed = new Feed("My Awesome Store", "https://example.com", "Best products online");
// With RSS version 2.0
$feed = new Feed("My Awesome Store", "https://example.com", "Best products online", "2.0");
// Set/change version after construction
$feed->setRssVersion("2.0");
```
```
--------------------------------
### Product Core Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the essential product identifiers, title, description, and URLs required by Google Merchant for product display and indexing.
```APIDOC
## `Product` — Core Identity and Listing Attributes
Sets the required identifiers, title, description, and URLs that Google Merchant uses to display and index a product listing.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setId('SKU-42') // g:id
->setTitle('Acme Running Shoes — Blue, Size 10') // g:title (wrapped in CDATA)
->setDescription('Lightweight mesh upper...') // g:description (CDATA)
->setLink('https://example.com/products/sku-42') // g:link
->setMobileLink('https://m.example.com/p/sku-42'); // g:mobile_link
```
```
--------------------------------
### Set Product Identifiers
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets product identifiers like brand, GTIN, and MPN. The `setIdentifierExists()` method accepts only 'yes' or 'no' and throws an exception for invalid values.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
$item->setBrand('Acme Corp'); // g:brand
$item->setGtin('00012345678905'); // g:gtin (UPC/EAN/ISBN/ITF-14)
$item->setMpn('ACME-RUN-SHOE-BLU-10'); // g:mpn
// For custom/handmade products without standard identifiers:
try {
$item->setIdentifierExists('no'); // g:identifier_exists
} catch (InvalidArgumentException $e) {
error_log($e->getMessage());
}
```
--------------------------------
### Category and Product Type
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Assigns a Google product category and the merchant's own product type path to the product.
```APIDOC
## `Product` — Category and Product Type
Assigns Google's taxonomy category and the merchant's own product type path.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setGoogleCategory('Apparel & Accessories > Shoes'); // g:google_product_category
$item->setProductType('Running > Road Running > Neutral'); // g:product_type
```
```
--------------------------------
### Set Product Condition
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the product condition to 'new', 'refurbished', or 'used' using constants. Throws InvalidArgumentException for invalid values.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Condition;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
try {
$item->setCondition(Condition::NEW_PRODUCT); // 'new'
// $item->setCondition(Condition::REFURBISHED); // 'refurbished'
// $item->setCondition(Condition::USED); // 'used'
} catch (InvalidArgumentException $e) {
error_log($e->getMessage());
}
```
--------------------------------
### Set Product Shipping Dimensions and Labels
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets flat shipping metadata fields including weight, dimensions, and labels. Weights and dimensions must include units as part of the string value.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setShippingWeight('1.5 kg'); // g:shipping_weight
$item->setShippingLength('30 cm'); // g:shipping_length
$item->setShippingWidth('20 cm'); // g:shipping_width
$item->setShippingHeight('10 cm'); // g:shipping_height
$item->setShippingLabel('fragile'); // g:shipping_label
```
--------------------------------
### Product Identifiers
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets product identifiers like Brand, GTIN, MPN, and `identifier_exists`. The `setIdentifierExists()` method accepts only 'yes' or 'no'.
```APIDOC
## `Product` — Identifiers: Brand, GTIN, MPN, and `identifier_exists`
Sets the product identifiers Google uses for catalog matching. `setIdentifierExists()` accepts only `'yes'` or `'no'` and throws `InvalidArgumentException` otherwise.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
$item->setBrand('Acme Corp'); // g:brand
$item->setGtin('00012345678905'); // g:gtin (UPC/EAN/ISBN/ITF-14)
$item->setMpn('ACME-RUN-SHOE-BLU-10'); // g:mpn
// For custom/handmade products without standard identifiers:
try {
$item->setIdentifierExists('no'); // g:identifier_exists
} catch (InvalidArgumentException $e) {
error_log($e->getMessage());
}
```
```
--------------------------------
### Set and Add Generic Product Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Use `setAttribute` to set a specific attribute, overwriting any existing value for that attribute name. Use `addAttribute` to append multiple values for the same attribute name, such as `additional_image_link`. Attribute names are automatically converted to lowercase. Set the third parameter to `true` to wrap the value in CDATA.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
// Set a custom or unsupported attribute
$item->setAttribute('energy_efficiency_class', 'A+');
// Wrap in CDATA
$item->setAttribute('display_ads_title', 'Buy Now — Limited Stock!', true);
// Accumulate multiple values (won't overwrite each other)
$item->addAttribute('additional_image_link', 'https://example.com/img/alt1.jpg');
$item->addAttribute('additional_image_link', 'https://example.com/img/alt2.jpg');
$item->addAttribute('additional_image_link', 'https://example.com/img/alt3.jpg');
```
--------------------------------
### Product Image Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets the primary product image using `setImage()` and adds supplementary images using `addAdditionalImage()`. `setAdditionalImage()` can be used to overwrite a previously set additional image, while `addAdditionalImage()` appends new images, supporting up to 10 additional images as per Google's specifications.
```APIDOC
## `Product::setImage()` and `Product::setAdditionalImage()` / `Product::addAdditionalImage()`
Sets the primary product image and adds supplementary images. `setAdditionalImage()` overwrites any previously set additional image, while `addAdditionalImage()` appends a new `g:additional_image_link` element (Google allows up to 10).
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setImage('https://example.com/images/sku-42-main.jpg');
// Add multiple additional images
$item->addAdditionalImage('https://example.com/images/sku-42-side.jpg');
$item->addAdditionalImage('https://example.com/images/sku-42-back.jpg');
/*
Produces:
https://example.com/images/sku-42-side.jpghttps://example.com/images/sku-42-back.jpg
*/
```
```
--------------------------------
### Product::setShipping and Product::addShipping
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Attaches structured shipping information to a product. `setShipping` overwrites existing rules, while `addShipping` appends new ones for different regions or services.
```APIDOC
## `Product::setShipping(Shipping $shipping)` and `Product::addShipping(Shipping $shipping)`
Attaches a structured `g:shipping` sub-element to a product. Use `setShipping()` to set a single rule (overwrites previous) or `addShipping()` to append multiple shipping rules for different regions or services.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Shipping;
$item = new Product();
// Build a shipping rule
$shipping = new Shipping();
$shipping->setCountry('US') // ISO 3166-1 country code
->setRegion('CA, NSW, 03')
->setPostalCode('94043')
->setLocationId('21137')
->setLocationGroupName('West Coast')
->setService('UPS Express')
->setPrice('5.99 USD');
$item->setShipping($shipping);
// Add a second shipping rule for a different region
$shipping2 = new Shipping();
$shipping2->setCountry('US')
->setRegion('NY')
->setService('FedEx Ground')
->setPrice('7.99 USD');
$item->addShipping($shipping2);
/*
Produces:
USCA, NSW, 03
...
USNY
...
*/
```
```
--------------------------------
### Create a new Google Merchant Feed
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Instantiate the Feed class to create the top-level feed container. You can optionally specify an RSS version.
```php
use Vitalybaev\GoogleMerchant\Feed;
// Without RSS version attribute
$feed = new Feed("My Awesome Store", "https://example.com", "Best products online");
// With RSS version 2.0
$feed = new Feed("My Awesome Store", "https://example.com", "Best products online", "2.0");
// Set/change version after construction
$feed->setRssVersion("2.0");
```
--------------------------------
### Add a Product to the Feed
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Append a Product object to the feed. Products are added in the order they appear in your catalog loop.
```php
use Vitalybaev\GoogleMerchant\Feed;
use Vitalybaev\GoogleMerchant\Product;
$feed = new Feed("My Store", "https://example.com", "Store description");
$item = new Product();
$item->setId('SKU-001')->setTitle('Blue Widget')->setPrice('9.99 USD');
$feed->addProduct($item);
```
--------------------------------
### Feed::build
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Serializes the entire feed into an XML string. The resulting XML can be written to a file, cached for performance, or streamed directly as an HTTP response with the `Content-Type` header set to `application/xml`.
```APIDOC
## `Feed::build()`
Serializes the entire feed to an XML string. The output can be written to a file, cached, or streamed directly as a `text/xml` HTTP response.
```php
use Vitalybaev\GoogleMerchant\Feed;
use Vitalybaev\GoogleMerchant\Product;
$feed = new Feed("My Store", "https://example.com", "Great deals", "2.0");
$item = new Product();
$item->setId('1')->setTitle('Widget')->setPrice('4.99 USD');
$feed->addProduct($item);
$xml = $feed->build();
// Write to file
file_put_contents('/var/www/feeds/google-merchant.xml', $xml);
// Or stream as HTTP response
header('Content-Type: application/xml; charset=utf-8');
echo $xml;
/*
Expected output:
My Store
https://example.com
Great deals14.99 USD
*/
```
```
--------------------------------
### Shipping Dimensions and Labels
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets flat shipping metadata including weight, dimensions, and labels. Units must be included with the values.
```APIDOC
## `Product` — Shipping Dimensions and Labels
Sets flat shipping metadata fields. Weights and dimensions must include units as part of the string value.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setShippingWeight('1.5 kg'); // g:shipping_weight
$item->setShippingLength('30 cm'); // g:shipping_length
$item->setShippingWidth('20 cm'); // g:shipping_width
$item->setShippingHeight('10 cm'); // g:shipping_height
$item->setShippingLabel('fragile'); // g:shipping_label
```
```
--------------------------------
### Set Custom Product Attributes
Source: https://github.com/vitalybaev/php-google-merchant-feed/blob/master/readme.md
Use `setAttribute` to set a specific attribute, replacing any existing value. Use `addAttribute` to append a value to an attribute that can have multiple entries, such as `additional_image_link`.
```php
$product->setAttribute($attributeName, $attributeValue, $isCData = false)
```
```php
$product->addAttribute($attributeName, $attributeValue, $isCData = false)
```
--------------------------------
### Set Product Availability
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets product availability using predefined constants. Throws InvalidArgumentException for invalid values. Can be dynamically set based on stock levels.
```php
use Vitalybaev\GoogleMerchant\Product;
use Vitalybaev\GoogleMerchant\Product\Availability\Availability;
use Vitalybaev\GoogleMerchant\Exception\InvalidArgumentException;
$item = new Product();
// Constants: IN_STOCK | OUT_OF_STOCK | PREORDER | BACKORDER
$item->setAvailability(Availability::IN_STOCK);
// Dynamic example based on stock level
try {
$item->setAvailability($product->stock > 0 ? Availability::IN_STOCK : Availability::OUT_OF_STOCK);
} catch (InvalidArgumentException $e) {
error_log('Bad availability value: ' . $e->getMessage());
}
```
--------------------------------
### Set Product Variant Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets physical variant properties such as color, size, and material. The 'adult' attribute accepts boolean values which are converted to 'yes' or 'no'.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setColor('Midnight Blue'); // g:color
$item->setSize('10 US'); // g:size
$item->setMaterial('Mesh'); // g:material
$item->setAdult(false); // g:adult → 'no'
```
--------------------------------
### Product::setAttribute and Product::addAttribute
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Low-level methods for setting Google Merchant attributes not covered by dedicated setters. `setAttribute` replaces existing values, while `addAttribute` accumulates multiple values under the same tag name. Attribute names are normalized to lowercase.
```APIDOC
## `Product::setAttribute(string $name, $value, bool $isCData = false)` and `Product::addAttribute(string $name, $value, bool $isCData = false)`
Low-level methods for setting any Google Merchant attribute not covered by a dedicated setter. `setAttribute()` replaces any existing value for that name; `addAttribute()` accumulates multiple values under the same tag name (e.g., multiple `additional_image_link` nodes). Attribute names are normalized to lowercase.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
// Set a custom or unsupported attribute
$item->setAttribute('energy_efficiency_class', 'A+');
// Wrap in CDATA
$item->setAttribute('display_ads_title', 'Buy Now — Limited Stock!', true);
// Accumulate multiple values (won't overwrite each other)
$item->addAttribute('additional_image_link', 'https://example.com/img/alt1.jpg');
$item->addAttribute('additional_image_link', 'https://example.com/img/alt2.jpg');
$item->addAttribute('additional_image_link', 'https://example.com/img/alt3.jpg');
```
```
--------------------------------
### Feed::addProduct
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Appends a `Product` item to the feed. This method should be called once for each product in your catalog loop. Products will appear in the XML in the order they are added.
```APIDOC
## `Feed::addProduct(Product $product)`
Appends a `Product` item to the feed. Call this once per product in your catalog loop. Products appear in the XML in the order they were added.
```php
use Vitalybaev\GoogleMerchant\Feed;
use Vitalybaev\GoogleMerchant\Product;
$feed = new Feed("My Store", "https://example.com", "Store description");
$item = new Product();
$item->setId('SKU-001')->setTitle('Blue Widget')->setPrice('9.99 USD');
$feed->addProduct($item);
```
```
--------------------------------
### Set Product Custom Labels for Ad Segmentation
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Assign values to the five available custom label slots (0-4) using `setCustomLabel`. Each slot corresponds to a `g:custom_label_N` element and can be used independently for campaign segmentation in Google Ads.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setCustomLabel('summer-sale', 0); // g:custom_label_0
$item->setCustomLabel('high-margin', 1); // g:custom_label_1
$item->setCustomLabel('clearance', 2); // g:custom_label_2
$item->setCustomLabel('bundle', 3); // g:custom_label_3
$item->setCustomLabel('new-arrival', 4); // g:custom_label_4
```
--------------------------------
### Variant Attributes
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets physical variant properties like color, size, and material, which Google uses to group product variants.
```APIDOC
## `Product` — Variant Attributes
Sets physical variant properties used by Google to group product variants together.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setColor('Midnight Blue'); // g:color
$item->setSize('10 US'); // g:size
$item->setMaterial('Mesh'); // g:material
$item->setAdult(false); // g:adult → 'no'
```
```
--------------------------------
### Product::setCustomLabel
Source: https://context7.com/vitalybaev/php-google-merchant-feed/llms.txt
Sets one of the five available custom label slots (0-4) for campaign segmentation in Google Ads. Each slot corresponds to an independent `g:custom_label_N` element.
```APIDOC
## `Product::setCustomLabel(string $value, int $position)`
Sets one of the five custom label slots (0–4) used for campaign segmentation in Google Ads. Each position is an independent `g:custom_label_N` element.
```php
use Vitalybaev\GoogleMerchant\Product;
$item = new Product();
$item->setCustomLabel('summer-sale', 0); // g:custom_label_0
$item->setCustomLabel('high-margin', 1); // g:custom_label_1
$item->setCustomLabel('clearance', 2); // g:custom_label_2
$item->setCustomLabel('bundle', 3); // g:custom_label_3
$item->setCustomLabel('new-arrival', 4); // g:custom_label_4
```
```
=== COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.