Your IP : 3.142.119.68
<?php
namespace Bitrix\Crm\Recycling;
use Bitrix\Main;
use Bitrix\Crm;
Main\Localization\Loc::loadMessages(__FILE__);
class ContactController extends BaseController
{
use MultiFieldControllerMixin {
recoverMultiFields as innerRecoverMultiFields;
}
use ActivityControllerMixin;
use AddressControllerMixin;
use RequisiteControllerMixin;
/** @var ContactController|null */
protected static $instance = null;
/**
* @return ContactController|null
*/
public static function getInstance()
{
if(self::$instance === null)
{
self::$instance = new ContactController();
}
return self::$instance;
}
public static function getFieldNames()
{
return array(
'ID',
'DATE_CREATE', 'DATE_MODIFY', 'CREATED_BY_ID', 'MODIFY_BY_ID',
'ASSIGNED_BY_ID', 'PHOTO', 'ADDRESS', 'EXPORT', 'OPENED',
'LEAD_ID', 'COMPANY_ID', 'TYPE_ID', 'SOURCE_ID', 'SOURCE_DESCRIPTION',
'HONORIFIC', 'NAME', 'LAST_NAME', 'SECOND_NAME', 'BIRTHDATE', 'POST', 'COMMENTS',
'WEBFORM_ID', 'FACE_ID', 'ORIGINATOR_ID', 'ORIGIN_ID', 'ORIGIN_VERSION'
);
}
/**
* Get Entity Type ID
* @return int
*/
public function getEntityTypeID()
{
return \CCrmOwnerType::Contact;
}
/**
* Get Suspended Entity Type ID
* @return int
*/
public function getSuspendedEntityTypeID()
{
return \CCrmOwnerType::SuspendedContact;
}
/**
* Get recyclebin entity type name.
* @see \Bitrix\Crm\Integration\Recyclebin\Contact::getEntityName
* @return string
*/
public function getRecyclebinEntityTypeName()
{
return 'crm_contact';
}
public function getActivityOwnerNotFoundMessage($entityTypeID, $entityID, array $params)
{
$entityTitle = Crm\Integration\Recyclebin\RecyclingManager::resolveEntityTitle(
\CCrmOwnerType::Contact,
$entityID
);
return Main\Localization\Loc::getMessage(
'CRM_CONTACT_CTRL_ACTIVITY_OWNER_NOT_FOUND',
[
'#OWNER_TITLE#' => $entityTitle,
'#OWNER_ID#' => $entityID,
'#ID#' => isset($params['ID']) ? $params['ID'] : '',
'#TITLE#' => isset($params['title']) ? $params['title'] : ''
]
);
}
public function getEntityFields($entityID)
{
$dbResult = \CCrmContact::GetListEx(
array(),
array('=ID' => $entityID, 'CHECK_PERMISSIONS' => 'N'),
false,
false,
array('*')
);
$fields = $dbResult->Fetch();
return is_array($fields) ? $fields : null;
}
public function prepareEntityData($entityID, array $params = array())
{
$fields = isset($params['FIELDS']) && is_array($params['FIELDS']) ? $params['FIELDS'] : null;
if(empty($fields))
{
$fields = $this->getEntityFields($entityID);
}
if(empty($fields))
{
throw new Main\ObjectNotFoundException("Could not find entity: #{$entityID}.");
}
$slots = array('FIELDS' => array_intersect_key($fields, array_flip(self::getFieldNames())));
if(isset($fields['LEAD_ID']) && $fields['LEAD_ID'] > 0)
{
$slots['PARENT_LEAD_ID'] = (int)$fields['LEAD_ID'];
}
$companyIDs = Crm\Binding\ContactCompanyTable::getContactCompanyIDs($entityID);
if(!empty($companyIDs))
{
$slots['COMPANY_IDS'] = $companyIDs;
}
$leadIDs = Crm\Binding\LeadContactTable::getContactLeadIDs($entityID);
if(!empty($leadIDs))
{
$slots['LEAD_IDS'] = $leadIDs;
}
$dealIDs = DealBinder::getInstance()->getBoundEntityIDs(\CCrmOwnerType::Contact, $entityID);
if(!empty($dealIDs))
{
$slots['DEAL_IDS'] = $dealIDs;
}
$quoteIDs = QuoteBinder::getInstance()->getBoundEntityIDs(\CCrmOwnerType::Contact, $entityID);
if(!empty($quoteIDs))
{
$slots['QUOTE_IDS'] = $quoteIDs;
}
$invoiceIDs = InvoiceBinder::getInstance()->getBoundEntityIDs(\CCrmOwnerType::Contact, $entityID);
if(!empty($invoiceIDs))
{
$slots['INVOICE_IDS'] = $invoiceIDs;
}
$requisiteLinks = Crm\EntityRequisite::getLinksByOwner(\CCrmOwnerType::Contact, $entityID);
if(!empty($requisiteLinks))
{
$slots['REQUISITE_LINKS'] = $requisiteLinks;
}
$slots = array_merge($slots, $this->prepareActivityData($entityID, $params));
return array(
'TITLE' => \CCrmOwnerType::GetCaption(
\CCrmOwnerType::Contact,
$entityID,
false,
array('FIELDS' => $fields)
),
'SLOTS' => $slots
);
}
/**
* Move entity to Recycle Bin.
* @param int $entityID Entity ID.
* @param array $params Additional operation parameters.
* @return void
* @throws Crm\Synchronization\UserFieldSynchronizationException
* @throws Main\ArgumentException
* @throws Main\ArgumentOutOfRangeException
* @throws Main\Db\SqlQueryException
* @throws Main\InvalidOperationException
* @throws Main\LoaderException
* @throws Main\ObjectException
* @throws Main\ObjectNotFoundException
* @throws Main\SystemException
*/
public function moveToBin($entityID, array $params = array())
{
if(!Main\Loader::includeModule('recyclebin'))
{
throw new Main\InvalidOperationException("Could not load module RecycleBin.");
}
$fields = isset($params['FIELDS']) && is_array($params['FIELDS']) ? $params['FIELDS'] : null;
if(empty($fields))
{
$fields = $params['FIELDS'] = $this->getEntityFields($entityID);
}
if(empty($fields))
{
throw new Main\ObjectNotFoundException("Could not find entity: #{$entityID}.");
}
$entityData = $this->prepareEntityData($entityID, $params);
$recyclingEntity = Crm\Integration\Recyclebin\Contact::createRecycleBinEntity($entityID);
$recyclingEntity->setTitle($entityData['TITLE']);
$slots = isset($entityData['SLOTS']) && is_array($entityData['SLOTS']) ? $entityData['SLOTS'] : array();
$relations = ContactRelationManager::getInstance()->buildCollection($entityID, $slots);
foreach($slots as $slotKey => $slotData)
{
$recyclingEntity->add($slotKey, $slotData);
}
//region Files
if(isset($fields['PHOTO']) && $fields['PHOTO'] > 0)
{
$recyclingEntity->addFile($fields['PHOTO'], Crm\Integration\StorageType::FileName);
}
//endregion
$result = $recyclingEntity->save();
$errors = $result->getErrors();
if(!empty($errors))
{
throw new Main\SystemException($errors[0]->getMessage(), $errors[0]->getCode());
}
$recyclingEntityID = $recyclingEntity->getId();
//region Convert User Fields to Suspended Type
$suspendedUserFields = $this->prepareSuspendedUserFields($entityID);
if(!empty($suspendedUserFields))
{
$this->saveSuspendedUserFields($recyclingEntityID, $suspendedUserFields);
}
//endregion
if(isset($slots['QUOTE_IDS']) && is_array($slots['QUOTE_IDS']))
{
QuoteBinder::getInstance()->unbindEntities(\CCrmOwnerType::Contact, $entityID, $slots['QUOTE_IDS']);
}
if(isset($slots['INVOICE_IDS']) && is_array($slots['INVOICE_IDS']))
{
InvoiceBinder::getInstance()->unbindEntities(\CCrmOwnerType::Contact, $entityID, $slots['INVOICE_IDS']);
}
$this->suspendActivities($entityData, $entityID, $recyclingEntityID);
$this->suspendMultiFields($entityID, $recyclingEntityID);
$this->suspendAddresses($entityID, $recyclingEntityID);
$this->suspendTimeline($entityID, $recyclingEntityID);
$this->suspendDocuments($entityID, $recyclingEntityID);
$this->suspendLiveFeed($entityID, $recyclingEntityID);
$this->suspendRequisites($entityID, $recyclingEntityID);
$this->suspendUtm($entityID, $recyclingEntityID);
$this->suspendTracing($entityID, $recyclingEntityID);
//region Relations
foreach($relations as $relation)
{
/** @var Relation $relation */
$relation->setRecycleBinID(\CCrmOwnerType::Contact, $entityID, $recyclingEntityID);
$relation->save();
}
ContactRelationManager::getInstance()->registerRecycleBin($recyclingEntityID, $entityID, $slots);
//endregion
}
/**
* Recover entity from Recycle Bin.
* @param int $entityID Entity ID.
* @param array $params Additional operation parameters.
* @return bool
* @throws Crm\Synchronization\UserFieldSynchronizationException
* @throws Main\AccessDeniedException
* @throws Main\ArgumentException
* @throws Main\ArgumentOutOfRangeException
* @throws Main\ArgumentTypeException
* @throws Main\Db\SqlQueryException
* @throws Main\InvalidOperationException
* @throws Main\LoaderException
* @throws Main\NotSupportedException
* @throws Main\ObjectException
* @throws Main\ObjectNotFoundException
* @throws Main\ObjectPropertyException
* @throws Main\SystemException
*/
public function recover($entityID, array $params = array())
{
if($entityID <= 0)
{
return false;
}
$recyclingEntityID = isset($params['ID']) ? (int)$params['ID'] : 0;
if($recyclingEntityID <= 0)
{
return false;
}
$slots = isset($params['SLOTS']) ? $params['SLOTS'] : null;
if(!is_array($slots))
{
return false;
}
$fields = isset($slots['FIELDS']) ? $slots['FIELDS'] : null;
if(!(is_array($fields) && !empty($fields)))
{
return false;
}
unset($fields['ID'], $fields['COMPANY_ID'], $fields['COMPANY_IDS'], $fields['LEAD_ID']);
$relationMap = RelationMap::createByEntity(\CCrmOwnerType::Contact, $entityID, $recyclingEntityID);
$relationMap->build();
ContactRelationManager::getInstance()->prepareRecoveryFields($fields, $relationMap);
//region Convert User Fields from Suspended Type
$userFields = $this->prepareRestoredUserFields($recyclingEntityID);
if(!empty($userFields))
{
$fields = array_merge($fields, $userFields);
}
//endregion
$entity = new \CCrmContact(false);
$newEntityID = $entity->Add(
$fields,
true,
array(
'IS_RESTORATION' => true,
'DISABLE_USER_FIELD_CHECK' => true
)
);
if($newEntityID <= 0)
{
return false;
}
//region Relations
ContactRelationManager::getInstance()->recoverBindings($newEntityID, $relationMap);
Relation::updateEntityID(\CCrmOwnerType::Contact, $entityID, $newEntityID, $recyclingEntityID);
//endregion
$quoteIDs = isset($slots['QUOTE_IDS']) ? $slots['QUOTE_IDS'] : null;
if(is_array($quoteIDs))
{
QuoteBinder::getInstance()->bindEntities(
\CCrmOwnerType::Contact,
$newEntityID,
Crm\Entity\Quote::selectExisted($quoteIDs)
);
}
$invoiceIDs = isset($slots['INVOICE_IDS']) ? $slots['INVOICE_IDS'] : null;
if(is_array($invoiceIDs) && !empty($invoiceIDs))
{
InvoiceBinder::getInstance()->bindEntities(
\CCrmOwnerType::Contact,
$newEntityID,
$invoiceIDs
);
}
$this->eraseSuspendedUserFields($recyclingEntityID);
$this->recoverMultiFields($recyclingEntityID, $newEntityID);
$this->recoverAddresses($recyclingEntityID, $newEntityID);
$this->recoverTimeline($recyclingEntityID, $newEntityID);
$this->recoverDocuments($recyclingEntityID, $newEntityID);
$this->recoverLiveFeed($recyclingEntityID, $newEntityID);
$this->recoverRequisites($recyclingEntityID, $newEntityID);
$this->recoverUtm($recyclingEntityID, $newEntityID);
$this->recoverTracing($recyclingEntityID, $newEntityID);
$requisiteLinks = isset($slots['REQUISITE_LINKS']) ? $slots['REQUISITE_LINKS'] : null;
if(is_array($requisiteLinks) && !empty($requisiteLinks))
{
Crm\EntityRequisite::setLinks($requisiteLinks);
}
$this->recoverActivities($recyclingEntityID, $entityID, $newEntityID, $params, $relationMap);
//region Relations
Relation::unregisterRecycleBin($recyclingEntityID);
Relation::deleteJunks();
//endregion
$this->rebuildSearchIndex($newEntityID);
$this->startRecoveryWorkflows($newEntityID);
return true;
}
/**
* Recover entity multifields.
* @param int $recyclingEntityID Recycle Bin Entity ID.
* @param int $newEntityID New Entity ID.
* @throws Main\ArgumentException
*/
protected function recoverMultiFields($recyclingEntityID, $newEntityID)
{
$this->innerRecoverMultiFields($recyclingEntityID, $newEntityID);
\CCrmContact::SynchronizeMultifieldMarkers($newEntityID);
}
/**
* Erase entity from Recycle Bin.
* @param int $entityID Entity ID.
* @param array $params Additional operation parameters.
* @return void
* @throws Main\AccessDeniedException
* @throws Main\ArgumentException
* @throws Main\ArgumentOutOfRangeException
* @throws Main\InvalidOperationException
* @throws Main\LoaderException
*/
public function erase($entityID, array $params = array())
{
if($entityID <= 0)
{
throw new Main\ArgumentException('Must be greater than zero.', 'entityID');
}
$recyclingEntityID = isset($params['ID']) ? (int)$params['ID'] : 0;
if($recyclingEntityID <= 0)
{
throw new Main\ArgumentException('Could not find parameter named: "ID".', 'params');
}
/*
$slots = isset($params['SLOTS']) ? $params['SLOTS'] : null;
if(is_array($slots))
{
$fields = isset($slots['FIELDS']) ? $slots['FIELDS'] : null;
}
*/
$relationMap = RelationMap::createByEntity(\CCrmOwnerType::Contact, $entityID, $recyclingEntityID);
$relationMap->build();
$this->eraseActivities($recyclingEntityID, $params, $relationMap);
$this->eraseSuspendedMultiFields($recyclingEntityID);
$this->eraseSuspendedAddresses($recyclingEntityID, array(Crm\EntityAddress::Primary));
$this->eraseSuspendedTimeline($recyclingEntityID);
$this->eraseSuspendedDocuments($recyclingEntityID);
$this->eraseSuspendedLiveFeed($recyclingEntityID);
$this->eraseSuspendedRequisites($recyclingEntityID);
$this->eraseSuspendedUtm($recyclingEntityID);
$this->eraseSuspendedTracing($recyclingEntityID);
$this->eraseSuspendedUserFields($recyclingEntityID);
//region Files
if(isset($params['FILES']) && is_array($params['FILES']) && !empty($params['FILES']))
{
$this->eraseFiles($params['FILES']);
}
//endregion
Relation::deleteByRecycleBin($recyclingEntityID);
}
}