A situation often arises that it is necessary to extend the functionality of the emarket basket () method, which is responsible for adding an item to the basket. In system version 2.8.4.3 and below, in the method basket the event for customizing this action has not yet been registered, therefore, to solve the problem from our example, we will move the basket method into a custom file.

Task: it is necessary, when adding an item to the cart, to give the buyer a small comment on the item that he will put in the cart; this comment must also be seen in the administrative part when viewing the order parameters. Also, in our new method we will add functionality that will allow us to increase or decrease the quantity of any item in the order by one.

Solution: Let's copy the code of the basket method from the file __purchasing.php, to file classes / modules / emarket / __ custom.php and rename the method to basket_custom... In the new method, the line:

$ order = self :: getBasketOrder (! in_array ($ mode, array ("put", "remove")));

needs to be changed to:

$ order = $ this -> getBasketOrder (! in_array ($ mode, array ("put", "remove")));

After the line:

if ($ itemType == "element") (

$ orderItem -> dop_info = htmlspecialchars (getRequest ("dop_info"));

this code will add the passed value from the field to the order element dop_info.

To configure the functionality of increasing or decreasing the quantity of any item in the order, you must:

after the line:

$ options = getRequest ("options");

add:

$ mode_change = (int) getRequest ("change_item");

and also after the line:

$ amount = $ amount? $ amount: ($ orderItem -> getAmount () + 1);

add:

if ($ mode_change) $ amount = ($ mode_change == 1)? $ orderItem -> getAmount () + 1: $ orderItem -> getAmount () - 1;

Using the TPL template engine as an example, when used in a template tpls / emarket / default.tpl, in the block order_item, links:

+ -

to which you can attach buttons, you can increase or decrease the quantity of any item in the order by one.

array ("basket_custom")); ?>

In the site templates, a form must be created to add a product to the basket, the action of the form, standard, except that instead of the basket method, you must write basket_custom. Also, you need to add input to the form itself:

< input name = "dop_info" style = "width: 100px;" type = "text" />

In the administrative part, in the module Data Templates you need to open the data type for editing Order, get its xml representation by adding at the end of the browser address bar: .xml

In the received data, there will be approximately the following block:

"Order Names" field-type-id = "12" visible = "visible" guide-id = "73"> "Multiple choice dropdown list" data-type = "relation" multiple = "multiple" />

in which guide-id = "73", then open the data type with type_id = 73 for editing, follow the link / admin / data / type_edit / 73 /... Add one more field of the String type to the "Name properties" group, with a string identifier dop_info... To display the saved value, when viewing the order in detail, we will reassign some templates from the file \ styles \ skins \ mac \ data \ modules \ emarket \ order-edit.xsl, to be more precise, we add to the name of the order item, the output of the value from the dop_info field. To implement this part of the order, add the file: \ styles \ skins \ mac \ data \ modules \ emarket \ form.modify.custom.xsl with the following content:

"http://www.w3.org/1999/XSL/Transform" xmlns: xlink = "http://www.w3.org/TR/xlink">
"object" mode = "order-item-name"> "($ lang-prefix) / admin / catalog / edit / (// property / value / page / @ id) /">
"// property [@name =" dop_info "] / value" />

After completing all the described actions, when the buyer adds an order element, he can indicate a short comment to the added product, and the store administrator, when viewing the order in detail, will be able to read this comment.

Actually, the question is about the implementation of the store and how I will evaluate it.

First, let's take a look at a real store, how it works, what functions are implemented there and its cost.

And so an online store on Bitrix can be implemented on 2 editions, this is a small business and a business.

What is the main difference for a store?

1. There is no advertising module - the expediency of this module can be questioned; it can be implemented on infoblocks and it will work quickly and well, and the module itself is heavy, in some cases it is not at all expedient

2. The online store module itself differs in that in business there are no restrictions on the number of prices for a product, and there are no kits and kits, in a small business there is only one warehouse, there are no affiliates (a controversial question whether it is necessary in most cases) and the rest of electronic content cannot be sold works in the editorial offices of stores in the same way.

What we have, Bitrix is ​​fully integrated with 1C, small business is good if there are no warehouses and different prices, for example, wholesale and for goods. Business is a monstrous shop that is ready for any enterprise.

And the price: 9,000 and 19,000, the difference is palpable.

The start costs 1 400 i.e. sobsvenno other additions 7,600 and 17,600, respectively.

On average, at the labor exchange, the work of a programmer in php is $ 5-10 per hour, i.e. 130 UAH - 260 UAH 58 and 29 hours, respectively, i.e. with normal working hours a day 4-7 days. Is it real?

