📜 ⬆️ ⬇️

Bitrix Integration. Implementing a directory with two item group structures

Disclaimer


This article is not a campaign for any CMS, no matter how good or bad it is ...

Prologue


One of the most and first and most common problems that emerges at the beginning of the work on the integration of 1C and online store is the problem of the directory structure. As a rule, the nomenclature structure existing in the customer’s 1C database, to put it mildly, is not ready for export to the site, and the customer is extremely opposed to changing it, because the business process is worked out, everyone is accustomed to such a structure, which is and no one has the slightest desire to change their habits.
What do we usually do in this situation? I think that the same as others, we are creating an alternative structure, all products are tied to it and the new structure is already being uploaded to the site, and the old one remains untouched in 1C base. In the end, everyone is happy. To implement this in conjunction with Bitrix, it is enough to slightly upgrade the unloading that comes in the kit ... *

* - Writing this article was planned before the release of the 12th version of Bitrix and the update of uploading, respectively. Now announced regular functionality to create a directory structure different from that used in the 1C database. Yes, of course, the availability of full-time functionality is great, but still it seems to me that it is not always convenient to configure the structure during the unloading setup, so I would prefer, as before, to implement a separate structure as a separate directory. But this is a matter of situation and taste of everyone ...
')
So, when the problem of structure is caused only by the unwillingness to change the basic structure - we can easily solve the problem by replacing groups. But, what if all the same such hierarchy in the database is not just a whim, but a requirement of a business process? ..

Task


Here once came to us such a task. This time everything is more interesting, the need has been added to link discounts to groups of goods, not to new ones, but to those in the database. For example:

There is the following hierarchy in the database (in the example I selected groups based on the manufacturer, there was no single logic in the real database, for example, part of the groups could be by manufacturer, part by supplier, and part by product type):

  Philips
	 TV P11 - 100 rubles
	 Iron P11 - 50rub
 Samsung
	 S11 TV - 110 rubles
	 Phone S11 - 80rub


The hierarchy in the online store is different:
 Equipment
	 Irons
		 Iron P11
	 TVs
		 TV P11
		 S11 TV
	 Telephones
		 S11 phone


Suppose that counterparty A has a discount on all products of the Philips group - 10%, and on Samsung products - 15%. And counterparty Philips has 20%, and Samsung products 30%.

Then, it turns out that Counterparty A should see the directory like this:
 Equipment
	 Irons
		 Iron P11 - 45rub
	 TVs
		 TV P11 - 90rub
		 TV S11 - 93.5rub
	 Telephones
		 Phone S11 - 68rub


A counterparty B:
 Equipment
	 Irons
		 Iron P11 - 40rub
	 TVs
		 TV P11 - 80rub
		 TV S11 - 77rub
	 Telephones
		 Phone S11 - 56rub


Beatrix has an excellent mechanism for working with discounts, and I would not like to touch him, because these changes would draw a ton of other edits. Yes, of course, theoretically, it would be possible to make discounts not on a group of nomenclature, but on a certain product, but then, when unloading, you have to pull a set of discounts for each product. And now in the database about 10 thousand goods and about a thousand counterparties, each of which can have a couple of dozen unique discounts and also the base is growing, the counterparties are added ... This approach was immediately discarded.
Obviously, the site needs to know both group structures in order to calculate the price based on the first one, and build a directory tree based on the second one.

Decision


To solve, we need a very convenient property of the information block element in Bitrix - “Binding to sections”. And it is convenient because when using the Bitrix API to get the list of elements, the CIBlockElement :: GetList function returns not only the elements that are in this group, but also the elements that are linked through the "Bind to sections" property. It is also interesting that the section of the same information block cannot be selected for the property “Snap to sections”, although at the same time the similar property “Snap to elements” does not impose such restrictions. This immediately suggests that there should be two information blocks in one, the first structure with the elements themselves, and in the second group, alternative groups.
It would seem that everything, the issue is resolved, since everything is provided at the module level, then there should be no further problems, take the group of the second information block as the basis, and pull out the elements of the first one. But it was not there. The regular component of the catalog is not able. A request to the support service confirmed the absence of such an opportunity. But why? After all, there is everything for this, and the necessary property and even the platform itself is sharpened to make such samples, but, alas ...

