New CRM API
To simplify development all entities in CRM are in progress of continuous upgrade.
This indicates that old kernel class methods
CCrmDeal
: Add, Update, Delete and similar methods in classes \CCrmLead, \CCrmContact, \CCrmCompany
are delegating complete logic for processing to classes of Operation.
Criteria and objectives
During the SPA development process, a corresponding objective was established to wrap it into a general API, which can provide for a convenient handling of not only SPA items, but also elements of any types of entities.
The following criteria were used when designing new API:
- Reduced code duplication.
- Loosened class cohesion.
- Implemented test coverage.
Main objectives were set as follows:
- Increased code quality.
- Reduced number of errors.
- Increased development speed and implementation of new features.
To improve structure of the code, it was decided to split it into services.
Service - is an object, usually, in singular instance, that execute a small-scale dedicated portion of logic.
Services must strictly adhere to the shared responsibility mode. This requires a significant number of them.
Service instances are retrieved via Service\Container
.
Categories
In addition to services, significant amount of auxiliary code was written. Complete code can be separated into several categories:
- Services:
- \Bitrix\Crm\Service\Accounting
- \Bitrix\Crm\Service\Container
- \Bitrix\Crm\Service\Context
- \Bitrix\Crm\Service\Converter
- \Bitrix\Crm\Service\Director
- \Bitrix\Crm\Service\DynamicTypesMap
- \Bitrix\Crm\Service\EditorAdapter
- \Bitrix\Crm\Service\EventHandler
- \Bitrix\Crm\Service\EventHistory
- \Bitrix\Crm\Service\Factory
- \Bitrix\Crm\Service\FileUploader
- \Bitrix\Crm\Service\Localization
- \Bitrix\Crm\Service\ParentFieldManager
- \Bitrix\Crm\Service\Router
- \Bitrix\Crm\Service\Scenario
- \Bitrix\Crm\Service\TypesMap
- \Bitrix\Crm\Service\UserPermissions
- Data access:
- Element operations:
- Interfaces:
Access point when handling new API is Service\Container
.
It produces a required service, with required methods called.
In case of software logic is attached to any specific entity type, access point is Service\Factory
.
Concepts
Below are some basic concepts that must be considered when handling this API.
Developer Experience
Positive Developer Experience was one of focal points during the development.
Set objective was to reduce difficulties with feature introduction and understanding of why one or the other method is being called.
Below are some of specifics applicable to the complete code.
Naming rules
Bitrix24 development team implemented the following naming rules for the new API:
- Base class is located in a "general" namespace. For example,
\Bitrix\Crm\Service\Operation
. - Its descendants are located in the folder with the same name, as the base class. For example,
\Bitrix\Crm\Service\Operation\Add
. - When using the base class implementation, parent namespace is required to be included into the code. For example,
use Bitrix\Crm\Service\Operation; $addOperation = new Operation\Add();
Services
CRM concentrates a lot of features. To reduce cohesion between classes, majority of features was split into services.
Each service solves a specific task or a job. Amount of services is significant, which allows easy handling.
Dedicated business logic
During API design stage, large focus was devoted to layering of classes into three base classes.
- Date.
- Business logic.
- Interfaces.
Classes and methods for handling business logic shall not upload the data. Data must be received in a finalized format, significantly simplifying the process of test coverage.
Unit tests
Class design must envisage testing, thus improving class structure. Availability of tests in itself, speaks to the improved code quality.
Bitrix24 introduced a significant amount of tests for new classes (as well as for some old ones).
Error processing
Majority of methods that execute any updates are returned by the object Bitrix\Main\Result
or its descendants.
This allows to correctly process/show operational errors.
Entities
Presently, the following entities supports the new API:
- leads,
- deals,
- contacts,
- companies,
- estimates,
- new invoices,
- smart activities.
Rollback to legacy API
If you find any incompatibility in operation of your new and legacy API, please contact technical support.
In case of any suspicion of API strange behaviour in adding/updating/deleting deals and other CRM entities, you can return your old behaviour for a specific entity.
Disabling new API for deals from PHP console:
if (\Bitrix\Main\Loader::requireModule('crm')) { \Bitrix\Crm\Settings\DealSettings::getCurrent()->setFactoryEnabled(false); }
In similar manner you can disable new API by clicking a link in browser under any user having access to deals:
{адрес портала}/crm/deal?enableFactory=N
Similarly, new API can be enabled back, if you changed your mind:
if (\Bitrix\Main\Loader::requireModule('crm')) { \Bitrix\Crm\Settings\DealSettings::getCurrent()->setFactoryEnabled(true); }
or
{адрес портала}/crm/deal?enableFactory=Y
All of the above works for leads, deals, contact and companies:
if (\Bitrix\Main\Loader::requireModule('crm')) { // disable new API for deals \Bitrix\Crm\Settings\DealSettings::getCurrent()->setFactoryEnabled(false); // enable it back \Bitrix\Crm\Settings\DealSettings::getCurrent()->setFactoryEnabled(true); // similar for leads // disable \Bitrix\Crm\Settings\LeadSettings::getCurrent()->setFactoryEnabled(false); // enable \Bitrix\Crm\Settings\LeadSettings::getCurrent()->setFactoryEnabled(true); // similar for contacts // disable \Bitrix\Crm\Settings\ContactSettings::getCurrent()->setFactoryEnabled(false); // enable \Bitrix\Crm\Settings\ContactSettings::getCurrent()->setFactoryEnabled(true); // similar for contacts // disable \Bitrix\Crm\Settings\CompanySettings::getCurrent()->setFactoryEnabled(false); // enable \Bitrix\Crm\Settings\CompanySettings::getCurrent()->setFactoryEnabled(true); }
The same as links:
//deals // disable {portal address}/crm/deal?enableFactory=N // enable {portal address}/crm/deal?enableFactory=Y //leads // disable {portal address}/crm/lead?enableFactory=N // enable {portal address}/crm/lead?enableFactory=Y //contacts // disable {portal address}/crm/contact?enableFactory=N // enable {portal address}/crm/contact?enableFactory=Y //companies // disable {portal address}/crm/company?enableFactory=N // enable {portal address}/crm/company?enableFactory=Y
You can check, if new API is enabled by using PHP only:
if (\Bitrix\Main\Loader::includeModule('crm')) { // prints true, if new API is enabled for deals var_dump(\Bitrix\Crm\Settings\DealSettings::getCurrent()->isFactoryEnabled()); //similar for other entities var_dump(\Bitrix\Crm\Settings\LeadSettings::getCurrent()->isFactoryEnabled()); var_dump(\Bitrix\Crm\Settings\ContactSettings::getCurrent()->isFactoryEnabled()); var_dump(\Bitrix\Crm\Settings\CompanySettings::getCurrent()->isFactoryEnabled()); // The same can be checked using the classes \CCrmDeal, \CCrmLead, \CCrmContact, \CCrmCompany $entity = new \CCrmDeal(); var_dump($entity->isUseOperation()); }
Attention!Bitrix24 releases updates and fixes for any discovered incompatibilities on a continuous basis. New API is forcibly enabled on all installations (previously without such API) as soon as all major inconsistencies are fixed. After time time, the option to rollback to an old behaviour will be disabled in Bitrix24.