Let's figure out what needs to be implemented first.

1. Product catalog

2. Basket

2.1. Discounts

3. Checkout

3.1. Payment Methods

3.2. Delivery methods

Well, let's simplify for a start:

Bitrix start

Any correct development in Bitrix begins with a separate module in which everything will be stored and not interfere with everything else.

The development of an online store module begins with a standard "empty module"

create a folder local in the root of the site and create a folder in it modules / NAMESPACE in my case it will be binliz.sale in order for Bitrix to determine that this is a module, you need to create a couple of daddies and files, this is all written in the Bitrix course, but I will write exactly what I am doing

create a folder install, files install / index.php, include.php, options.php

/ ** * User: binliz * / use Bitrix \ Main \ Localization \ Loc; Loc :: loadMessages (__ FILE__); if (class_exists ("binliz_sale")) (return;) class binliz_sale extends CModule (public $ MODULE_ID = "binliz.sale"; public $ MODULE_VERSION = "0.1"; public $ MODULE_VERSION_DATE = "2016-09-19"; public $ MODULE_NAME = "Module binliz sale"; public $ MODULE_DESCRIPTION = "The store module is used for auto-connecting classes. Uses the D7 engine."; Public $ MODULE_GROUP_RIGHTS = "N"; public $ PARTNER_NAME = "binliz"; public $ PARTNER_URI = "http: // site "; public function DoInstall () (global $ APPLICATION; RegisterModule ($ this-> MODULE_ID);) public function DoUninstall () (global $ APPLICATION; UnRegisterModule ($ this-> MODULE_ID);))

That's all, let's go to Desktop> Marketplace> Installed Solutions and install our module, we will often install and install this to know for sure that our module will unfold out of the box.

The first thing that we need to organize is the ability to create a directory in the admin panel, for convenience we will make it the same as for Bitrix i.e. without inventing a new structure - we will add our own tabs with the trade catalog to the infoblock elements.

How do you organize this? First, let's try to create a table in which we will store our infoblocks, which will become catalogs.

CREATE TABLE `b_binliz_sale_catalog` (` ID` int (11) NOT NULL, `IBLOCK_ID` int (11) NOT NULL,` OFFER_IBLOCK_ID` int (11) NOT NULL, `IS_CATALOG` int (1) NOT NULL,` IS_OFFERS` int (1) NOT NULL) ENGINE = InnoDB DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci; ALTER TABLE `b_binliz_sale_catalog` ADD PRIMARY KEY (` ID`), ADD UNIQUE KEY `IBLOCK_ID` (` IBLOCK_ID`), ADD UNIQUE KEY `OFFER_IBLOCK_ID` (` OFFER_IBLOCK_ID`); ALTER TABLE `b_binliz_sale_catalog` MODIFY` ID` int (11) NOT NULL AUTO_INCREMENT;

Let's create a view of this table in ORM, create a lib folder and put the file in it salecatalog.php

