Introduction

This guide teaches X-Cart developers how they can add their own field to products and then use it on invoices.

Table of Contents

Implementation

First of all, create a new module. We are creating a module with developer ID Tony and module ID ProductFieldDemo.

Adding new field to product model

Decorate the \XLite\Model\Product class (more info about X-Cart classnames). We are creating the <X-Cart>/classes/XLite/Module/Tony/ProductFieldDemo/Model/Product.php file with the following content: 

<?php
// vim: set ts=4 sw=4 sts=4 et:

namespace XLite\Module\Tony\ProductFieldDemo\Model;

class Product extends \XLite\Model\Product implements \XLite\Base\IDecorator
{
	/**
	 * @Column (type="string", length=32)
	 */
	protected $testField;
}

Here protected $testField says that now product objects will have a new property that can be accessed like $product->testField.

/**
 * @Column (type="string", length=32)
 */

This line of the code specifies parameters of this field, i.e. that this field is a string and can be up to 32 symbols.

That is it. If we re-deploy the store right now, X-Cart will create a new field in the database according to our parameters we specified. Do not initiate store re-deployment right now though.

Creating interface for editing this field

Now we need to be able to specify value of this property on product details page in admin area. We decorate \XLite\View\Model\Product class and create <X-Cart>/classes/XLite/Module/Tony/ProductFieldDemo/View/Model/Product.php file with the following content: 

<?php
// vim: set ts=4 sw=4 sts=4 et:

namespace XLite\Module\Tony\ProductFieldDemo\View\Model;

class Product extends \XLite\View\Model\Product implements \XLite\Base\IDecorator
{
	public function __construct(array $params = array(), array $sections = array())
    {
        parent::__construct($params, $sections);

        $this->schemaDefault += array (
        	'testField' => array(
            	self::SCHEMA_CLASS    => 'XLite\View\FormField\Input\Text',
            	self::SCHEMA_LABEL    => 'Test field',
            	self::SCHEMA_REQUIRED => false,
            	),
        	);
    }
}

Such code will add a new field to the product details page in admin area. This field will be named Test field and its value will be saved into testField field of xc_products MySQL table. The FormField class that defines an input field in the interface is default \XLite\View\FormField\Input\Text one.

Note: see an example of creating model editing form with more detailed explanation here: Model editing page.

Showing this field value on thank you page

Finally, we need to display the value of this field on thank you page after the order is placed. It should be displayed like this:

In order to achieve it, we create the <X-Cart>/skins/default/en/modules/Tony/ProductFieldDemo/item.test-field.tpl template with the following content: 

{* vim: set ts=2 sw=2 sts=2 et: *}
{**
 * @ListChild (list="invoice.item.name", weight="20")
 *}
<li class="test-field">
  <span class="name">{t(#Test field#)}</span>
  <span class="test-field-value">{item.product.getTestField()}</span>
</li>

In this template, we tell template to be registered in the invoice.item.name view list (more about template system in X-Cart).

Another important part is that we just call value of testField property as item.product.getTestField(), even though we did not declare getTestField() method in the \XLite\Model\Product. X-Cart creates get{PropertyName}() methods for each property automatically, if it is not declared explicitly.

Checking the results

Now we need to re-deploy the store and after it is finished, we go to any product in admin area and we will be able to see our new field there: 

Define it as you wish, then add this product to cart in customer zone and place an order with it. You will see a thank you page with this field’s value there:

Module pack

You can download this module from here: https://dl.dropboxusercontent.com/u/23858825/Tony-ProductFieldDemo-v5_1_0.tar