Documentation

Data read from various entity type

Quite often, data for different entity types must be read.

Get titles for entity sections (Deals, Leads and etc.)

$descriptions = \CCrmOwnerType::GetAllDescriptions();

// returns "Contact"
$contactDescription = $descriptions[\CCrmOwnerType::Contact];
// the same
//$contactDescription = \CCrmOwnerType::GetDescription(\CCrmOwnerType::Contact);

$categoryDescriptions = \CCrmOwnerType::GetAllCategoryCaptions();
// returns "Contacts"
$contactCategoryDescription = $categoryDescriptions[\CCrmOwnerType::Contact];
// the same
//$contactCategoryDescription = \CCrmOwnerType::GetCategoryCaption(\CCrmOwnerType::Contact);

Get link to list / element

You need to use Service\Router.

Check access permissions

You need to use Service\UserPermissions.

Get title for element of arbitrary type

Method generates element title from several fields depending on entity type.

Do not use this method inside a cycle.

$dealTitle = \CCrmOwnerType::GetCaption(\CCrmOwnerType::Deal, 11);

// title is not escaped!

Get base data about element of arbitrary type

$data = [];

$isCheckAccess = true;

$isLoaded = \CCrmOwnerType::TryGetEntityInfo(\CCrmOwnerType::Order, 22, $data, $isCheckAccess);
if ($isLoaded)
{
    print_r($data);
}

Get base data about element list of arbitrary type

// key - element ID
$data = [
    11 => [],
    13 => [],
    222 => [],
];

$isCheckAccess = true;

\CCrmOwnerType::PrepareEntityInfoBatch(\CCrmOwnerType::Lead, $data, $isCheckAccess);
print_r($data);

Find out the user responsible for an element

$isCheckAccess = true;

// loads the actual responsible user
$responsibleId = \CCrmOwnerType::loadResponsibleId(\CCrmOwnerType::Lead, 11, $isCheckAccess);

// GetResponsibleID - the same, but data is cached

Read arbitrary data

  1. You need to understand that different types of entities has a various sets of fields. By default, the method Service\Factory::getItems() loads all fields, except data of associated collections of contacts and products.
  2. If you need to limit/expand the selection, select for a query must be generated individually, based on entity type.
  3. New API starting from CRM version 21.400.0 supports a full-scale operation with SPAs and quotes.
  4. Support for leads, deals, contacts and companies will be available no later than CRM version 21.800.0.

Let's overview the example having set of element IDs of various types. You need to get information about them, including contact data (multifields).

use Bitrix\Main\Loader;
use Bitrix\Crm\Service;
use Bitrix\Crm\Item;

Loader::includeModule('crm');

$elements = [
	[
		'ENTITY_TYPE_ID' => 1,
		'ENTITY_ID' => 1,
	],
	[
		'ENTITY_TYPE_ID' => 2,
		'ENTITY_ID' => 3,
	],
	[
		'ENTITY_TYPE_ID' => 2,
		'ENTITY_ID' => 5,
	],
	[
		'ENTITY_TYPE_ID' => 3,
		'ENTITY_ID' => 10,
	],
	[
		'ENTITY_TYPE_ID' => 4,
		'ENTITY_ID' => 33,
	],
	[
		'ENTITY_TYPE_ID' => 130,
		'ENTITY_ID' => 10,
	]
];

// source data, grouped by entity type
$typed = [];
foreach ($elements as $element)
{
	$typed[$element['ENTITY_TYPE_ID']][$element['ENTITY_ID']] = $element['ENTITY_ID'];
}
// all contacts IDs
$contactIds = $typed[\CCrmOwnerType::Contact] ?? [];
// all companies IDs
$companyIds = $typed[\CCrmOwnerType::Company] ?? [];
// all contacts IDs
$contacts = [];
// all companies data
$companies = [];
// associations/bindings
$relations = [];
// all entities with multi-fields
$multiFields = [];

$result = [];
foreach ($typed as $entityTypeId => $entityIds)
{
	// first load all types but contacts and companies
	if (
		$entityTypeId === \CCrmOwnerType::Contact
		|| $entityTypeId === \CCrmOwnerType::Company
	)
	{
		continue;
	}
	$factory = Service\Container::getInstance()->getFactory($entityTypeId);
	if (!$factory)
	{
		continue;
	}
	// with access permission check if required
	// $items = $factory->getItemsFilteredByPermissions([
	$items = $factory->getItems([
		'select' => ['*', Item::FIELD_NAME_CONTACT_BINDINGS],
		'filter' => [
			'@ID' => $entityIds,
		],
	]);
	
	foreach ($items as $item)
	{
		$identifier = \Bitrix\Crm\ItemIdentifier::createByItem($item);
		$compatibleData = $item->getCompatibleData();
		$result[$item->getEntityTypeId()][$item->getId()] = $compatibleData;
		foreach ($compatibleData['CONTACT_BINDINGS'] as $contactBinding)
		{
		    // write associated contacts IDs 
			$contactIds[] = $contactBinding['CONTACT_ID'];
			$relations[\CCrmOwnerType::Contact][$contactBinding['CONTACT_ID']][] = $identifier;
		}
		if ($item->hasField(Item::FIELD_NAME_COMPANY_ID))
		{
		    // write associated company ID
			$companyId = (int)$item->getCompanyId();
			if ($companyId > 0)
			{
				$companyIds[] = $companyId;
				$relations[\CCrmOwnerType::Company][$companyId][] = $identifier;
			}
		}
		if ($item->getEntityTypeId() === \CCrmOwnerType::Lead)
		{
			$multiFields[] = [
				'NAME' => \CCrmOwnerType::LeadName,
				'ID' => $item->getId(),
			];
		}
	}
}