Namespace Binliz \ Sale; use Bitrix \ Main, Bitrix \ Main \ Localization \ Loc; Loc :: loadMessages (__ FILE__); / ** * Class SaleCatalogTable * * @package Binliz \ Sale ** / class SaleCatalogTable extends Main \ Entity \ DataManager (/ ** * Returns DB table name for entity. * * @Return string * / public static function getTableName () ( return "b_binliz_sale_catalog";) / ** * Returns entity map definition. * * @return array * / public static function getMap () (return array ("ID" => array ("data_type" => "integer", "primary "=> true," autocomplete "=> true," title "=> Loc :: getMessage (" SALE_CATALOG_ENTITY_ID_FIELD "),)," IBLOCK_ID "=> array (" data_type "=>" integer "," required "=> true, "title" => Loc :: getMessage ("SALE_CATALOG_ENTITY_IBLOCK_ID_FIELD"),), "OFFER_IBLOCK_ID" => array ("data_type" => "integer", "required" => true, "title" => Loc :: getMessage ("SALE_CATALOG_ENTITY_OFFER_IBLOCK_ID_FIELD"),), "IS_CATALOG" => array ("data_type" => "integer", "required" => true, "title" => Loc :: getMessage ("SALE_CATALOG_ENTITY_ISEL_CATALOG) IS_OFFERS "=> array (" data_type "=>" intege r "," required "=> true," title "=> Loc :: getMessage (" SALE_CATALOG_ENTITY_IS_OFFERS_FIELD "),),); ))

And you can put in the prinitsy and localization lang / ru / lib / salediscount.php

$ MESS ["SALE_CATALOG_ENTITY_ID_FIELD"] = ""; $ MESS ["SALE_CATALOG_ENTITY_IBLOCK_ID_FIELD"] = ""; $ MESS ["SALE_CATALOG_ENTITY_OFFER_IBLOCK_ID_FIELD"] = ""; $ MESS ["SALE_CATALOG_ENTITY_IS_CATALOG_FIELD"] = ""; $ MESS ["SALE_CATALOG_ENTITY_IS_OFFERS_FIELD"] = "";

until I redefined anything, just put the file, the plate was created, it's time to create a tab and set methods for working with it, since we have Bitrix, it has an event system the best and correct way is to organize classes that will be hung on these very events and solve our problems , for this I preferred to be guided by the principle of one class, one solution and the constructor itself the definition of what we are hanging on. The first step is to solve the problem of defining directories. To do this, we need to create a tab in the information block editing section in which there will be our check mark that this is a directory and while this is enough we will not bother until we can do it later with trade offers. Let's create an abstract class for events in which we will create an array passing the following data:

the module we are hanging on, the event, and the class method that is responsible for this. To do this, in the lib folder, create the events folder and put our events there. And so is the abstract class.

Namespace Binliz \ Sale \ Events; abstract class Base (protected $ eventlist =; public final function __construct () ($ eventManager = \ Bitrix \ Main \ EventManager :: getInstance (); foreach ($ this-> eventlist as $ event) ($ eventMethods = get_called_class (). "::". $ event ["method"]; $ eventManager-> addEventHandler ($ event ["module"], $ event ["event"], $ eventMethods);)))

And a class for working with an infoblock:

Namespace Binliz \ Sale \ Events; class SaleCatalogIblockEdit extends Base (protected $ eventlist = [["module" => "main", "event" => "onAdminTabControlBegin", "method" => "onAdminTabControlBegin"], ["module" => "iblock", " event "=>" onAfterIblockAdd "," method "=>" onAdminIblock "], [" module "=>" iblock "," event "=>" onAfterIblockUpdate "," method "=>" onAdminIblock "], [" module "=>" iblock "," event "=>" OnIBlockDelete "," method "=>" onAdminIblockDelete "],]; static public function getApp () ($ application = \ Bitrix \ Main \ Application :: getInstance (); $ context = $ application-> getContext (); $ request = $ context-> getRequest (); $ uri = $ request-> getRequestedPage (); return array ("application" => $ application, "context" => $ context, "request" => $ request, "uri" => $ uri);) public function onAdminTabControlBegin (& $ form) ($ ells = self :: getApp (); if ($ ells ["uri"] == "/bitrix/admin/iblock_edit.php") (if ($ ells ["request"] -> getQuery ("ID")> 0) $ results = \ Binliz \ Sale \ SaleCatalogTable :: GetByIblock ($ ells ["request "] -> getQuery (" ID ")); ob_start (); include (__ DIR __." / temp lates / iblock_edit.php "); $ str = ob_get_contents (); ob_end_clean (); $ form-> tabs = array ("DIV" => "BINLIZ_SALE_CATALOG", "TAB" => "Trade directory Binliz.Sale", "ICON" => "main_user_edit", "TITLE" => "Settings directory", " CONTENT "=> $ str); )) public function onAdminIblock ($ arFields) ($ ells = self :: getApp (); file_put_contents (__ DIR __. "/ fields.txt", var_export (array ($ arFields, $ ells ["request"] -> getPostList () , $ ells ["request"] -> getPost ("IS_BINLIZ_CATALOG")), 1)); if ($ arFields ["RESULT"]! = false) ($ ID = $ arFields ["ID"]; $ fields = ["IBLOCK_ID" => $ ID, "IS_CATALOG" => $ ells ["request"] -> getPost ("IS_BINLIZ_CATALOG") == "Y"? 1: 0]; \ Binliz \ Sale \ SaleCatalogTable :: AddByIblock ( $ ID, $ fields);)) public function onAdminIblockDelete ($ ID) (\ Binliz \ Sale \ SaleCatalogTable :: DeleteByIblock ($ ID);))

Let's add our functions to the table model accordingly:

Public function GetByIblock ($ IBLOCK_ID) ($ query = new \ Bitrix \ Main \ Entity \ Query (self :: getEntity ()); $ query-> setSelect (array ("*")); $ query-> setFilter (array ("= IBLOCK_ID" => $ IBLOCK_ID)); $ result = $ query-> exec (); $ ells = $ result-> fetch (); if (isset ($ ells ["ID"])) return $ ells ; else return false;) public function AddByIblock ($ IBLOCK_ID, $ arFields) ($ query = new \ Bitrix \ Main \ Entity \ Query (self :: getEntity ()); $ query-> setSelect (array ("IBLOCK_ID", "ID")); $ query-> setFilter (array ("= IBLOCK_ID" => $ IBLOCK_ID)); $ result = $ query-> exec (); $ ells = $ result-> fetch (); if (isset ($ ells ["ID"])) self :: Update ($ ells ["ID"], $ arFields); else $ res = self :: Add ($ arFields);) public function DeleteByIblock ($ IBLOCK_ID) ($ query = new \ Bitrix \ Main \ Entity \ Query (self :: getEntity ()); $ query-> setSelect (array ("IBLOCK_ID", "OFFER_IBLOCK_ID", "ID", "IS_CATALOG", "IS_OFFERS")); $ query-> setFilter (array ("= IBLOCK_ID" => $ IBLOCK_ID)); $ result = $ query-> exec (); $ ells = $ result-> fetch (); if (isset ($ ells ["ID "]) && $ ells ["OFFER_IBLOCK_ID"] == null) (self :: Delete ($ ells ["ID"]); return true;))

And the template file with a check mark that we output:

Hurray, so we got a working checkbox that determines whether we have a directory or not.

The contents of the include scopes are stored in separate PHP or HTML files. Areas for pages or sections are saved with some suffix. For example, the shipped product files use the suffix _inc(For example, index_inc.php), and the include area for the site section is saved in a file named sect and adding a suffix to it (for example, sect_inc.php).

Important! The file with the include area must be saved in the same directory as the page for which it was created. The include area for a section is in the folder of that section.

The connection of areas in the site design template is performed using the component Inserting an include area or using a function.

The suffix used to designate the included areas is determined by the option of the same name in the component settings Inserting an include area... A component can be placed not only in a design template, but also on site pages, provided that the file suffix must be different from the one used in the template.

One component can only be configured for one of the above display options. In addition, they may be displayed on the pages of the site in accordance with any other conditions. For example, only on the main page of the site or only for authorized visitors, etc.

Note: defined by option Show include area.

If the component is located in the site design template, then the information from file will be displayed on the entire site. Setting the parameter is available only to a user with the rights edit_php.

Placing an include area

To place the include area, do the following:

  • Open the site template or page for editing in a visual editor.
  • Add component Inserting an include area (bitrix: main.include) into the site template (or into the body of the page) and configure its parameters.

The use of include areas when integrating into a design has a limitation. It is related to the size reserved for the cell in which the component is placed. If the entered text, picture, or something else is larger in size than the place assigned to the component, then the design will "go", that is, it will be distorted.

Using include scopes allows you to control more than just text. You can put a picture in this area instead of text (or a component Random photo) and get an individual view of each section. In this case, the individuality will be "dynamic", changeable.

Create and edit an include area

The creation of include areas can be done:


Similarly, you can proceed to editing the included areas:


Attention! If you are going to use the option from file, then you need to check that the file is connected from the system, and not called directly. This is done with the following line:
.

An example of the contents of the include file:

World Book
All the books of the world


Include scopes templates

Included scopes are created from templates stored in folders named / page_templates /:

  • /bitrix/templates/.default/page_templates/ - if this include area template is used for all site design templates;
  • / bitrix / templates /<идентификатор шаблона>/ page_templates / - if separate include area templates are used for the site template.

In order to be able to select a template in the visual editor on the basis of which an editable region is created, a list of templates for editable regions must be added to the file .content.php.

File .content.php stored in the / page_templates / folder in the directory of the corresponding site template.

Sample file content:

GetMessage ("standart"), "sort" => 1); $ TEMPLATE ["page_inc.php"] = Array ("name" => GetMessage ("page_inc"), "sort" => 2); $ TEMPLATE ["sect_inc.php"] = Array ("name" => GetMessage ("sect_inc"), "sort" => 3); ?>

Please note that the template name can be passed as a parameter when connecting the editable area in the site template ("TEMPLATE" => "page_inc.php" in the example below).


If you connect editable areas using PHP function IncludeFile () placed in the appropriate places in the design template, then the code can look like this:

$ APPLICATION-> IncludeFile (substr ($ APPLICATION-> GetCurPage (),
0, strlen ($ APPLICATION-> GetCurPage ()) - 4). "_ Inc.php", Array (),
Array ("MODE" => "html", "NAME" => GetMessage ("PAGE_INC"), "TEMPLATE" => "page_inc.php"));
?>
$ APPLICATION->
IncludeFile ($ APPLICATION-> GetCurDir (). "Sect_inc.php", Array (), Array ("MODE" => "html",
"NAME" => GetMessage ("SECT_INC"), "TEMPLATE" => "sect_inc.php"));
?>