This is a guide that will help you to adapt your module to X-Cart 5.3 version. Please be sure to apply those changes only on dev copy of your store.
Typical update procedure
Below is the typical update steps a developer needs to perform to update the module for X-Cart 5.3 software. You might need to apply some additional fixes and changes, depending on your module complexity.
(Developer build only) Install composer and call
composer install
in<X-Cart>/src/
in your console, in order to install all required components.Rename each template file extension from .tpl to .twig.
Find all .tpl file path occurrencies in php classes inside
classes/XLite/Module/<DEVNAME>/<MODULENAME>
and replace them with .twig ones.Move template files according to the following scheme:
skins/default/en/
->skins/customer/
skins/admin/en/
->skins/admin/
skins/admin/ru/
->skins/admin_ru/
skins/mail/en/
->skins/mail/common/
skins/admin/en/mail
->skins/mail/admin/
skins/default/en/mail/
->skins/mail/customer/
- the same for ColorSchemes and CustomSkin:
default
should be renamed tocustomer
Use Flexy-to-Twig migration tool to convert each template to Twig-compatible code. Read more about template changes.
Change Main.php
getMajorVersion()
,getMinorVersion()
andgetMinorRequiredCoreVersion()
methods accordingly. AddgetBuildVersion()
method. Read more here about X-Cart 5.3 versioning.Find each
@LC_Dependencies
occurrencies and replace them with@Decorator\Depend
. Note that right syntax is@Decorator\Depend({‘X’, ‘b’})
, not@Decorator\Depend(‘a’, ‘b’)
.Update model files. Ensure that each getter/setter is defined in the code (they are not generated automatically anymore). Apply other needed changes.
Update repository files. Check on the list of all required changes.
Update viewer files. Replace each type occurrence according to the following table:
XLite\Model\WidgetParam\Int
=>XLite\Model\WidgetParam\TypeInt
XLite\Model\WidgetParam\String
=>XLite\Model\WidgetParam\TypeString
XLite\Model\WidgetParam\Checkbox
=>XLite\Model\WidgetParam\TypeCheckbox
XLite\Model\WidgetParam\Object
=>XLite\Model\WidgetParam\TypeObject
XLite\View\FormField\Input\Text\Float
=>XLite\View\FormField\Input\Text\FloatInput
XLite\View\FormField\Input\Base\String
=>XLite\View\FormField\Input\Base\StringInput
XLite\View\FormField\Inline\Input\Text\Float
=>XLite\View\FormField\Inline\Input\Text\FloatInput
Read more about viewer widget changes and apply fixes if needed.
Template changes
Use the our Flexy-to-Twig migration tool to convert your templates in your module.
If you modified templates only by using Webmaster mode or CustomSkin module, follow the steps described below.
- Upgrade your store to X-Cart 5.3;
- Go to Look & Feel > Webmaster mode section in your admin area. If there are any templates, then you will be able to convert them;
- Click on the Flexy-to-twig converter button;
- You will get a list of the files to convert. The first column will show which files will be converted. The second column will show the new location of the converted twig template. The last column will show the status of the file: whether it is converted or not.
- Press Convert button to convert the files. As soon as the files convert you will see the green sign in the right column.
Other changes (apart from the obvious syntactical changes, refer to Twig documentation) that the template designer should know:
- Template file extension is changed from
.tpl
to.twig
. This also affects View classes that define template file names. - The View object that is rendering the template is available via a special this variable. It means that Flexy's
{getProductUrl()}
corresponds to Twig's{{ this.getProductUrl() }}
. In Twig there is a difference between the local variables ({{ product }}
) and the properties/methods of the bound View object ({{ this.product }}
). - Flexy's
<widget class="XLite\View\Widget" param1="value1" param2="value2" />
construct maps to{{ widget('XLite\\View\\Widget', param1='value1', param2='value2') }}
Twig function call. Note the doubled backslashes in class names, these are required in Twig. <widget template="other.tpl" />
converts to a simple template inclusion:{% include 'other.tpl' %}
. All local variables (for example, those that were introduces by a{% for %}
loop) will be available in the included template as a local {{ variable }}. Note that this is different from accessing the View object property:{{ this.variable }}
.- Flexy's
<list name="product.details" param1="value1" param2="value2" />
converts to{{ widget_list('product.details', param1='value1', param2='value2') }}
Twig function call. <widget class="XLite\View\Form\Import" name="importform" /> … <widget name="importform" end />
in Twig is expressed as{% form 'XLite\\View\\Form\\Import' %} … {% endform %}
. The advantage is that Twig checks at template compile time that opening and closing tags are correctly balanced.- Twig function
{{ t('Product name') }}
translates strings just as Flexy's{t(#Product name#)}
. - Twig function
{{ url(...) }}
provides a shortcut toAView::buildURL
.
If some of the widget parameters contain dashes (or other non-alphanumeric and non-underscore characters), Twig will not compile widget function call with such arguments and will throw an error: {{ widget('XLite\\View\\Widget', weird-param-name='value1') }}
. In order to work around this syntax limitation, you can use an alternate widget call syntax: {{ widget('XLite\\View\\Widget', {'weird-param-name': 'value1'}) }}
. However we strongly advise you to use only camel-cased parameter names as this is the recommended naming convention: {{ widget('XLite\\View\\Widget', weirdParamName='value1') }}
The above also applies to widget_list function parameters.
New templates structure
X-Cart 5.3 changed the structure of the templates and you need to make sure that if your module used default templates, that these templates are still in place.
Template files should be moved according to the following scheme:
skins/default/en/
->skins/customer/
skins/admin/en/
->skins/admin/
skins/admin/ru/
->skins/admin_ru/
skins/mail/en/
->skins/mail/common/
skins/admin/en/mail
->skins/mail/admin/
skins/default/en/mail/
->skins/mail/customer/
- the same for ColorSchemes and CustomSkin:
default
should be renamed tocustomer
CustomSkin module has become discontinued as a method to apply changes over any skin, so you need to move files from skins/custom_skin/
folder to skins/theme_tweaker/
. Please note that it will only work for customer
and mail
interface files.
Model changes
If you did not specify getters/setters in your Models, you must define them (they are not added automatically by decorator anymore). You can use
.dev/scripts/doctrine-generate-entities.php
script in order to do that quickly.If your module adds a field with
money
type, then you need to manually add getter and setter for it. See\XLite\Model\Product
class as an example.If your class decorates another one and adds DB table indexes by
@Table(@Index)
directive, then you need to mark your class as@MappedSuperclass
.
Repository changes
Starting from 5.3.x,
XLite/Model/Repo/ARepo
class contains all general methods to search entities, likesearch()
and it doesn't usegetHandlingSearchParams()
method anymore. Therefore you should removesearch()
,searchCount()
,searchResult()
,callSearchConditionHandler()
,isSearchParamHasHandler()
,getHandlingSearchParams()
,prepareCndLimit()
,prepareCndOrderBy()
methods. Define them only to modify the default behaviour.Replace
SEARCH_ORDERBY
andSEARCH_LIMIT
constants withP_ORDER_BY
andP_LIMIT
respectively.Replace all
P_ORDER_BY
usages to the one of the following:$cnd->{static::P_ORDER_BY} = array(static::SORT_BY_MODE_LAST_VISIT_DATE, 'DESC');
$cnd->{static::P_ORDER_BY} = array(
array(Repo::SORT_BY_MODE_ENABLED, 'DESC'),
array(Repo::SORT_BY_MODE_DELAY, 'ASC'),
);If you need the default sort order, add this field to the repo:
protected $defaultOrderBy = array('date' => false); // true means ASC, false means DESC
Replace each
SEARCH_ORDERBY_*
constant with direct field name, prepended by table alias and a dot.
Widget changes
Itemslist widgets were vastly improved to ease their usage. Now you can:
define
getSortByModeDefault()
method, which should return table field to sort by (e.g., 'p.product_id');define
getSortOrderModeDefault()
method to set specific sort order. Return eitherstatic::SORT_ORDER_DESC
orstatic::SORT_ORDER_ASC
;define
$sortByModes
field to provide sorting modes in format of array, where keys are table field names (e.g. 'p.amount') and values are human-readable string name ('Amount');define
defineRepositoryName()
method, which should return repository FQCN (Fully-classified class name);remove some methods because their implementation was moved to abstract
AItemsList
class:getOrderBy()
getSearchCondition()
getSearchParams()
Code changes
Decorators of abstract classes must be explicitly defined as abstract.
Replace
@LC_Dependencies
directive with@Decorator\Depend
. Note that right syntax is@Decorator\Depend({‘a’, ‘b’})
, not@Decorator\Depend(‘a’, ‘b’)
.Change widget types in module settings:
XLite\Model\WidgetParam\Int
=>XLite\Model\WidgetParam\TypeInt
XLite\Model\WidgetParam\String
=>XLite\Model\WidgetParam\TypeString
XLite\Model\WidgetParam\Checkbox
=>XLite\Model\WidgetParam\TypeCheckbox
XLite\Model\WidgetParam\Object
=>XLite\Model\WidgetParam\TypeObject
XLite\View\FormField\Input\Text\Float
=>XLite\View\FormField\Input\Text\FloatInput
XLite\View\FormField\Input\Base\String
=>XLite\View\FormField\Input\Base\StringInput
XLite\View\FormField\Inline\Input\Text\Float
=>XLite\View\FormField\Inline\Input\Text\FloatInput