Yes, of course, no one bothers to make your component and do anything there, but, firstly, it will significantly increase the development time, and therefore cost, and secondly, it was curious what it is in the standard component. It was decided, we will pick the regular catalog and, if possible customizing it, to implement the support of the functionality we need.

To begin with, we create 2 information blocks described above, fill in test information, set up a binding. We should be able to do this:



(in the left part we see two information blocks described above, and on the right are elements of the Phlips section of the first information block)



(and here in the right part we see elements of the Samsung section of the first info block)

If we open the main page of the catalog, we see the sections of our information block:



If you go to the section, for example, TVs, then make sure that it is empty:



So let's start from here. The catalog component used by us is multipage. Inside it consists of a set of one-page components.
Section.php of the main component catalog is responsible for outputting the contents of a specific section. Open it and find the place where the single-page component of bitrix is ​​called: catalog.section. This is a one-page component that lists the elements. Immediately copy it to the custom directory and replace the call with custom: catalog.section.
Open the component.php file, which is responsible for the logic, the component custom: catalog.section. we find an interesting (yes, actually it’s the only one there) API call CIBlockElement :: GetList. We are interested in $ arFilter, because It is this parameter that determines which records will be filtered. Just above we find the place where $ arFilter itself is defined:
$arFilter = array( "IBLOCK_ID" => $arParams["IBLOCK_ID"], "IBLOCK_LID" => SITE_ID, "IBLOCK_ACTIVE" => "Y", "ACTIVE_DATE" => "Y", "ACTIVE" => "Y", "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R", "INCLUDE_SUBSECTIONS" => $arParams["INCLUDE_SUBSECTIO NS"], ); 

The reason why the component does not see our elements is visible - “IBLOCK_ID” => $ arParams [“IBLOCK_ID”]. With this line, we filter out all the elements that are outside our information block, and we have two information blocks, in one element, and in the other sections we need. In principle, it is enough to remove this line, update the TVs section page and we will see that our elements have appeared:



Everything is good, but when we removed the information block filtering, now the GetList function searches for elements of all information blocks, even for those that we don’t need at all, which obviously does not add performance. Therefore, it is best to customize the catalog component itself, add the additional parameter ID_IBLOCK2 to it, transfer it to the custom component: catalog.section. Accordingly, the definition of $ arFilter will look like this:
 $arFilter = array( "IBLOCK_ID" => $arParams["IBLOCK_ID2"], "IBLOCK_LID" => SITE_ID, "IBLOCK_ACTIVE" => "Y", "ACTIVE_DATE" => "Y", "ACTIVE" => "Y", "CHECK_PERMISSIONS" => "Y", "MIN_PERMISSION" => "R", "INCLUDE_SUBSECTIONS" => $arParams["INCLUDE_SUBSECTIONS"], ); 

Everything is now in order with the list of elements, but if we try to open the product card page, for example, TV P11, we will see an error:



Everything is the same here, we have cataloged the catalog.section, and catalog.element is still looking for our product in another info block. Customize it. Find at the very top of the line:
 $arParams["IBLOCK_ID"] = intval($arParams["IBLOCK_ID"]); 

Accordingly, we change it to:
 $arParams["IBLOCK_ID"] = intval($arParams["IBLOCK_ID2"]); 

And success, the product card began to open:



Everything. You can create discounts for groups of the first information block and everything will work when you build the catalog.
The solution was tested on a working site with ~ 10 thousand goods, with three types of prices, 1000 contractors and more than 5 thousand discounts.

Epilogue


We have solved the task with such simple manipulations and implemented interesting functionality, which I think is far from being in demand in our single case ... I don’t see any obstacles to implement this functionality out of the box, but, despite this, alas ...

If it is interesting, I can share other recipes in the following articles that are also not immediately obvious to a person who does not have enough experience working with Beatrix, but are often useful.

P.S


Thank you all for your attention! I will be glad to your comments, questions, discussions.
If you notice a typo or any error, Wellcome to PM;)

Source: https://habr.com/ru/post/159507/


All Articles