\Bitrix\Main\Type\Collection::normalizeArrayValuesByInt($contactIds);
\Bitrix\Main\Type\Collection::normalizeArrayValuesByInt($companyIds);

// load all contacts
if (!empty($contactIds))
{
	$factory = Service\Container::getInstance()->getFactory(\CCrmOwnerType::Contact);
	if (!$factory)
	{
		// no factory sorry
		throw new Exception('factory for ' . \CCrmOwnerType::Contact . ' not found');
	}
	// with access permission check if required
	// $items = $factory->getItemsFilteredByPermissions([
	$items = $factory->getItems([
		'filter' => [
			'@ID' => $contactIds,
		],
	]);
	foreach ($items as $item)
	{
		$compatibleData = $item->getCompatibleData();
		$contacts[$item->getId()] = $compatibleData;
		if (isset($typed[$item->getEntityTypeId()][$item->getId()]))
		{
			$result[$item->getEntityTypeId()][$item->getId()] = $compatibleData;
		}
		$multiFields[] = [
			'NAME' => \CCrmOwnerType::ContactName,
			'ID' => $item->getId(),
		];
	}
}

// load all companies
if (!empty($companyIds))
{
	$factory = Service\Container::getInstance()->getFactory(\CCrmOwnerType::Company);
	if (!$factory)
	{
		// no factory sorry
		throw new Exception('factory for ' . \CCrmOwnerType::Company . ' not found');
	}
	// если нужно с проверкой прав доступа
	// $items = $factory->getItemsFilteredByPermissions([
	$items = $factory->getItems([
		'filter' => [
			'@ID' => $companyIds,
		],
	]);
	foreach ($items as $item)
	{
		$compatibleData = $item->getCompatibleData();
		$companies[$item->getId()] = $compatibleData;
		if (isset($typed[$item->getEntityTypeId()][$item->getId()]))
		{
			$result[$item->getEntityTypeId()][$item->getId()] = $compatibleData;
		}
		$multiFields[] = [
			'NAME' => \CCrmOwnerType::CompanyName,
			'ID' => $item->getId(),
		];
	}
}

// load all contact data and add them to result with account of associations
$filter = \Bitrix\Crm\FieldMultiTable::prepareFilter($multiFields);
$multiFields = \Bitrix\Crm\FieldMultiTable::getList([
	'filter' => $filter,
]);
while ($fieldItem = $multiFields->fetch())
{
	$entityTypeId = \CCrmOwnerType::ResolveID($fieldItem['ENTITY_ID']);
	$itemId = (int)$fieldItem['ELEMENT_ID'];
	if (isset($result[$entityTypeId][$itemId]))
	{
		$result[$entityTypeId][$itemId]['FM'][] = $fieldItem;
	}
	if (isset($relations[$entityTypeId][$itemId]))
	{
		foreach ($relations[$entityTypeId][$itemId] as $identifier)
		{
			$result[$identifier->getEntityTypeId()][$identifier->getEntityId()]['FM'][] = $fieldItem;
		}
	}
}

print_r($result);

Code in this example can be improved; it is left as is for illustration purposes.

It's preferable to wrap it into a class of your choosing.

Get first stage (ignoring access permissions)

Without a pipeline, but with enabled pipeline support, uses default pipeline.
$getFirstStageId = function(int $entityTypeId, int $categoryId = null): ?string
{
    $factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory($entityTypeId);
    if (!$factory || !$factory->isStagesSupported())
    {
        return null;
    }

    $firstStage = $factory->getStages((int)$categoryId)->getAll()[0];

    return $firstStage ? $firstStage->getStatusId() : null;
};

Get first stage with access permissions factored in

.You need to use the method \Bitrix\Crm\Service\UserPermissions::getStartStageId

$getFirstStageIdWithPermissions = function(
    int $entityTypeId, 
    int $userId = null,
    int $categoryId = null, 
    string $operation = \Bitrix\Crm\Service\UserPermissions::OPERATION_READ
): ?string
{
    $factory = \Bitrix\Crm\Service\Container::getInstance()->getFactory($entityTypeId);
    if (!$factory || !$factory->isStagesSupported())
    {
        return null;
    }

    $stages = $factory->getStages((int)$categoryId);

    return \Bitrix\Crm\Service\Container::getInstance()->getUserPermissions($userId)->getStartStageId(
        $entityTypeId,
        $stages,
        (int)$categoryId,
        $operation
    );
};

© «Bitrix24», 2001-2024