CS-Cart allows you to create multiple storefronts and control them from one administration panel. These storefronts work with the same database, but they can have different designs, products, categories, customers, settings, and design.
You can adapt a storefront for a separate target audience. For example, if you sell clothes, you can create a separate storefront with a different design to sell kids clothes only. You can also make a storefront look like an entirely separate store to your customers.
Hint
Watch this video on YouTube to learn more about storefronts.
You can manage your storefronts under Administration → Stores. The main parameters of a storefront are as follows:
CS-Cart uses the following database tables to store the information about storefronts:
The Administration panel has 3 modes of managing objects:
Scripts work faster in the Simple Ultimate mode, because some of the checks to determine the owner of an object are skipped. To separate the logic within the code, the value of Registry::get('runtime.simple_ultimate')
in the Simple Ultimate mode is set to true
.
The value of Registry::get('runtime.company_id')
will be 0 in the All Stores and Simple Ultimate modes. To get the current storefront ID, use Registry::get('runtime.forced_company_id')
.
Some interfaces, like themes, may require the Selected Storefront mode. In this case, the administrator will be offered to choose the storefront.
Objects can be divided in two types: they either have an owner (a specific storefront), or don’t. Below you can the lists of standard CS-Cart objects that have or don’t have an owner. Add-ons may add other objects to either of those lists.
All object tables in the database have the company_id
field that defines the owner storefront of an object. Administrators can access the object in the All Stores mode, or by choosing the owner storefront in the Selected Storefront mode.
You can edit these objects in the All Stores and Simple Ultimate modes only—they are not directly related to storefronts.
CS-Cart has the sharing mechanism to provide access to objects of a storefront from a different storefront. You can have objects specific to one storefront or shared among multiple storefronts.
Important
Only the owner can edit an object. Other storefronts have read access.
There is a schema to describe the objects available for sharing. Here’s an example description:
'shippings' => array(
'controller' => 'shippings',
'api' => 'shippings',
'mode' => 'update',
'type' => 'tpl_tabs',
'params' => array(
'object_id' => '@shipping_id',
'object' => 'shippings'
),
'table' => array(
'name' => 'shippings',
'key_field' => 'shipping_id',
),
'buttons' => array(
'type' => 'save_cancel',
'but_name' => 'dispatch[shippings.update_shipping]',
),
'request_object' => 'shipping_data',
'have_owner' => true,
),
Here’s the schema explained. Required fields are marked with *:
tpl_tabs
is available$_REQUEST
$_REQUEST
; the value of the key will be used to find the current owner storefrontcompany_id
field in the tableCurrently you can share the following objects among storefronts:
Note
Add-ons can extend the sharing schema and add their own objects to it.
The editing pages of the shareable objects have a special Share tab. It will appear depending on the settings specified in the schema. The storefronts listed on the tab will have access to the object. The information about sharing is saved automatically, based on the data from the schema.
Before the query is processed by the current controller, the sharing mechanism intercepts the query and matches it against the schema. If the checks are successful, the mechanism saves the sharing data.
Shared objects are saved in the cscart_ult_objects_sharing table, that has the following fields:
share_company_id
—storefront identifiershare_object_id
—object identifiershare_object_type
—symbol code of the object typeWhen selecting objects described in the schema, the original query will be extended to check the permissions of the current storefront.
Here’s an example of page selection for the storefront with company_id = 3
.
Original query:
SELECT cscart_pages.page_id
FROM cscart_pages
WHERE page_id = 2
Extended query:
SELECT cscart_pages.page_id
FROM cscart_pages
INNER JOIN cscart_ult_objects_sharing ON (
cscart_ult_objects_sharing.share_object_id = cscart_pages.page_id
AND cscart_ult_objects_sharing.share_company_id = 3
AND cscart_ult_objects_sharing.share_object_type = 'pages'
)
WHERE page_id = 2
If the cscart_ult_objects_sharing table doesn’t have the information about the shared page with page_id = 2
, the query will return nothing.
The query extension is done automatically on low level—that way any query made through db_query
can be analyzed and extended. The logic that extends queries is located in the fn_ult_db_query_process function. That function is a processor of the standard db_query_process
hook.
To prevent query extension, you can set the value of the runtime.skip_sharing_selection
in Registry
to true:
Registry::set('runtime.skip_sharing_selection', true);
Debugging tools:
Products are a special type of object—they don’t have their own sharing schema, but they can still be shared among categories. Products are shared via categories: any product can have multiple categories, including those from different storefronts.
You share a product with a storefront by assigning that product to any category of that storefront.
If an object is shared with a storefront, you can change the properties of that object for that specific storefront. This is called redefining values. For example, a product can have different names, descriptions and prices on different storefronts.
This is implemented separately for every object type. Currently you can redefine values for these objects:
You can redefine the values of the following product properties on different storefronts:
The properties available for redefinition are specified in the code. There are no schemas for simple sharing. CS-Cart uses the following tables to save the values:
Every storefront can have its own option variant modifiers. CS-Cart stores them in the cscart_ult_product_option_variants table.
If you edit the values of language variables in the Selected Storefront mode, these values will only be saved for the selected storefront. CS-Cart stores these values in the cscart_ult_language_values table.
The following status fields can have different values for different storefronts:
CS-Cart uses the cscart_ult_status_descriptions to store these values.
fn_get_company_condition
—returns the line, using company_id
as a condition if necessaryfn_ult_get_shared_companies
—returns the identifiers of the storefronts, among which the object is sharedfn_ult_is_shared_product
—checks if a product is shared with this storefrontfn_ult_get_shared_product_companies
—returns the identifiers of the storefront, among which the product is sharedfn_share_object
—shares objects of one storefront with another storefrontfn_share_object_to_all
—shares an object with all storefrontsfn_ult_update_share_object
—shares an object with a specific storefrontThere are two types of settings:
Every setting defines its own type in the edition_type
field of the cscart_settings_objects table. If this field has the line VENDOR
, the setting is store-specific, and its values are saved in the cscart_settings_vendor_values table.
Note
In the Simple Ultimate mode the values of store-specific settings are saved in the cscart_settings_objects table.
You can access the values of the settings for the current storefront from the Registry, for example:
Registry::get('settings.Appearance.frontend_default_language')
Use the Settings
class to manage settings on the code level—this class has all the necessary methods.
Storefronts can use a separate domain or a subfolder of the main domain. This is specified in the Storefront URL and Secure storefront URL (for HTTPS) settings. All the logic that handles defining storefront URLs is located in the fn_init_store_params_by_host function.
For the storefronts to work properly, configure your web server to make index.php process all the requests sent to nonexistent addresses.
CS-Cart comes with the properly configured .htaccess. Make sure to allow its use in the web server settings. This code from the .htaccess file redirects all the necessary queries to index.php:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L,QSA]
When nginx works directly with PHP (FastCGI, php-fpm), configure the redirection rules manually. Here is the part of the configuration file that redirects for nonexistent files and directories to index.php:
location / {
# Redirecting all requests for nonexistent files and directories to index.php
try_files $uri $uri/ /index.php?$args;
}
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php$ {
include fastcgi.conf;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
Questions & Feedback
Have any questions that weren't answered here? Need help with solving a problem in your online store? Want to report a bug in our software? Find out how to contact us.